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
121
plugins/parsers/opentsdb/parser.go
Normal file
121
plugins/parsers/opentsdb/parser.go
Normal file
|
@ -0,0 +1,121 @@
|
|||
package opentsdb
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/metric"
|
||||
"github.com/influxdata/telegraf/plugins/parsers"
|
||||
)
|
||||
|
||||
// Parser encapsulates a OpenTSDB Parser.
|
||||
type Parser struct {
|
||||
DefaultTags map[string]string `toml:"-"`
|
||||
Log telegraf.Logger `toml:"-"`
|
||||
}
|
||||
|
||||
func (p *Parser) Parse(buf []byte) ([]telegraf.Metric, error) {
|
||||
var metrics []telegraf.Metric
|
||||
|
||||
scanner := bufio.NewScanner(bytes.NewReader(buf))
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
// delete LF and CR
|
||||
line = strings.TrimRight(line, "\r\n")
|
||||
|
||||
m, err := p.ParseLine(line)
|
||||
if err != nil {
|
||||
p.Log.Errorf("Error parsing %q as opentsdb: %s", line, err)
|
||||
|
||||
// Don't let one bad line spoil a whole batch. In particular, it may
|
||||
// be a valid opentsdb telnet protocol command, like "version", that
|
||||
// we don't support.
|
||||
continue
|
||||
}
|
||||
|
||||
metrics = append(metrics, m)
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return metrics, nil
|
||||
}
|
||||
|
||||
// ParseLine performs OpenTSDB parsing of a single line.
|
||||
func (p *Parser) ParseLine(line string) (telegraf.Metric, error) {
|
||||
// Break into fields ("put", name, timestamp, value, tag1, tag2, ..., tagN).
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) < 4 || fields[0] != "put" {
|
||||
return nil, errors.New("doesn't have required fields")
|
||||
}
|
||||
|
||||
// decode the name and tags
|
||||
measurement := fields[1]
|
||||
tsStr := fields[2]
|
||||
valueStr := fields[3]
|
||||
tagStrs := fields[4:]
|
||||
|
||||
// Parse value.
|
||||
v, err := strconv.ParseFloat(valueStr, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing field %q value failed: %w", measurement, err)
|
||||
}
|
||||
|
||||
fieldValues := map[string]interface{}{"value": v}
|
||||
|
||||
// Parse timestamp.
|
||||
ts, err := strconv.ParseInt(tsStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing field %q time failed: %w", measurement, err)
|
||||
}
|
||||
|
||||
var timestamp time.Time
|
||||
if ts < 1e12 {
|
||||
// second resolution
|
||||
timestamp = time.Unix(ts, 0)
|
||||
} else {
|
||||
// millisecond resolution
|
||||
timestamp = time.UnixMilli(ts)
|
||||
}
|
||||
|
||||
tags := make(map[string]string, len(p.DefaultTags)+len(tagStrs))
|
||||
for k, v := range p.DefaultTags {
|
||||
tags[k] = v
|
||||
}
|
||||
|
||||
for _, tag := range tagStrs {
|
||||
tagValue := strings.Split(tag, "=")
|
||||
if len(tagValue) != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
name := tagValue[0]
|
||||
value := tagValue[1]
|
||||
if name == "" || value == "" {
|
||||
continue
|
||||
}
|
||||
tags[name] = value
|
||||
}
|
||||
|
||||
return metric.New(measurement, tags, fieldValues, timestamp), nil
|
||||
}
|
||||
|
||||
func (p *Parser) SetDefaultTags(tags map[string]string) {
|
||||
p.DefaultTags = tags
|
||||
}
|
||||
|
||||
func init() {
|
||||
parsers.Add("opentsdb",
|
||||
func(string) telegraf.Parser {
|
||||
return &Parser{}
|
||||
})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue