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,48 @@
# Clone Processor Plugin
The clone processor plugin create a copy of each metric passing through it,
preserving untouched the original metric and allowing modifications in the
copied one.
The modifications allowed are the ones supported by input plugins and
aggregators:
* name_override
* name_prefix
* name_suffix
* tags
Select the metrics to modify using the standard [metric
filtering](../../../docs/CONFIGURATION.md#metric-filtering) options. Filtering
options apply to both the clone and the original.
Values of *name_override*, *name_prefix*, *name_suffix* and already present
*tags* with conflicting keys will be overwritten. Absent *tags* will be
created.
A typical use-case is gathering metrics once and cloning them to simulate
having several hosts (modifying ``host`` tag).
## 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
# Apply metric modifications using override semantics.
[[processors.clone]]
## All modifications on inputs and aggregators can be overridden:
# name_override = "new_name"
# name_prefix = "new_name_prefix"
# name_suffix = "new_name_suffix"
## Tags to be added (all values must be strings)
# [processors.clone.tags]
# additional_tag = "tag_value"
```

View file

@ -0,0 +1,52 @@
//go:generate ../../../tools/readme_config_includer/generator
package clone
import (
_ "embed"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/processors"
)
//go:embed sample.conf
var sampleConfig string
type Clone struct {
NameOverride string
NamePrefix string
NameSuffix string
Tags map[string]string
}
func (*Clone) SampleConfig() string {
return sampleConfig
}
func (c *Clone) Apply(in ...telegraf.Metric) []telegraf.Metric {
out := make([]telegraf.Metric, 0, 2*len(in))
for _, original := range in {
m := original.Copy()
if len(c.NameOverride) > 0 {
m.SetName(c.NameOverride)
}
if len(c.NamePrefix) > 0 {
m.AddPrefix(c.NamePrefix)
}
if len(c.NameSuffix) > 0 {
m.AddSuffix(c.NameSuffix)
}
for key, value := range c.Tags {
m.AddTag(key, value)
}
out = append(out, m)
}
return append(out, in...)
}
func init() {
processors.Add("clone", func() telegraf.Processor {
return &Clone{}
})
}

View file

@ -0,0 +1,242 @@
package clone
import (
"sync"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/metric"
"github.com/influxdata/telegraf/testutil"
)
func TestRetainsTags(t *testing.T) {
input := metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
)
expected := []telegraf.Metric{
metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
),
metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
),
}
plugin := &Clone{}
actual := plugin.Apply(input)
testutil.RequireMetricsEqual(t, expected, actual)
}
func TestAddTags(t *testing.T) {
input := metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
)
expected := []telegraf.Metric{
metric.New(
"m1",
map[string]string{
"metric_tag": "from_metric",
"added_tag": "from_config",
"another_tag": "",
},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
),
metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
),
}
plugin := &Clone{
Tags: map[string]string{
"added_tag": "from_config",
"another_tag": "",
},
}
actual := plugin.Apply(input)
testutil.RequireMetricsEqual(t, expected, actual)
}
func TestOverwritesPresentTagValues(t *testing.T) {
input := metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
)
expected := []telegraf.Metric{
metric.New(
"m1",
map[string]string{"metric_tag": "from_config"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
),
metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
),
}
plugin := &Clone{
Tags: map[string]string{"metric_tag": "from_config"},
}
actual := plugin.Apply(input)
testutil.RequireMetricsEqual(t, expected, actual)
}
func TestOverridesName(t *testing.T) {
input := metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
)
expected := []telegraf.Metric{
metric.New(
"overridden",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
),
metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
),
}
plugin := &Clone{NameOverride: "overridden"}
actual := plugin.Apply(input)
testutil.RequireMetricsEqual(t, expected, actual)
}
func TestNamePrefix(t *testing.T) {
input := metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
)
expected := []telegraf.Metric{
metric.New(
"Pre-m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
),
metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
),
}
plugin := &Clone{NamePrefix: "Pre-"}
actual := plugin.Apply(input)
testutil.RequireMetricsEqual(t, expected, actual)
}
func TestNameSuffix(t *testing.T) {
input := metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
)
expected := []telegraf.Metric{
metric.New(
"m1-suff",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
),
metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Unix(0, 0),
),
}
plugin := &Clone{NameSuffix: "-suff"}
actual := plugin.Apply(input)
testutil.RequireMetricsEqual(t, expected, actual)
}
func TestTracking(t *testing.T) {
inputRaw := []telegraf.Metric{
metric.New(
"m1",
map[string]string{"metric_tag": "from_metric"},
map[string]interface{}{"value": int64(1)},
time.Now(),
),
metric.New(
"m2",
map[string]string{"metric_tag": "foo_metric"},
map[string]interface{}{"value": int64(2)},
time.Now(),
),
}
var mu sync.Mutex
delivered := make([]telegraf.DeliveryInfo, 0, len(inputRaw))
notify := func(di telegraf.DeliveryInfo) {
mu.Lock()
defer mu.Unlock()
delivered = append(delivered, di)
}
input := make([]telegraf.Metric, 0, len(inputRaw))
expected := make([]telegraf.Metric, 0, 2*len(input))
for _, m := range inputRaw {
tm, _ := metric.WithTracking(m, notify)
input = append(input, tm)
expected = append(expected, m)
}
expected = append(expected, input...)
// Process expected metrics and compare with resulting metrics
plugin := &Clone{}
actual := plugin.Apply(input...)
testutil.RequireMetricsEqual(t, expected, actual)
// Simulate output acknowledging delivery
for _, m := range actual {
m.Accept()
}
// Check delivery
require.Eventuallyf(t, func() bool {
mu.Lock()
defer mu.Unlock()
return len(input) == len(delivered)
}, time.Second, 100*time.Millisecond, "%d delivered but %d expected", len(delivered), len(expected))
}

View file

@ -0,0 +1,10 @@
# Apply metric modifications using override semantics.
[[processors.clone]]
## All modifications on inputs and aggregators can be overridden:
# name_override = "new_name"
# name_prefix = "new_name_prefix"
# name_suffix = "new_name_suffix"
## Tags to be added (all values must be strings)
# [processors.clone.tags]
# additional_tag = "tag_value"