mirror of https://github.com/golang/go.git
internal/telemetry/export/ocagent: correctly marshal points to JSON
This change adds a custom MarshalJSON func to Point so that values are formatted the same way jsonpb formats them. This allows the OpenCensus service to determine the concrete type of the point's value when unmarshaling. What works: * Points with Int64, Double, and Distribution values will marshal correctly. What does not work: * Points with Summary values will not marshal. Updates golang/go#33819 Change-Id: Ia76ebff4e0e2b6ff2ddf72b8d6187f49069d4cad Reviewed-on: https://go-review.googlesource.com/c/tools/+/207838 Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com> Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
82924fac8e
commit
96ad48e4b0
|
|
@ -4,6 +4,11 @@
|
|||
|
||||
package wire
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ExportMetricsServiceRequest struct {
|
||||
Node *Node `json:"node,omitempty"`
|
||||
Metrics []*Metric `json:"metrics,omitempty"`
|
||||
|
|
@ -62,6 +67,48 @@ type PointInt64Value struct {
|
|||
Int64Value int64 `json:"int64Value,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON creates JSON formatted the same way as jsonpb so that the
|
||||
// OpenCensus service can correctly determine the underlying value type.
|
||||
// This custom MarshalJSON exists because,
|
||||
// by default *Point is JSON marshalled as:
|
||||
// {"value": {"int64Value": 1}}
|
||||
// but it should be marshalled as:
|
||||
// {"int64Value": 1}
|
||||
func (p *Point) MarshalJSON() ([]byte, error) {
|
||||
if p == nil {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
|
||||
switch d := p.Value.(type) {
|
||||
case PointInt64Value:
|
||||
return json.Marshal(&struct {
|
||||
Timestamp *Timestamp `json:"timestamp,omitempty"`
|
||||
Value int64 `json:"int64Value,omitempty"`
|
||||
}{
|
||||
Timestamp: p.Timestamp,
|
||||
Value: d.Int64Value,
|
||||
})
|
||||
case PointDoubleValue:
|
||||
return json.Marshal(&struct {
|
||||
Timestamp *Timestamp `json:"timestamp,omitempty"`
|
||||
Value float64 `json:"doubleValue,omitempty"`
|
||||
}{
|
||||
Timestamp: p.Timestamp,
|
||||
Value: d.DoubleValue,
|
||||
})
|
||||
case PointDistributionValue:
|
||||
return json.Marshal(&struct {
|
||||
Timestamp *Timestamp `json:"timestamp,omitempty"`
|
||||
Value *DistributionValue `json:"distributionValue,omitempty"`
|
||||
}{
|
||||
Timestamp: p.Timestamp,
|
||||
Value: d.DistributionValue,
|
||||
})
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown point type %T", p.Value)
|
||||
}
|
||||
}
|
||||
|
||||
type PointDoubleValue struct {
|
||||
DoubleValue float64 `json:"doubleValue,omitempty"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
package wire
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMarshalJSON(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pt *Point
|
||||
want string
|
||||
}{
|
||||
{
|
||||
"PointInt64",
|
||||
&Point{
|
||||
Value: PointInt64Value{
|
||||
Int64Value: 5,
|
||||
},
|
||||
},
|
||||
`{"int64Value":5}`,
|
||||
},
|
||||
{
|
||||
"PointDouble",
|
||||
&Point{
|
||||
Value: PointDoubleValue{
|
||||
DoubleValue: 3.14,
|
||||
},
|
||||
},
|
||||
`{"doubleValue":3.14}`,
|
||||
},
|
||||
{
|
||||
"PointDistribution",
|
||||
&Point{
|
||||
Value: PointDistributionValue{
|
||||
DistributionValue: &DistributionValue{
|
||||
Count: 3,
|
||||
Sum: 10,
|
||||
Buckets: []*Bucket{
|
||||
{
|
||||
Count: 1,
|
||||
},
|
||||
{
|
||||
Count: 2,
|
||||
},
|
||||
},
|
||||
BucketOptions: BucketOptionsExplicit{
|
||||
Bounds: []float64{
|
||||
0, 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
`{"distributionValue":{"count":3,"sum":10,"bucket_options":{"bounds":[0,5]},"buckets":[{"count":1},{"count":2}]}}`,
|
||||
},
|
||||
{
|
||||
"nil point",
|
||||
nil,
|
||||
`null`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
buf, err := tt.pt.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatalf("Got:\n%v\nWant:\n%v", err, nil)
|
||||
}
|
||||
got := string(buf)
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Fatalf("Got:\n%s\nWant:\n%s", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue