mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-29 02:01:43 +00:00
Restore custom encoders/decoders for backwards compatibility
This commit is contained in:
@@ -77,10 +77,6 @@ func TestProbe(t *testing.T) {
|
||||
want := report.MakeReport()
|
||||
node := report.MakeNodeWith("a", map[string]string{"b": "c"})
|
||||
|
||||
// DeepEqual doesn't handle the location of timestamps correctly
|
||||
// See https://github.com/golang/go/issues/10089
|
||||
node.Controls.Timestamp = time.Now()
|
||||
|
||||
// marshalling->unmarshaling is not idempotent due to `json:"omitempty"`
|
||||
// tags, transforming empty slices into nils. So, we make DeepEqual
|
||||
// happy by setting empty `json:"omitempty"` entries to nil
|
||||
|
||||
@@ -3,6 +3,7 @@ package report
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ugorji/go/codec"
|
||||
"github.com/weaveworks/scope/common/mtime"
|
||||
)
|
||||
|
||||
@@ -83,3 +84,39 @@ func (nc NodeControls) Add(ids ...string) NodeControls {
|
||||
Controls: nc.Controls.Add(ids...),
|
||||
}
|
||||
}
|
||||
|
||||
// WireNodeControls is the intermediate type for json encoding.
|
||||
type WireNodeControls struct {
|
||||
Timestamp string `json:"timestamp,omitempty"`
|
||||
Controls StringSet `json:"controls,omitempty"`
|
||||
}
|
||||
|
||||
// CodecEncodeSelf implements codec.Selfer
|
||||
func (nc *NodeControls) CodecEncodeSelf(encoder *codec.Encoder) {
|
||||
encoder.Encode(WireNodeControls{
|
||||
Timestamp: renderTime(nc.Timestamp),
|
||||
Controls: nc.Controls,
|
||||
})
|
||||
}
|
||||
|
||||
// CodecDecodeSelf implements codec.Selfer
|
||||
func (nc *NodeControls) CodecDecodeSelf(decoder *codec.Decoder) {
|
||||
in := WireNodeControls{}
|
||||
if err := decoder.Decode(&in); err != nil {
|
||||
return
|
||||
}
|
||||
*nc = NodeControls{
|
||||
Timestamp: parseTime(in.Timestamp),
|
||||
Controls: in.Controls,
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON shouldn't be used, use CodecEncodeSelf instead
|
||||
func (NodeControls) MarshalJSON() ([]byte, error) {
|
||||
panic("MarshalJSON shouldn't be used, use CodecEncodeSelf instead")
|
||||
}
|
||||
|
||||
// UnmarshalJSON shouldn't be used, use CodecDecodeSelf instead
|
||||
func (*NodeControls) UnmarshalJSON(b []byte) error {
|
||||
panic("UnmarshalJSON shouldn't be used, use CodecDecodeSelf instead")
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package report
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ugorji/go/codec"
|
||||
)
|
||||
|
||||
@@ -57,22 +55,23 @@ func (*MetricRow) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
type wiredMetricRow struct {
|
||||
ID string `json:"id"`
|
||||
Label string `json:"label"`
|
||||
Format string `json:"format,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
Value float64 `json:"value"`
|
||||
Priority float64 `json:"priority,omitempty"`
|
||||
Samples []Sample `json:"samples"`
|
||||
Min float64 `json:"min"`
|
||||
Max float64 `json:"max"`
|
||||
First time.Time `json:"first,omitempty"`
|
||||
Last time.Time `json:"last,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Label string `json:"label"`
|
||||
Format string `json:"format,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
Value float64 `json:"value"`
|
||||
Priority float64 `json:"priority,omitempty"`
|
||||
Samples []Sample `json:"samples"`
|
||||
Min float64 `json:"min"`
|
||||
Max float64 `json:"max"`
|
||||
First string `json:"first,omitempty"`
|
||||
Last string `json:"last,omitempty"`
|
||||
}
|
||||
|
||||
// CodecEncodeSelf marshals this MetricRow. It takes the basic Metric
|
||||
// rendering, then adds some row-specific fields.
|
||||
func (m *MetricRow) CodecEncodeSelf(encoder *codec.Encoder) {
|
||||
in := m.Metric.ToIntermediate()
|
||||
encoder.Encode(wiredMetricRow{
|
||||
ID: m.ID,
|
||||
Label: m.Label,
|
||||
@@ -80,11 +79,11 @@ func (m *MetricRow) CodecEncodeSelf(encoder *codec.Encoder) {
|
||||
Group: m.Group,
|
||||
Value: m.Value,
|
||||
Priority: m.Priority,
|
||||
Samples: m.Metric.Samples,
|
||||
Min: m.Metric.Min,
|
||||
Max: m.Metric.Max,
|
||||
First: m.Metric.First,
|
||||
Last: m.Metric.Last,
|
||||
Samples: in.Samples,
|
||||
Min: in.Min,
|
||||
Max: in.Max,
|
||||
First: in.First,
|
||||
Last: in.Last,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -92,6 +91,14 @@ func (m *MetricRow) CodecEncodeSelf(encoder *codec.Encoder) {
|
||||
func (m *MetricRow) CodecDecodeSelf(decoder *codec.Decoder) {
|
||||
var in wiredMetricRow
|
||||
decoder.Decode(&in)
|
||||
w := WireMetrics{
|
||||
Samples: in.Samples,
|
||||
Min: in.Min,
|
||||
Max: in.Max,
|
||||
First: in.First,
|
||||
Last: in.Last,
|
||||
}
|
||||
metric := w.FromIntermediate()
|
||||
*m = MetricRow{
|
||||
ID: in.ID,
|
||||
Label: in.Label,
|
||||
@@ -99,13 +106,7 @@ func (m *MetricRow) CodecDecodeSelf(decoder *codec.Decoder) {
|
||||
Group: in.Group,
|
||||
Value: in.Value,
|
||||
Priority: in.Priority,
|
||||
Metric: &Metric{
|
||||
Samples: in.Samples,
|
||||
Min: in.Min,
|
||||
Max: in.Max,
|
||||
First: in.First,
|
||||
Last: in.Last,
|
||||
},
|
||||
Metric: &metric,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ package report
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/ugorji/go/codec"
|
||||
)
|
||||
|
||||
// Metrics is a string->metric map.
|
||||
@@ -36,11 +38,9 @@ func (m Metrics) Copy() Metrics {
|
||||
// Metric is a list of timeseries data with some metadata. Clients must use the
|
||||
// Add method to add values. Metrics are immutable.
|
||||
type Metric struct {
|
||||
Samples []Sample `json:"samples"`
|
||||
Min float64 `json:"min"`
|
||||
Max float64 `json:"max"`
|
||||
First time.Time `json:"first"`
|
||||
Last time.Time `json:"last"`
|
||||
Samples []Sample
|
||||
Min, Max float64
|
||||
First, Last time.Time
|
||||
}
|
||||
|
||||
// Sample is a single datapoint of a metric.
|
||||
@@ -206,3 +206,73 @@ func (m Metric) LastSample() (Sample, bool) {
|
||||
}
|
||||
return m.Samples[len(m.Samples)-1], true
|
||||
}
|
||||
|
||||
// WireMetrics is the on-the-wire representation of Metrics.
|
||||
type WireMetrics struct {
|
||||
Samples []Sample `json:"samples,omitempty"` // On the wire, samples are sorted oldest to newest,
|
||||
Min float64 `json:"min"` // the opposite order to how we store them internally.
|
||||
Max float64 `json:"max"`
|
||||
First string `json:"first,omitempty"`
|
||||
Last string `json:"last,omitempty"`
|
||||
}
|
||||
|
||||
func renderTime(t time.Time) string {
|
||||
if t.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return t.Format(time.RFC3339Nano)
|
||||
}
|
||||
|
||||
func parseTime(s string) time.Time {
|
||||
t, _ := time.Parse(time.RFC3339Nano, s)
|
||||
return t
|
||||
}
|
||||
|
||||
// ToIntermediate converts the metric to a representation suitable
|
||||
// for serialization.
|
||||
func (m Metric) ToIntermediate() WireMetrics {
|
||||
return WireMetrics{
|
||||
Samples: m.Samples,
|
||||
Max: m.Max,
|
||||
Min: m.Min,
|
||||
First: renderTime(m.First),
|
||||
Last: renderTime(m.Last),
|
||||
}
|
||||
}
|
||||
|
||||
// FromIntermediate obtains the metric from a representation suitable
|
||||
// for serialization.
|
||||
func (m WireMetrics) FromIntermediate() Metric {
|
||||
return Metric{
|
||||
Samples: m.Samples,
|
||||
Max: m.Max,
|
||||
Min: m.Min,
|
||||
First: parseTime(m.First),
|
||||
Last: parseTime(m.Last),
|
||||
}
|
||||
}
|
||||
|
||||
// CodecEncodeSelf implements codec.Selfer
|
||||
func (m *Metric) CodecEncodeSelf(encoder *codec.Encoder) {
|
||||
in := m.ToIntermediate()
|
||||
encoder.Encode(in)
|
||||
}
|
||||
|
||||
// CodecDecodeSelf implements codec.Selfer
|
||||
func (m *Metric) CodecDecodeSelf(decoder *codec.Decoder) {
|
||||
in := WireMetrics{}
|
||||
if err := decoder.Decode(&in); err != nil {
|
||||
return
|
||||
}
|
||||
*m = in.FromIntermediate()
|
||||
}
|
||||
|
||||
// MarshalJSON shouldn't be used, use CodecEncodeSelf instead
|
||||
func (Metric) MarshalJSON() ([]byte, error) {
|
||||
panic("MarshalJSON shouldn't be used, use CodecEncodeSelf instead")
|
||||
}
|
||||
|
||||
// UnmarshalJSON shouldn't be used, use CodecDecodeSelf instead
|
||||
func (*Metric) UnmarshalJSON(b []byte) error {
|
||||
panic("UnmarshalJSON shouldn't be used, use CodecDecodeSelf instead")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user