Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
51
plugins/inputs/azure_storage_queue/README.md
Normal file
51
plugins/inputs/azure_storage_queue/README.md
Normal file
|
@ -0,0 +1,51 @@
|
|||
# Azure Queue Storage Input Plugin
|
||||
|
||||
This plugin gathers queue sizes from the [Azure Queue Storage][azure_queues]
|
||||
service, storing a large numbers of messages.
|
||||
|
||||
⭐ Telegraf v1.13.0
|
||||
🏷️ cloud
|
||||
💻 all
|
||||
|
||||
[azure_queues]: https://learn.microsoft.com/en-us/azure/storage/queues
|
||||
|
||||
## Global configuration options <!-- @/docs/includes/plugin_config.md -->
|
||||
|
||||
In addition to the plugin-specific configuration settings, plugins support
|
||||
additional global and plugin configuration settings. These settings are used to
|
||||
modify metrics, tags, and field or create aliases and configure ordering, etc.
|
||||
See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||
|
||||
[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins
|
||||
|
||||
## Configuration
|
||||
|
||||
```toml @sample.conf
|
||||
# Gather Azure Storage Queue metrics
|
||||
[[inputs.azure_storage_queue]]
|
||||
## Azure Storage Account name and shared access key (required)
|
||||
account_name = "mystorageaccount"
|
||||
account_key = "storageaccountaccesskey"
|
||||
|
||||
## Disable peeking age of oldest message (faster)
|
||||
# peek_oldest_message_age = true
|
||||
```
|
||||
|
||||
## Metrics
|
||||
|
||||
- azure_storage_queues
|
||||
- tags:
|
||||
- queue
|
||||
- account
|
||||
- fields:
|
||||
- size (integer, count)
|
||||
- oldest_message_age_ns (integer, nanoseconds) Age of message at the head
|
||||
of the queue. Requires `peek_oldest_message_age` to be configured
|
||||
to `true`.
|
||||
|
||||
## Example Output
|
||||
|
||||
```text
|
||||
azure_storage_queues,queue=myqueue,account=mystorageaccount oldest_message_age=799714900i,size=7i 1565970503000000000
|
||||
azure_storage_queues,queue=myemptyqueue,account=mystorageaccount size=0i 1565970502000000000
|
||||
```
|
123
plugins/inputs/azure_storage_queue/azure_storage_queue.go
Normal file
123
plugins/inputs/azure_storage_queue/azure_storage_queue.go
Normal file
|
@ -0,0 +1,123 @@
|
|||
//go:generate ../../../tools/readme_config_includer/generator
|
||||
package azure_storage_queue
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azqueue"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
//go:embed sample.conf
|
||||
var sampleConfig string
|
||||
|
||||
type AzureStorageQueue struct {
|
||||
EndpointURL string `toml:"endpoint"`
|
||||
StorageAccountName string `toml:"account_name"`
|
||||
StorageAccountKey string `toml:"account_key"`
|
||||
PeekOldestMessageAge bool `toml:"peek_oldest_message_age"`
|
||||
Log telegraf.Logger
|
||||
|
||||
client *azqueue.ServiceClient
|
||||
}
|
||||
|
||||
func (*AzureStorageQueue) SampleConfig() string {
|
||||
return sampleConfig
|
||||
}
|
||||
|
||||
func (a *AzureStorageQueue) Init() error {
|
||||
// Check settings
|
||||
if a.StorageAccountName == "" {
|
||||
return errors.New("account_name must be configured")
|
||||
}
|
||||
|
||||
if a.StorageAccountKey == "" {
|
||||
return errors.New("account_key must be configured")
|
||||
}
|
||||
|
||||
// Prepare the client
|
||||
if a.EndpointURL == "" {
|
||||
a.EndpointURL = "https://" + a.StorageAccountName + ".queue.core.windows.net"
|
||||
}
|
||||
credentials, err := azqueue.NewSharedKeyCredential(a.StorageAccountName, a.StorageAccountKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating shared-key credentials failed: %w", err)
|
||||
}
|
||||
|
||||
client, err := azqueue.NewServiceClientWithSharedKeyCredential(a.EndpointURL, credentials, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating client failed: %w", err)
|
||||
}
|
||||
a.client = client
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *AzureStorageQueue) Gather(acc telegraf.Accumulator) error {
|
||||
ctx := context.Background()
|
||||
|
||||
a.Log.Debugf("Listing queues of storage account %q", a.StorageAccountName)
|
||||
|
||||
// Iterate through the queues and generate metrics
|
||||
pages := a.client.NewListQueuesPager(nil)
|
||||
for pages.More() {
|
||||
response, err := pages.NextPage(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting next page failed: %w", err)
|
||||
}
|
||||
|
||||
// Get the properties and the message properties for each of the queues
|
||||
for _, queue := range response.Queues {
|
||||
if queue.Name == nil {
|
||||
continue
|
||||
}
|
||||
name := strings.TrimSpace(*queue.Name)
|
||||
|
||||
// Access the queue and get the properties
|
||||
c := a.client.NewQueueClient(*queue.Name)
|
||||
props, err := c.GetProperties(ctx, nil)
|
||||
if err != nil {
|
||||
acc.AddError(fmt.Errorf("getting properties for queue %q failed: %w", name, err))
|
||||
continue
|
||||
}
|
||||
if props.ApproximateMessagesCount == nil {
|
||||
acc.AddError(fmt.Errorf("unset message count for queue %q", name))
|
||||
continue
|
||||
}
|
||||
|
||||
// Setup the metric elements
|
||||
tags := map[string]string{
|
||||
"account": a.StorageAccountName,
|
||||
"queue": strings.TrimSpace(name),
|
||||
}
|
||||
fields := map[string]interface{}{
|
||||
"size": *props.ApproximateMessagesCount,
|
||||
}
|
||||
now := time.Now()
|
||||
if a.PeekOldestMessageAge {
|
||||
if r, err := c.PeekMessage(ctx, nil); err != nil {
|
||||
acc.AddError(fmt.Errorf("peeking message for queue %q failed: %w", name, err))
|
||||
} else if len(r.Messages) > 0 && r.Messages[0] != nil && r.Messages[0].InsertionTime != nil {
|
||||
msg := r.Messages[0]
|
||||
fields["oldest_message_age_ns"] = now.Sub(*msg.InsertionTime).Nanoseconds()
|
||||
}
|
||||
}
|
||||
acc.AddFields("azure_storage_queues", fields, tags, now)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
inputs.Add("azure_storage_queue", func() telegraf.Input {
|
||||
return &AzureStorageQueue{PeekOldestMessageAge: true}
|
||||
})
|
||||
}
|
150
plugins/inputs/azure_storage_queue/azure_storage_queue_test.go
Normal file
150
plugins/inputs/azure_storage_queue/azure_storage_queue_test.go
Normal file
|
@ -0,0 +1,150 @@
|
|||
package azure_storage_queue
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azqueue"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/modules/azure/azurite"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/metric"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
func TestEmulatorIntegration(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping integration test in short mode")
|
||||
}
|
||||
|
||||
// Require the developers to explicitly accept the EULA of the emulator
|
||||
if os.Getenv("AZURE_EVENT_HUBS_EMULATOR_ACCEPT_EULA") != "yes" {
|
||||
t.Skip(`
|
||||
Skipping due to unexcepted EULA. To run this test, please check the EULA of the emulator
|
||||
at https://github.com/Azure/azure-event-hubs-emulator-installer/blob/main/EMULATOR_EULA.md
|
||||
and accept it by setting the environment variable AZURE_EVENT_HUBS_EMULATOR_ACCEPT_EULA
|
||||
to 'yes'.
|
||||
`)
|
||||
}
|
||||
|
||||
// Setup the Azure Event Hub emulator environment
|
||||
// See https://learn.microsoft.com/en-us/azure/event-hubs/test-locally-with-event-hub-emulator
|
||||
emulator, err := azurite.Run(
|
||||
t.Context(),
|
||||
"mcr.microsoft.com/azure-storage/azurite:3.28.0",
|
||||
azurite.WithInMemoryPersistence(64.0),
|
||||
)
|
||||
require.NoError(t, err, "failed to start Azurite container")
|
||||
defer testcontainers.TerminateContainer(emulator) //nolint:errcheck // Ignore error as we can't do anything about it
|
||||
|
||||
endpoint, err := emulator.QueueServiceURL(t.Context())
|
||||
require.NoError(t, err, "getting queue URL failed")
|
||||
endpoint += "/" + azurite.AccountName
|
||||
|
||||
// Create two queues and push some messages to get data
|
||||
credentials, err := azqueue.NewSharedKeyCredential(azurite.AccountName, azurite.AccountKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
client, err := azqueue.NewServiceClientWithSharedKeyCredential(endpoint, credentials, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Remember the oldest messages
|
||||
oldest := make(map[string]time.Time, 2)
|
||||
|
||||
// Add five messages to test queue one
|
||||
_, err = client.CreateQueue(t.Context(), "test-one", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
qc := client.NewQueueClient("test-one")
|
||||
for i := range 5 {
|
||||
msg := fmt.Sprintf(`{"count": %d, "message": "foobar"}`, i)
|
||||
resp, err := qc.EnqueueMessage(t.Context(), msg, nil)
|
||||
require.NoError(t, err)
|
||||
if i == 0 {
|
||||
oldest["test-one"] = *resp.Date
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
// Add three messages to test queue two
|
||||
_, err = client.CreateQueue(t.Context(), "test-two", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
qc = client.NewQueueClient("test-two")
|
||||
for i := range 3 {
|
||||
msg := fmt.Sprintf(`{"count": %d, "message": "tiger"}`, i)
|
||||
resp, err := qc.EnqueueMessage(t.Context(), msg, nil)
|
||||
require.NoError(t, err)
|
||||
if i == 0 {
|
||||
oldest["test-two"] = *resp.Date
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
// Setup plugin
|
||||
plugin := &AzureStorageQueue{
|
||||
EndpointURL: endpoint,
|
||||
StorageAccountName: azurite.AccountName,
|
||||
StorageAccountKey: azurite.AccountKey,
|
||||
PeekOldestMessageAge: true,
|
||||
Log: &testutil.Logger{},
|
||||
}
|
||||
|
||||
require.NoError(t, plugin.Init())
|
||||
|
||||
// Make sure we are connected
|
||||
var acc testutil.Accumulator
|
||||
require.NoError(t, plugin.Gather(&acc))
|
||||
|
||||
expected := []telegraf.Metric{
|
||||
metric.New(
|
||||
"azure_storage_queues",
|
||||
map[string]string{
|
||||
"account": azurite.AccountName,
|
||||
"queue": "test-one",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"oldest_message_age_ns": int64(0),
|
||||
"size": int64(5),
|
||||
},
|
||||
time.Unix(0, 0),
|
||||
),
|
||||
metric.New(
|
||||
"azure_storage_queues",
|
||||
map[string]string{
|
||||
"account": azurite.AccountName,
|
||||
"queue": "test-two",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"oldest_message_age_ns": int64(0),
|
||||
"size": int64(3),
|
||||
},
|
||||
time.Unix(0, 0),
|
||||
),
|
||||
}
|
||||
|
||||
// Test the metrics
|
||||
options := []cmp.Option{
|
||||
testutil.IgnoreTime(),
|
||||
testutil.IgnoreFields("oldest_message_age_ns"),
|
||||
}
|
||||
actual := acc.GetTelegrafMetrics()
|
||||
testutil.RequireMetricsEqual(t, expected, actual, options...)
|
||||
|
||||
// Test the oldest-message values
|
||||
for _, m := range actual {
|
||||
q, found := m.GetTag("queue")
|
||||
require.True(t, found)
|
||||
|
||||
actualAge, found := m.GetField("oldest_message_age_ns")
|
||||
require.True(t, found)
|
||||
|
||||
expectedAge := m.Time().Sub(oldest[q])
|
||||
require.Equal(t, expectedAge.Nanoseconds(), actualAge)
|
||||
}
|
||||
}
|
8
plugins/inputs/azure_storage_queue/sample.conf
Normal file
8
plugins/inputs/azure_storage_queue/sample.conf
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Gather Azure Storage Queue metrics
|
||||
[[inputs.azure_storage_queue]]
|
||||
## Azure Storage Account name and shared access key (required)
|
||||
account_name = "mystorageaccount"
|
||||
account_key = "storageaccountaccesskey"
|
||||
|
||||
## Disable peeking age of oldest message (faster)
|
||||
# peek_oldest_message_age = true
|
Loading…
Add table
Add a link
Reference in a new issue