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
48
plugins/processors/clone/README.md
Normal file
48
plugins/processors/clone/README.md
Normal 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"
|
||||
```
|
52
plugins/processors/clone/clone.go
Normal file
52
plugins/processors/clone/clone.go
Normal 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{}
|
||||
})
|
||||
}
|
242
plugins/processors/clone/clone_test.go
Normal file
242
plugins/processors/clone/clone_test.go
Normal 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))
|
||||
}
|
10
plugins/processors/clone/sample.conf
Normal file
10
plugins/processors/clone/sample.conf
Normal 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"
|
Loading…
Add table
Add a link
Reference in a new issue