130 lines
3.0 KiB
Go
130 lines
3.0 KiB
Go
package telegraf
|
|
|
|
import (
|
|
"bytes"
|
|
"time"
|
|
|
|
"github.com/influxdata/influxdb/client/v2"
|
|
"github.com/influxdata/influxdb/models"
|
|
)
|
|
|
|
type Metric interface {
|
|
// Name returns the measurement name of the metric
|
|
Name() string
|
|
|
|
// Name returns the tags associated with the metric
|
|
Tags() map[string]string
|
|
|
|
// Time return the timestamp for the metric
|
|
Time() time.Time
|
|
|
|
// UnixNano returns the unix nano time of the metric
|
|
UnixNano() int64
|
|
|
|
// Fields returns the fields for the metric
|
|
Fields() map[string]interface{}
|
|
|
|
// String returns a line-protocol string of the metric
|
|
String() string
|
|
|
|
// PrecisionString returns a line-protocol string of the metric, at precision
|
|
PrecisionString(precison string) string
|
|
|
|
// Point returns a influxdb client.Point object
|
|
Point() *client.Point
|
|
}
|
|
|
|
// metric is a wrapper of the influxdb client.Point struct
|
|
type metric struct {
|
|
pt *client.Point
|
|
}
|
|
|
|
// NewMetric returns a metric with the given timestamp. If a timestamp is not
|
|
// given, then data is sent to the database without a timestamp, in which case
|
|
// the server will assign local time upon reception. NOTE: it is recommended to
|
|
// send data with a timestamp.
|
|
func NewMetric(
|
|
name string,
|
|
tags map[string]string,
|
|
fields map[string]interface{},
|
|
t ...time.Time,
|
|
) (Metric, error) {
|
|
var T time.Time
|
|
if len(t) > 0 {
|
|
T = t[0]
|
|
}
|
|
|
|
pt, err := client.NewPoint(name, tags, fields, T)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &metric{
|
|
pt: pt,
|
|
}, nil
|
|
}
|
|
|
|
// MetricParser is an object for Parsing incoming metrics.
|
|
type MetricParser struct {
|
|
// DefaultTags will be added to every parsed metric
|
|
DefaultTags map[string]string
|
|
}
|
|
|
|
func NewMetricParser() *MetricParser {
|
|
return &MetricParser{}
|
|
}
|
|
|
|
// ParseMetrics returns a slice of Metrics from a text representation of a
|
|
// metric (in line-protocol format)
|
|
// with each metric separated by newlines. If any metrics fail to parse,
|
|
// a non-nil error will be returned in addition to the metrics that parsed
|
|
// successfully.
|
|
func (mp *MetricParser) Parse(buf []byte) ([]Metric, error) {
|
|
// parse even if the buffer begins with a newline
|
|
buf = bytes.TrimPrefix(buf, []byte("\n"))
|
|
points, err := models.ParsePoints(buf)
|
|
metrics := make([]Metric, len(points))
|
|
for i, point := range points {
|
|
tags := point.Tags()
|
|
for k, v := range mp.DefaultTags {
|
|
tags[k] = v
|
|
}
|
|
// Ignore error here because it's impossible that a model.Point
|
|
// wouldn't parse into client.Point properly
|
|
metrics[i], _ = NewMetric(point.Name(), tags,
|
|
point.Fields(), point.Time())
|
|
}
|
|
return metrics, err
|
|
}
|
|
|
|
func (m *metric) Name() string {
|
|
return m.pt.Name()
|
|
}
|
|
|
|
func (m *metric) Tags() map[string]string {
|
|
return m.pt.Tags()
|
|
}
|
|
|
|
func (m *metric) Time() time.Time {
|
|
return m.pt.Time()
|
|
}
|
|
|
|
func (m *metric) UnixNano() int64 {
|
|
return m.pt.UnixNano()
|
|
}
|
|
|
|
func (m *metric) Fields() map[string]interface{} {
|
|
return m.pt.Fields()
|
|
}
|
|
|
|
func (m *metric) String() string {
|
|
return m.pt.String()
|
|
}
|
|
|
|
func (m *metric) PrecisionString(precison string) string {
|
|
return m.pt.PrecisionString(precison)
|
|
}
|
|
|
|
func (m *metric) Point() *client.Point {
|
|
return m.pt
|
|
}
|