feat(agent): Add option to avoid filtering of global tags (#13605)

This commit is contained in:
Sven Rebhan 2023-07-14 16:00:10 +02:00 committed by GitHub
parent 9ede0b0c49
commit 3da80fdfc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 135 additions and 46 deletions

View File

@ -263,6 +263,10 @@ type AgentConfig struct {
// Flag to always keep tags explicitly defined in the plugin itself and
// ensure those tags always pass filtering.
AlwaysIncludeLocalTags bool `toml:"always_include_local_tags"`
// Flag to always keep tags explicitly defined in the global tags section
// and ensure those tags always pass filtering.
AlwaysIncludeGlobalTags bool `toml:"always_include_global_tags"`
}
// InputNames returns a list of strings of the configured inputs.
@ -1459,8 +1463,9 @@ func (c *Config) buildFilter(tbl *ast.Table) (models.Filter, error) {
// models.InputConfig to be inserted into models.RunningInput
func (c *Config) buildInput(name string, tbl *ast.Table) (*models.InputConfig, error) {
cp := &models.InputConfig{
Name: name,
AlwaysIncludeLocalTags: c.Agent.AlwaysIncludeLocalTags,
Name: name,
AlwaysIncludeLocalTags: c.Agent.AlwaysIncludeLocalTags,
AlwaysIncludeGlobalTags: c.Agent.AlwaysIncludeGlobalTags,
}
c.getFieldDuration(tbl, "interval", &cp.Interval)
c.getFieldDuration(tbl, "precision", &cp.Precision)

View File

@ -326,6 +326,11 @@ The agent table configures Telegraf and the defaults used across all plugins.
via `taginclude` or `tagexclude`. This removes the need to specify local tags
twice.
- **always_include_global_tags**:
Ensure tags explicitly defined in the `global_tags` section will *always* pass
tag-filtering via `taginclude` or `tagexclude`. This removes the need to
specify those tags twice.
## Plugins
Telegraf plugins are divided into 4 types: [inputs][], [outputs][],

View File

@ -71,12 +71,13 @@ type InputConfig struct {
CollectionOffset time.Duration
Precision time.Duration
NameOverride string
MeasurementPrefix string
MeasurementSuffix string
Tags map[string]string
Filter Filter
AlwaysIncludeLocalTags bool
NameOverride string
MeasurementPrefix string
MeasurementSuffix string
Tags map[string]string
Filter Filter
AlwaysIncludeLocalTags bool
AlwaysIncludeGlobalTags bool
}
func (r *RunningInput) metricFiltered(metric telegraf.Metric) {
@ -113,17 +114,12 @@ func (r *RunningInput) MakeMetric(metric telegraf.Metric) telegraf.Metric {
return nil
}
tags := r.Config.Tags
if r.Config.AlwaysIncludeLocalTags {
tags = nil
}
m := makemetric(
makemetric(
metric,
r.Config.NameOverride,
r.Config.MeasurementPrefix,
r.Config.MeasurementSuffix,
tags,
r.Config.Tags,
r.defaultTags)
r.Config.Filter.Modify(metric)
@ -132,18 +128,20 @@ func (r *RunningInput) MakeMetric(metric telegraf.Metric) telegraf.Metric {
return nil
}
if r.Config.AlwaysIncludeLocalTags {
// Apply plugin tags after filtering
for k, v := range r.Config.Tags {
if _, ok := metric.GetTag(k); !ok {
metric.AddTag(k, v)
}
if r.Config.AlwaysIncludeLocalTags || r.Config.AlwaysIncludeGlobalTags {
var local, global map[string]string
if r.Config.AlwaysIncludeLocalTags {
local = r.Config.Tags
}
if r.Config.AlwaysIncludeGlobalTags {
global = r.defaultTags
}
makemetric(metric, "", "", "", local, global)
}
r.MetricsGathered.Incr(1)
GlobalMetricsGathered.Incr(1)
return m
return metric
}
func (r *RunningInput) Gather(acc telegraf.Accumulator) error {

View File

@ -55,8 +55,8 @@ func TestMakeMetricNoFields(t *testing.T) {
map[string]interface{}{},
now,
telegraf.Untyped)
m = ri.MakeMetric(m)
assert.Nil(t, m)
actual := ri.MakeMetric(m)
require.Nil(t, actual)
}
// nil fields should get dropped
@ -74,7 +74,7 @@ func TestMakeMetricNilFields(t *testing.T) {
},
now,
telegraf.Untyped)
m = ri.MakeMetric(m)
actual := ri.MakeMetric(m)
expected := metric.New("RITest",
map[string]string{},
@ -84,7 +84,7 @@ func TestMakeMetricNilFields(t *testing.T) {
now,
)
require.Equal(t, expected, m)
require.Equal(t, expected, actual)
}
func TestMakeMetricWithPluginTags(t *testing.T) {
@ -103,7 +103,7 @@ func TestMakeMetricWithPluginTags(t *testing.T) {
},
now,
telegraf.Untyped)
m = ri.MakeMetric(m)
actual := ri.MakeMetric(m)
expected := metric.New("RITest",
map[string]string{
@ -114,7 +114,7 @@ func TestMakeMetricWithPluginTags(t *testing.T) {
},
now,
)
require.Equal(t, expected, m)
require.Equal(t, expected, actual)
}
func TestMakeMetricFilteredOut(t *testing.T) {
@ -136,8 +136,8 @@ func TestMakeMetricFilteredOut(t *testing.T) {
},
now,
telegraf.Untyped)
m = ri.MakeMetric(m)
assert.Nil(t, m)
actual := ri.MakeMetric(m)
require.Nil(t, actual)
}
func TestMakeMetricWithDaemonTags(t *testing.T) {
@ -156,7 +156,7 @@ func TestMakeMetricWithDaemonTags(t *testing.T) {
},
now,
telegraf.Untyped)
m = ri.MakeMetric(m)
actual := ri.MakeMetric(m)
expected := metric.New("RITest",
map[string]string{
"foo": "bar",
@ -166,7 +166,7 @@ func TestMakeMetricWithDaemonTags(t *testing.T) {
},
now,
)
require.Equal(t, expected, m)
require.Equal(t, expected, actual)
}
func TestMakeMetricNameOverride(t *testing.T) {
@ -183,7 +183,7 @@ func TestMakeMetricNameOverride(t *testing.T) {
},
now,
telegraf.Untyped)
m = ri.MakeMetric(m)
actual := ri.MakeMetric(m)
expected := metric.New("foobar",
nil,
map[string]interface{}{
@ -191,7 +191,7 @@ func TestMakeMetricNameOverride(t *testing.T) {
},
now,
)
require.Equal(t, expected, m)
require.Equal(t, expected, actual)
}
func TestMakeMetricNamePrefix(t *testing.T) {
@ -208,7 +208,7 @@ func TestMakeMetricNamePrefix(t *testing.T) {
},
now,
telegraf.Untyped)
m = ri.MakeMetric(m)
actual := ri.MakeMetric(m)
expected := metric.New("foobar_RITest",
nil,
map[string]interface{}{
@ -216,7 +216,7 @@ func TestMakeMetricNamePrefix(t *testing.T) {
},
now,
)
require.Equal(t, expected, m)
require.Equal(t, expected, actual)
}
func TestMakeMetricNameSuffix(t *testing.T) {
@ -233,7 +233,7 @@ func TestMakeMetricNameSuffix(t *testing.T) {
},
now,
telegraf.Untyped)
m = ri.MakeMetric(m)
actual := ri.MakeMetric(m)
expected := metric.New("RITest_foobar",
nil,
map[string]interface{}{
@ -241,7 +241,7 @@ func TestMakeMetricNameSuffix(t *testing.T) {
},
now,
)
require.Equal(t, expected, m)
require.Equal(t, expected, actual)
}
func TestMetricErrorCounters(t *testing.T) {
@ -283,8 +283,8 @@ func TestMakeMetricWithAlwaysKeepingPluginTagsDisabled(t *testing.T) {
Filter: Filter{
TagInclude: []string{"b"},
},
AlwaysIncludeLocalTags: false,
})
ri.SetDefaultTags(map[string]string{"logic": "rulez"})
require.NoError(t, ri.Config.Filter.Compile())
m := testutil.MustMetric("RITest",
@ -296,7 +296,7 @@ func TestMakeMetricWithAlwaysKeepingPluginTagsDisabled(t *testing.T) {
},
now,
telegraf.Untyped)
m = ri.MakeMetric(m)
actual := ri.MakeMetric(m)
expected := metric.New("RITest",
map[string]string{
@ -307,7 +307,85 @@ func TestMakeMetricWithAlwaysKeepingPluginTagsDisabled(t *testing.T) {
},
now,
)
require.Equal(t, expected, m)
require.Equal(t, expected, actual)
}
func TestMakeMetricWithAlwaysKeepingLocalPluginTagsEnabled(t *testing.T) {
now := time.Now()
ri := NewRunningInput(&testInput{}, &InputConfig{
Name: "TestRunningInput",
Tags: map[string]string{
"foo": "bar",
},
Filter: Filter{
TagInclude: []string{"b"},
},
AlwaysIncludeLocalTags: true,
})
ri.SetDefaultTags(map[string]string{"logic": "rulez"})
require.NoError(t, ri.Config.Filter.Compile())
m := testutil.MustMetric("RITest",
map[string]string{
"b": "test",
},
map[string]interface{}{
"value": int64(101),
},
now,
telegraf.Untyped)
actual := ri.MakeMetric(m)
expected := metric.New("RITest",
map[string]string{
"b": "test",
"foo": "bar",
},
map[string]interface{}{
"value": 101,
},
now,
)
require.Equal(t, expected, actual)
}
func TestMakeMetricWithAlwaysKeepingGlobalPluginTagsEnabled(t *testing.T) {
now := time.Now()
ri := NewRunningInput(&testInput{}, &InputConfig{
Name: "TestRunningInput",
Tags: map[string]string{
"foo": "bar",
},
Filter: Filter{
TagInclude: []string{"b"},
},
AlwaysIncludeGlobalTags: true,
})
ri.SetDefaultTags(map[string]string{"logic": "rulez"})
require.NoError(t, ri.Config.Filter.Compile())
m := testutil.MustMetric("RITest",
map[string]string{
"b": "test",
},
map[string]interface{}{
"value": int64(101),
},
now,
telegraf.Untyped)
actual := ri.MakeMetric(m)
expected := metric.New("RITest",
map[string]string{
"b": "test",
"logic": "rulez",
},
map[string]interface{}{
"value": 101,
},
now,
)
require.Equal(t, expected, actual)
}
func TestMakeMetricWithAlwaysKeepingPluginTagsEnabled(t *testing.T) {
@ -320,8 +398,10 @@ func TestMakeMetricWithAlwaysKeepingPluginTagsEnabled(t *testing.T) {
Filter: Filter{
TagInclude: []string{"b"},
},
AlwaysIncludeLocalTags: true,
AlwaysIncludeLocalTags: true,
AlwaysIncludeGlobalTags: true,
})
ri.SetDefaultTags(map[string]string{"logic": "rulez"})
require.NoError(t, ri.Config.Filter.Compile())
m := testutil.MustMetric("RITest",
@ -333,19 +413,20 @@ func TestMakeMetricWithAlwaysKeepingPluginTagsEnabled(t *testing.T) {
},
now,
telegraf.Untyped)
m = ri.MakeMetric(m)
actual := ri.MakeMetric(m)
expected := metric.New("RITest",
map[string]string{
"b": "test",
"foo": "bar",
"b": "test",
"foo": "bar",
"logic": "rulez",
},
map[string]interface{}{
"value": 101,
},
now,
)
require.Equal(t, expected, m)
require.Equal(t, expected, actual)
}
type testInput struct{}