influxdb/collectd/collectd.go

65 lines
1.6 KiB
Go
Raw Normal View History

2015-01-07 02:28:34 +00:00
package collectd
import (
"errors"
"fmt"
"log"
"math"
"time"
"github.com/kimor79/gollectd"
)
var ErrTimeOutOfBounds = errors.New("The time is to large to store")
//TODO corylanou: This needs to be made a public `main.Point` so we can share this across packages.
type Metrics []Metric
type Metric struct {
Name string
Tags map[string]string
Value interface{}
Timestamp time.Time
}
func Unmarshal(data *gollectd.Packet) (Metrics, error) {
// Prefer high resolution timestamp. TimeHR is 2^-30 seconds, so shift
// right 30 to get seconds then convert to microseconds for InfluxDB
unixTime := (data.TimeHR >> 30) * 1000 * 1000
// Fallback on unix timestamp if high res is 0
if unixTime == 0 {
unixTime = data.Time * 1000 * 1000
}
// Check to see if the unixTime is too large. If so, log an error
if unixTime > math.MaxInt64 {
log.Println("Collectd timestamp too large for InfluxDB. Wrapping around to 0.")
return Metrics{}, ErrTimeOutOfBounds
}
// Collectd time is uint64 but influxdb expects int64
//ts := int64(unixTime % math.MaxInt64)
var m Metrics
for i, _ := range data.Values {
metric := Metric{Name: fmt.Sprintf("%s_%s", data.Plugin, data.Values[i].Name)}
metric.Value = data.Values[i].Value
metric.Timestamp = time.Unix(0, int64(unixTime)*int64(time.Millisecond))
if data.Hostname != "" {
metric.Tags["host"] = data.Hostname
}
if data.PluginInstance != "" {
metric.Tags["instance"] = data.PluginInstance
}
if data.Type != "" {
metric.Tags["type"] = data.Type
}
if data.TypeInstance != "" {
metric.Tags["type_instance"] = data.TypeInstance
}
m = append(m, metric)
}
return m, nil
}