telegraf/plugins/serializers/carbon2/carbon2.go

129 lines
2.8 KiB
Go
Raw Normal View History

2019-01-26 10:06:08 +08:00
package carbon2
import (
"bytes"
"fmt"
"strconv"
"strings"
2020-09-10 22:56:35 +08:00
"github.com/influxdata/telegraf"
2019-01-26 10:06:08 +08:00
)
type format string
const (
Carbon2FormatFieldEmpty = format("")
Carbon2FormatFieldSeparate = format("field_separate")
Carbon2FormatMetricIncludesField = format("metric_includes_field")
)
var formats = map[format]struct{}{
Carbon2FormatFieldEmpty: {},
Carbon2FormatFieldSeparate: {},
Carbon2FormatMetricIncludesField: {},
}
2020-09-10 22:56:35 +08:00
type Serializer struct {
metricsFormat format
2019-01-26 10:06:08 +08:00
}
func NewSerializer(metricsFormat string) (*Serializer, error) {
var f = format(metricsFormat)
if _, ok := formats[f]; !ok {
return nil, fmt.Errorf("unknown carbon2 format: %s", f)
}
return &Serializer{
metricsFormat: f,
}, nil
2019-01-26 10:06:08 +08:00
}
2020-09-10 22:56:35 +08:00
func (s *Serializer) Serialize(metric telegraf.Metric) ([]byte, error) {
2019-01-26 10:06:08 +08:00
return s.createObject(metric), nil
}
2020-09-10 22:56:35 +08:00
func (s *Serializer) SerializeBatch(metrics []telegraf.Metric) ([]byte, error) {
2019-01-26 10:06:08 +08:00
var batch bytes.Buffer
for _, metric := range metrics {
batch.Write(s.createObject(metric))
}
return batch.Bytes(), nil
}
2020-09-10 22:56:35 +08:00
func (s *Serializer) createObject(metric telegraf.Metric) []byte {
2019-01-26 10:06:08 +08:00
var m bytes.Buffer
metricsFormat := s.getMetricsFormat()
2019-01-26 10:06:08 +08:00
for fieldName, fieldValue := range metric.Fields() {
if !isNumeric(fieldValue) {
continue
}
switch metricsFormat {
// Field separate is the default when no format specified.
case Carbon2FormatFieldEmpty:
case Carbon2FormatFieldSeparate:
m.WriteString(serializeMetricFieldSeparate(
metric.Name(), fieldName,
))
case Carbon2FormatMetricIncludesField:
m.WriteString(serializeMetricIncludeField(
metric.Name(), fieldName,
))
}
for _, tag := range metric.TagList() {
m.WriteString(strings.Replace(tag.Key, " ", "_", -1))
m.WriteString("=")
value := tag.Value
if len(value) == 0 {
value = "null"
2019-01-26 10:06:08 +08:00
}
m.WriteString(strings.Replace(value, " ", "_", -1))
2019-01-26 10:06:08 +08:00
m.WriteString(" ")
}
m.WriteString(" ")
m.WriteString(fmt.Sprintf("%v", fieldValue))
m.WriteString(" ")
m.WriteString(strconv.FormatInt(metric.Time().Unix(), 10))
m.WriteString("\n")
2019-01-26 10:06:08 +08:00
}
return m.Bytes()
}
func (s *Serializer) SetMetricsFormat(f format) {
s.metricsFormat = f
}
func (s *Serializer) getMetricsFormat() format {
return s.metricsFormat
}
func (s *Serializer) IsMetricsFormatUnset() bool {
return s.metricsFormat == Carbon2FormatFieldEmpty
}
func serializeMetricFieldSeparate(name, fieldName string) string {
return fmt.Sprintf("metric=%s field=%s ",
strings.Replace(name, " ", "_", -1),
strings.Replace(fieldName, " ", "_", -1),
)
}
func serializeMetricIncludeField(name, fieldName string) string {
return fmt.Sprintf("metric=%s_%s ",
strings.Replace(name, " ", "_", -1),
strings.Replace(fieldName, " ", "_", -1),
)
}
2019-01-26 10:06:08 +08:00
func isNumeric(v interface{}) bool {
switch v.(type) {
case string:
return false
default:
return true
}
}