feat(processors.template): Unify template metric (#13606)
This commit is contained in:
parent
d8f8d3cbc5
commit
f001b29eee
|
|
@ -129,6 +129,10 @@ type Metric interface {
|
||||||
// e.g. '{{.Neasurement}}-{{.Tag "foo"}}-{{.Field "bar"}}'
|
// e.g. '{{.Neasurement}}-{{.Tag "foo"}}-{{.Field "bar"}}'
|
||||||
type TemplateMetric interface {
|
type TemplateMetric interface {
|
||||||
Name() string
|
Name() string
|
||||||
Tag(key string) string
|
|
||||||
Field(key string) interface{}
|
Field(key string) interface{}
|
||||||
|
Fields() map[string]interface{}
|
||||||
|
Tag(key string) string
|
||||||
|
Tags() map[string]string
|
||||||
|
Time() time.Time
|
||||||
|
String() string
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,12 +88,12 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||||
|
|
||||||
Sometimes it is usefull to pass all fields with their values into a single
|
Sometimes it is usefull to pass all fields with their values into a single
|
||||||
message for sending it to a monitoring system (e.g. Syslog, GroundWork), then
|
message for sending it to a monitoring system (e.g. Syslog, GroundWork), then
|
||||||
you can use `.FieldList` or `.TagList`:
|
you can use `.Fields` or `.Tags`:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[[processors.template]]
|
[[processors.template]]
|
||||||
tag = "message"
|
tag = "message"
|
||||||
template = 'Message about {{.Name}} fields: {{.FieldList}}'
|
template = 'Message about {{.Name}} fields: {{.Fields}}'
|
||||||
```
|
```
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
|
|
@ -107,7 +107,7 @@ More advanced example, which might make more sense:
|
||||||
[[processors.template]]
|
[[processors.template]]
|
||||||
tag = "message"
|
tag = "message"
|
||||||
template = '''Message about {{.Name}} fields:
|
template = '''Message about {{.Name}} fields:
|
||||||
{{ range $field, $value := .FieldList -}}
|
{{ range $field, $value := .Fields -}}
|
||||||
{{$field}}:{{$value}}
|
{{$field}}:{{$value}}
|
||||||
{{ end }}'''
|
{{ end }}'''
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,12 @@ func (*TemplateProcessor) SampleConfig() string {
|
||||||
func (r *TemplateProcessor) Apply(in ...telegraf.Metric) []telegraf.Metric {
|
func (r *TemplateProcessor) Apply(in ...telegraf.Metric) []telegraf.Metric {
|
||||||
// for each metric in "in" array
|
// for each metric in "in" array
|
||||||
for _, metric := range in {
|
for _, metric := range in {
|
||||||
newM := TemplateMetric{metric}
|
m, ok := metric.(telegraf.TemplateMetric)
|
||||||
|
if !ok {
|
||||||
|
r.Log.Errorf("metric of type %T is not a template metric", metric)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newM := TemplateMetric{m}
|
||||||
|
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
if err := r.tmplTag.Execute(&b, &newM); err != nil {
|
if err := r.tmplTag.Execute(&b, &newM); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,20 @@
|
||||||
package template
|
package template
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/influxdata/telegraf"
|
"github.com/influxdata/telegraf"
|
||||||
|
"github.com/influxdata/telegraf/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
onceTagList sync.Once
|
||||||
|
onceFieldList sync.Once
|
||||||
)
|
)
|
||||||
|
|
||||||
type TemplateMetric struct {
|
type TemplateMetric struct {
|
||||||
metric telegraf.Metric
|
metric telegraf.TemplateMetric
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *TemplateMetric) Name() string {
|
func (m *TemplateMetric) Name() string {
|
||||||
|
|
@ -16,27 +22,53 @@ func (m *TemplateMetric) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *TemplateMetric) Tag(key string) string {
|
func (m *TemplateMetric) Tag(key string) string {
|
||||||
tagString, _ := m.metric.GetTag(key)
|
return m.metric.Tag(key)
|
||||||
return tagString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *TemplateMetric) Field(key string) interface{} {
|
func (m *TemplateMetric) Field(key string) interface{} {
|
||||||
field, _ := m.metric.GetField(key)
|
return m.metric.Field(key)
|
||||||
return field
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *TemplateMetric) Time() time.Time {
|
func (m *TemplateMetric) Time() time.Time {
|
||||||
return m.metric.Time()
|
return m.metric.Time()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *TemplateMetric) Tags() map[string]string {
|
||||||
|
return m.metric.Tags()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *TemplateMetric) Fields() map[string]interface{} {
|
||||||
|
return m.metric.Fields()
|
||||||
|
}
|
||||||
|
|
||||||
func (m *TemplateMetric) String() string {
|
func (m *TemplateMetric) String() string {
|
||||||
return fmt.Sprint(m.metric)
|
return m.metric.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *TemplateMetric) TagList() map[string]string {
|
func (m *TemplateMetric) TagList() map[string]string {
|
||||||
|
onceTagList.Do(func() {
|
||||||
|
models.PrintOptionValueDeprecationNotice(
|
||||||
|
telegraf.Warn, "processors.template", "template", "{{.TagList}}",
|
||||||
|
telegraf.DeprecationInfo{
|
||||||
|
Since: "1.28.0",
|
||||||
|
RemovalIn: "1.34.0",
|
||||||
|
Notice: "use '{{.Tags}}' instead",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
return m.metric.Tags()
|
return m.metric.Tags()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *TemplateMetric) FieldList() map[string]interface{} {
|
func (m *TemplateMetric) FieldList() map[string]interface{} {
|
||||||
|
onceFieldList.Do(func() {
|
||||||
|
models.PrintOptionValueDeprecationNotice(
|
||||||
|
telegraf.Warn, "processors.template", "template", "{{.FieldList}}",
|
||||||
|
telegraf.DeprecationInfo{
|
||||||
|
Since: "1.28.0",
|
||||||
|
RemovalIn: "1.34.0",
|
||||||
|
Notice: "use '{{.Fields}}' instead",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
return m.metric.Fields()
|
return m.metric.Fields()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,63 @@ func TestTagList(t *testing.T) {
|
||||||
testutil.RequireMetricsEqual(t, []telegraf.Metric{expected}, actual)
|
testutil.RequireMetricsEqual(t, []telegraf.Metric{expected}, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFields(t *testing.T) {
|
||||||
|
// Prepare
|
||||||
|
plugin := TemplateProcessor{
|
||||||
|
Tag: "fields",
|
||||||
|
Template: "{{.Fields}}",
|
||||||
|
Log: testutil.Logger{},
|
||||||
|
}
|
||||||
|
require.NoError(t, plugin.Init())
|
||||||
|
|
||||||
|
// Run
|
||||||
|
m := testutil.TestMetric(1.23)
|
||||||
|
actual := plugin.Apply(m)
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
expected := m.Copy()
|
||||||
|
expected.AddTag("fields", "map[value:1.23]")
|
||||||
|
testutil.RequireMetricsEqual(t, []telegraf.Metric{expected}, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTags(t *testing.T) {
|
||||||
|
// Prepare
|
||||||
|
plugin := TemplateProcessor{
|
||||||
|
Tag: "tags",
|
||||||
|
Template: "{{.Tags}}",
|
||||||
|
Log: testutil.Logger{},
|
||||||
|
}
|
||||||
|
require.NoError(t, plugin.Init())
|
||||||
|
|
||||||
|
// Run
|
||||||
|
m := testutil.TestMetric(1.23)
|
||||||
|
actual := plugin.Apply(m)
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
expected := m.Copy()
|
||||||
|
expected.AddTag("tags", "map[tag1:value1]")
|
||||||
|
testutil.RequireMetricsEqual(t, []telegraf.Metric{expected}, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestString(t *testing.T) {
|
||||||
|
// Prepare
|
||||||
|
plugin := TemplateProcessor{
|
||||||
|
Tag: "tags",
|
||||||
|
Template: "{{.}}",
|
||||||
|
Log: testutil.Logger{},
|
||||||
|
}
|
||||||
|
require.NoError(t, plugin.Init())
|
||||||
|
|
||||||
|
// Run
|
||||||
|
m := testutil.TestMetric(1.23)
|
||||||
|
actual := plugin.Apply(m)
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
expected := m.Copy()
|
||||||
|
expected.AddTag("tags", "test1 map[tag1:value1] map[value:1.23] 1257894000000000000")
|
||||||
|
testutil.RequireMetricsEqual(t, []telegraf.Metric{expected}, actual)
|
||||||
|
}
|
||||||
|
|
||||||
func TestDot(t *testing.T) {
|
func TestDot(t *testing.T) {
|
||||||
// Prepare
|
// Prepare
|
||||||
plugin := TemplateProcessor{Tag: "metric", Template: "{{.}}"}
|
plugin := TemplateProcessor{Tag: "metric", Template: "{{.}}"}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue