diff --git a/api.go b/api.go index faefe10..39e198f 100644 --- a/api.go +++ b/api.go @@ -8,13 +8,14 @@ import ( "strconv" "time" + "github.com/ClusterCockpit/cc-metric-store/lineprotocol" "github.com/gorilla/mux" ) type HostData struct { - Host string `json:"host"` - Start int64 `json:"start"` - Data []float64 `json:"data"` + Host string `json:"host"` + Start int64 `json:"start"` + Data []lineprotocol.Float `json:"data"` } type MetricData struct { diff --git a/lineprotocol/lineprotocol.go b/lineprotocol/lineprotocol.go index 97ad8d9..4505b1d 100644 --- a/lineprotocol/lineprotocol.go +++ b/lineprotocol/lineprotocol.go @@ -2,14 +2,29 @@ package lineprotocol import ( "errors" + "math" "strconv" "strings" "time" ) +// Go's JSON encoder for floats does not support NaN (https://github.com/golang/go/issues/3480). +// This program uses NaN as a signal for missing data. +// For the HTTP JSON API to be able to handle NaN values, +// we have to use our own type which implements encoding/json.Marshaler itself. +type Float float64 + +func (f Float) MarshalJSON() ([]byte, error) { + if math.IsNaN(float64(f)) { + return []byte("null"), nil + } + + return []byte(strconv.FormatFloat(float64(f), 'f', -1, 64)), nil +} + type Metric struct { Name string - Value float64 + Value Float } // measurement: node or cpu @@ -59,7 +74,7 @@ func Parse(rawline string) (*Line, error) { line.Fields = append(line.Fields, Metric{ Name: pair[0], - Value: field, + Value: Float(field), }) }