package model
import (
"encoding/json"
"fmt"
"sort"
"strconv"
"strings"
)
var ZeroSample = Sample {Timestamp : Earliest }
type Sample struct {
Metric Metric `json:"metric"`
Value SampleValue `json:"value"`
Timestamp Time `json:"timestamp"`
Histogram *SampleHistogram `json:"histogram"`
}
func (s *Sample ) Equal (o *Sample ) bool {
if s == o {
return true
}
if !s .Metric .Equal (o .Metric ) {
return false
}
if !s .Timestamp .Equal (o .Timestamp ) {
return false
}
if s .Histogram != nil {
return s .Histogram .Equal (o .Histogram )
}
return s .Value .Equal (o .Value )
}
func (s Sample ) String () string {
if s .Histogram != nil {
return fmt .Sprintf ("%s => %s" , s .Metric , SampleHistogramPair {
Timestamp : s .Timestamp ,
Histogram : s .Histogram ,
})
}
return fmt .Sprintf ("%s => %s" , s .Metric , SamplePair {
Timestamp : s .Timestamp ,
Value : s .Value ,
})
}
func (s Sample ) MarshalJSON () ([]byte , error ) {
if s .Histogram != nil {
v := struct {
Metric Metric `json:"metric"`
Histogram SampleHistogramPair `json:"histogram"`
}{
Metric : s .Metric ,
Histogram : SampleHistogramPair {
Timestamp : s .Timestamp ,
Histogram : s .Histogram ,
},
}
return json .Marshal (&v )
}
v := struct {
Metric Metric `json:"metric"`
Value SamplePair `json:"value"`
}{
Metric : s .Metric ,
Value : SamplePair {
Timestamp : s .Timestamp ,
Value : s .Value ,
},
}
return json .Marshal (&v )
}
func (s *Sample ) UnmarshalJSON (b []byte ) error {
v := struct {
Metric Metric `json:"metric"`
Value SamplePair `json:"value"`
Histogram SampleHistogramPair `json:"histogram"`
}{
Metric : s .Metric ,
Value : SamplePair {
Timestamp : s .Timestamp ,
Value : s .Value ,
},
Histogram : SampleHistogramPair {
Timestamp : s .Timestamp ,
Histogram : s .Histogram ,
},
}
if err := json .Unmarshal (b , &v ); err != nil {
return err
}
s .Metric = v .Metric
if v .Histogram .Histogram != nil {
s .Timestamp = v .Histogram .Timestamp
s .Histogram = v .Histogram .Histogram
} else {
s .Timestamp = v .Value .Timestamp
s .Value = v .Value .Value
}
return nil
}
type Samples []*Sample
func (s Samples ) Len () int {
return len (s )
}
func (s Samples ) Less (i , j int ) bool {
switch {
case s [i ].Metric .Before (s [j ].Metric ):
return true
case s [j ].Metric .Before (s [i ].Metric ):
return false
case s [i ].Timestamp .Before (s [j ].Timestamp ):
return true
default :
return false
}
}
func (s Samples ) Swap (i , j int ) {
s [i ], s [j ] = s [j ], s [i ]
}
func (s Samples ) Equal (o Samples ) bool {
if len (s ) != len (o ) {
return false
}
for i , sample := range s {
if !sample .Equal (o [i ]) {
return false
}
}
return true
}
type SampleStream struct {
Metric Metric `json:"metric"`
Values []SamplePair `json:"values"`
Histograms []SampleHistogramPair `json:"histograms"`
}
func (ss SampleStream ) String () string {
valuesLength := len (ss .Values )
vals := make ([]string , valuesLength +len (ss .Histograms ))
for i , v := range ss .Values {
vals [i ] = v .String ()
}
for i , v := range ss .Histograms {
vals [i +valuesLength ] = v .String ()
}
return fmt .Sprintf ("%s =>\n%s" , ss .Metric , strings .Join (vals , "\n" ))
}
func (ss SampleStream ) MarshalJSON () ([]byte , error ) {
if len (ss .Histograms ) > 0 && len (ss .Values ) > 0 {
v := struct {
Metric Metric `json:"metric"`
Values []SamplePair `json:"values"`
Histograms []SampleHistogramPair `json:"histograms"`
}{
Metric : ss .Metric ,
Values : ss .Values ,
Histograms : ss .Histograms ,
}
return json .Marshal (&v )
} else if len (ss .Histograms ) > 0 {
v := struct {
Metric Metric `json:"metric"`
Histograms []SampleHistogramPair `json:"histograms"`
}{
Metric : ss .Metric ,
Histograms : ss .Histograms ,
}
return json .Marshal (&v )
} else {
v := struct {
Metric Metric `json:"metric"`
Values []SamplePair `json:"values"`
}{
Metric : ss .Metric ,
Values : ss .Values ,
}
return json .Marshal (&v )
}
}
func (ss *SampleStream ) UnmarshalJSON (b []byte ) error {
v := struct {
Metric Metric `json:"metric"`
Values []SamplePair `json:"values"`
Histograms []SampleHistogramPair `json:"histograms"`
}{
Metric : ss .Metric ,
Values : ss .Values ,
Histograms : ss .Histograms ,
}
if err := json .Unmarshal (b , &v ); err != nil {
return err
}
ss .Metric = v .Metric
ss .Values = v .Values
ss .Histograms = v .Histograms
return nil
}
type Scalar struct {
Value SampleValue `json:"value"`
Timestamp Time `json:"timestamp"`
}
func (s Scalar ) String () string {
return fmt .Sprintf ("scalar: %v @[%v]" , s .Value , s .Timestamp )
}
func (s Scalar ) MarshalJSON () ([]byte , error ) {
v := strconv .FormatFloat (float64 (s .Value ), 'f' , -1 , 64 )
return json .Marshal ([...]interface {}{s .Timestamp , string (v )})
}
func (s *Scalar ) UnmarshalJSON (b []byte ) error {
var f string
v := [...]interface {}{&s .Timestamp , &f }
if err := json .Unmarshal (b , &v ); err != nil {
return err
}
value , err := strconv .ParseFloat (f , 64 )
if err != nil {
return fmt .Errorf ("error parsing sample value: %w" , err )
}
s .Value = SampleValue (value )
return nil
}
type String struct {
Value string `json:"value"`
Timestamp Time `json:"timestamp"`
}
func (s *String ) String () string {
return s .Value
}
func (s String ) MarshalJSON () ([]byte , error ) {
return json .Marshal ([]interface {}{s .Timestamp , s .Value })
}
func (s *String ) UnmarshalJSON (b []byte ) error {
v := [...]interface {}{&s .Timestamp , &s .Value }
return json .Unmarshal (b , &v )
}
type Vector []*Sample
func (vec Vector ) String () string {
entries := make ([]string , len (vec ))
for i , s := range vec {
entries [i ] = s .String ()
}
return strings .Join (entries , "\n" )
}
func (vec Vector ) Len () int { return len (vec ) }
func (vec Vector ) Swap (i , j int ) { vec [i ], vec [j ] = vec [j ], vec [i ] }
func (vec Vector ) Less (i , j int ) bool {
switch {
case vec [i ].Metric .Before (vec [j ].Metric ):
return true
case vec [j ].Metric .Before (vec [i ].Metric ):
return false
case vec [i ].Timestamp .Before (vec [j ].Timestamp ):
return true
default :
return false
}
}
func (vec Vector ) Equal (o Vector ) bool {
if len (vec ) != len (o ) {
return false
}
for i , sample := range vec {
if !sample .Equal (o [i ]) {
return false
}
}
return true
}
type Matrix []*SampleStream
func (m Matrix ) Len () int { return len (m ) }
func (m Matrix ) Less (i , j int ) bool { return m [i ].Metric .Before (m [j ].Metric ) }
func (m Matrix ) Swap (i , j int ) { m [i ], m [j ] = m [j ], m [i ] }
func (mat Matrix ) String () string {
matCp := make (Matrix , len (mat ))
copy (matCp , mat )
sort .Sort (matCp )
strs := make ([]string , len (matCp ))
for i , ss := range matCp {
strs [i ] = ss .String ()
}
return strings .Join (strs , "\n" )
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .