Add custom metrics name builder in graphite output
This commit is contained in:
parent
331b700d1b
commit
85f40ad742
|
@ -1,6 +1,7 @@
|
||||||
package graphite
|
package graphite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/influxdata/telegraf"
|
"github.com/influxdata/telegraf"
|
||||||
|
@ -18,6 +19,7 @@ type Graphite struct {
|
||||||
Servers []string
|
Servers []string
|
||||||
Prefix string
|
Prefix string
|
||||||
Timeout int
|
Timeout int
|
||||||
|
MetricsNameBuilder map[string][]string
|
||||||
conns []net.Conn
|
conns []net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +30,11 @@ var sampleConfig = `
|
||||||
prefix = ""
|
prefix = ""
|
||||||
# timeout in seconds for the write connection to graphite
|
# timeout in seconds for the write connection to graphite
|
||||||
timeout = 2
|
timeout = 2
|
||||||
|
# # Build custom metric name from tags for each plugins
|
||||||
|
# [graphite.metricsnamebuilder]
|
||||||
|
# # Igore unlisted tags and put metric name after disk name
|
||||||
|
# diskio = ["host","{{metric}}","name","{{field}}"]
|
||||||
|
# disk = ["host","{{metric}}","name","{{field}}"]
|
||||||
`
|
`
|
||||||
|
|
||||||
func (g *Graphite) Connect() error {
|
func (g *Graphite) Connect() error {
|
||||||
|
@ -72,34 +79,16 @@ func (g *Graphite) Write(metrics []telegraf.Metric) error {
|
||||||
// Prepare data
|
// Prepare data
|
||||||
var bp []string
|
var bp []string
|
||||||
for _, metric := range metrics {
|
for _, metric := range metrics {
|
||||||
// Get name
|
|
||||||
name := metric.Name()
|
|
||||||
// Convert UnixNano to Unix timestamps
|
// Convert UnixNano to Unix timestamps
|
||||||
timestamp := metric.UnixNano() / 1000000000
|
timestamp := metric.UnixNano() / 1000000000
|
||||||
tag_str := buildTags(metric)
|
|
||||||
|
|
||||||
for field_name, value := range metric.Fields() {
|
for field_name, value := range metric.Fields() {
|
||||||
// Convert value
|
// Convert value
|
||||||
value_str := fmt.Sprintf("%#v", value)
|
value_str := fmt.Sprintf("%#v", value)
|
||||||
// Write graphite metric
|
// Write graphite metric
|
||||||
var graphitePoint string
|
graphitePoint := fmt.Sprintf("%s %s %d\n",
|
||||||
if name == field_name {
|
g.buildMetricName(metric, field_name),
|
||||||
graphitePoint = fmt.Sprintf("%s.%s %s %d\n",
|
|
||||||
tag_str,
|
|
||||||
strings.Replace(name, ".", "_", -1),
|
|
||||||
value_str,
|
value_str,
|
||||||
timestamp)
|
timestamp)
|
||||||
} else {
|
|
||||||
graphitePoint = fmt.Sprintf("%s.%s.%s %s %d\n",
|
|
||||||
tag_str,
|
|
||||||
strings.Replace(name, ".", "_", -1),
|
|
||||||
strings.Replace(field_name, ".", "_", -1),
|
|
||||||
value_str,
|
|
||||||
timestamp)
|
|
||||||
}
|
|
||||||
if g.Prefix != "" {
|
|
||||||
graphitePoint = fmt.Sprintf("%s.%s", g.Prefix, graphitePoint)
|
|
||||||
}
|
|
||||||
bp = append(bp, graphitePoint)
|
bp = append(bp, graphitePoint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,7 +96,6 @@ func (g *Graphite) Write(metrics []telegraf.Metric) error {
|
||||||
|
|
||||||
// This will get set to nil if a successful write occurs
|
// This will get set to nil if a successful write occurs
|
||||||
err := errors.New("Could not write to any Graphite server in cluster\n")
|
err := errors.New("Could not write to any Graphite server in cluster\n")
|
||||||
|
|
||||||
// Send data to a random server
|
// Send data to a random server
|
||||||
p := rand.Perm(len(g.conns))
|
p := rand.Perm(len(g.conns))
|
||||||
for _, n := range p {
|
for _, n := range p {
|
||||||
|
@ -127,36 +115,35 @@ func (g *Graphite) Write(metrics []telegraf.Metric) error {
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
func (g *Graphite) buildMetricName(metric telegraf.Metric, fieldName string) string {
|
||||||
func buildTags(metric telegraf.Metric) string {
|
metricName := bytes.NewBufferString(g.Prefix)
|
||||||
var keys []string
|
metricName.WriteString(".")
|
||||||
tags := metric.Tags()
|
tags := metric.Tags()
|
||||||
|
metricsTemplate, ok := g.MetricsNameBuilder[metric.Name()]
|
||||||
|
if !ok {
|
||||||
|
metricsTemplate = []string{"host"}
|
||||||
for k := range tags {
|
for k := range tags {
|
||||||
if k == "host" {
|
if k != "host" {
|
||||||
|
metricsTemplate = append(metricsTemplate, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(metricsTemplate[1:])
|
||||||
|
if metric.Name() != fieldName {
|
||||||
|
metricsTemplate = append(metricsTemplate, "{{metric}}")
|
||||||
|
}
|
||||||
|
metricsTemplate = append(metricsTemplate, "{{field}}")
|
||||||
|
}
|
||||||
|
tags["{{metric}}"] = metric.Name()
|
||||||
|
tags["{{field}}"] = fieldName
|
||||||
|
for _, tagName := range metricsTemplate {
|
||||||
|
tagValue, ok := tags[tagName]
|
||||||
|
if !ok || tagValue == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
keys = append(keys, k)
|
metricName.WriteString(strings.Replace(tagValue, ".", "_", -1))
|
||||||
|
metricName.WriteString(".")
|
||||||
}
|
}
|
||||||
sort.Strings(keys)
|
return strings.Trim(metricName.String(), ".")
|
||||||
|
|
||||||
var tag_str string
|
|
||||||
if host, ok := tags["host"]; ok {
|
|
||||||
if len(keys) > 0 {
|
|
||||||
tag_str = strings.Replace(host, ".", "_", -1) + "."
|
|
||||||
} else {
|
|
||||||
tag_str = strings.Replace(host, ".", "_", -1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, k := range keys {
|
|
||||||
tag_value := strings.Replace(tags[k], ".", "_", -1)
|
|
||||||
if i == 0 {
|
|
||||||
tag_str += tag_value
|
|
||||||
} else {
|
|
||||||
tag_str += "." + tag_value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tag_str
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -103,7 +103,7 @@ func TCPServer(t *testing.T, wg *sync.WaitGroup) {
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGraphiteTags(t *testing.T) {
|
func TestGraphiteMetricName(t *testing.T) {
|
||||||
m1, _ := telegraf.NewMetric(
|
m1, _ := telegraf.NewMetric(
|
||||||
"mymeasurement",
|
"mymeasurement",
|
||||||
map[string]string{"host": "192.168.0.1"},
|
map[string]string{"host": "192.168.0.1"},
|
||||||
|
@ -122,12 +122,34 @@ func TestGraphiteTags(t *testing.T) {
|
||||||
map[string]interface{}{"value": float64(3.14)},
|
map[string]interface{}{"value": float64(3.14)},
|
||||||
time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC),
|
time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC),
|
||||||
)
|
)
|
||||||
|
m4, _ := telegraf.NewMetric(
|
||||||
tags1 := buildTags(m1)
|
"custom1",
|
||||||
tags2 := buildTags(m2)
|
map[string]string{"host": "192.168.0.1", "afoo": "first", "bfoo": "second"},
|
||||||
tags3 := buildTags(m3)
|
map[string]interface{}{"value": float64(3.14)},
|
||||||
|
time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC),
|
||||||
assert.Equal(t, "192_168_0_1", tags1)
|
)
|
||||||
assert.Equal(t, "192_168_0_1.first.second", tags2)
|
m5, _ := telegraf.NewMetric(
|
||||||
assert.Equal(t, "first.second", tags3)
|
"custom.2",
|
||||||
|
map[string]string{"host": "192.168.0.1", "afoo": "first", "bfoo": "second"},
|
||||||
|
map[string]interface{}{"value": float64(3.14)},
|
||||||
|
time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC),
|
||||||
|
)
|
||||||
|
g := Graphite{
|
||||||
|
Prefix: "my.prefix",
|
||||||
|
MetricsNameBuilder: map[string][]string{
|
||||||
|
"custom1": []string{"host", "afoo", "bfoo"},
|
||||||
|
"custom.2": []string{"{{field}}", "bfoo", "{{metric}}"}},
|
||||||
|
}
|
||||||
|
metricName1 := g.buildMetricName(m1, "value")
|
||||||
|
metricName2 := g.buildMetricName(m2, "value")
|
||||||
|
metricName3 := g.buildMetricName(m3, "value")
|
||||||
|
metricName4 := g.buildMetricName(m4, "value")
|
||||||
|
metricName5 := g.buildMetricName(m5, "value")
|
||||||
|
|
||||||
|
assert.Equal(t, "my.prefix.192_168_0_1.mymeasurement.value", metricName1)
|
||||||
|
assert.Equal(t, "my.prefix.192_168_0_1.first.second.mymeasurement.value", metricName2)
|
||||||
|
assert.Equal(t, "my.prefix.first.second.mymeasurement.value", metricName3)
|
||||||
|
assert.Equal(t, "my.prefix.192_168_0_1.first.second", metricName4)
|
||||||
|
assert.Equal(t, "my.prefix.value.second.custom_2", metricName5)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue