1
0
Fork 0

Adding upstream version 1.34.4.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-24 07:26:29 +02:00
parent e393c3af3f
commit 4978089aab
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
4963 changed files with 677545 additions and 0 deletions

View 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
```

View 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}
})
}

View 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)
}
}

View 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