2015-01-07 02:28:34 +00:00
|
|
|
package collectd
|
2015-01-07 23:10:27 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|