Skip to content

Commit 305a1b6

Browse files
committed
fix schema and id generation to be metrics2.0 compliant
* rename target_type to mtype - see metrics20/spec@2fa3265 * include mtype and unit into metric id. this is an overdue correction * base id off of metric, not name. see grafana/metrictank#30 (comment) * include interval into metric id. e.g. treat it like any other tag. after some discussion we think this will be the cleanest way to support multiple intervals for a given metric, metrictank just has to merge multiple metrics together. see grafana/metrictank#80 * remove references to nodejs note: this makes SetId about 27% slower
1 parent 1c574f3 commit 305a1b6

5 files changed

+66
-60
lines changed

event_gen.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func (z *ProbeEvent) DecodeMsg(dc *msgp.Reader) (err error) {
6868
if z.Tags == nil && msz > 0 {
6969
z.Tags = make(map[string]string, msz)
7070
} else if len(z.Tags) > 0 {
71-
for key := range z.Tags {
71+
for key, _ := range z.Tags {
7272
delete(z.Tags, key)
7373
}
7474
}
@@ -279,7 +279,7 @@ func (z *ProbeEvent) UnmarshalMsg(bts []byte) (o []byte, err error) {
279279
if z.Tags == nil && msz > 0 {
280280
z.Tags = make(map[string]string, msz)
281281
} else if len(z.Tags) > 0 {
282-
for key := range z.Tags {
282+
for key, _ := range z.Tags {
283283
delete(z.Tags, key)
284284
}
285285
}

metric.go

+22-16
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,31 @@ var errInvalidEmptyName = errors.New("name cannot be empty")
1818

1919
// MetricData contains all metric metadata and a datapoint
2020
type MetricData struct {
21-
Id string `json:"id"`
22-
OrgId int `json:"org_id"`
23-
Name string `json:"name"`
24-
Metric string `json:"metric"`
25-
Interval int `json:"interval"`
26-
Value float64 `json:"value"`
27-
Unit string `json:"unit"`
28-
Time int64 `json:"time"`
29-
TargetType string `json:"target_type"`
30-
Tags []string `json:"tags" elastic:"type:string,index:not_analyzed"`
21+
Id string `json:"id"`
22+
OrgId int `json:"org_id"`
23+
Name string `json:"name"`
24+
Metric string `json:"metric"`
25+
Interval int `json:"interval"`
26+
Value float64 `json:"value"`
27+
Unit string `json:"unit"`
28+
Time int64 `json:"time"`
29+
Mtype string `json:"mtype"`
30+
Tags []string `json:"tags" elastic:"type:string,index:not_analyzed"`
3131
}
3232

3333
// returns a id (hash key) in the format OrgId.md5Sum
3434
// the md5sum is a hash of the the concatination of the
35-
// series name + each tag key:value pair, sorted alphabetically.
35+
// metric + each tag key:value pair (in metrics2.0 sense, so also fields), sorted alphabetically.
3636
func (m *MetricData) SetId() {
3737
var buffer bytes.Buffer
38-
buffer.WriteString(m.Name)
39-
sort.Strings(m.Tags)
38+
buffer.WriteString(m.Metric)
39+
// all metrics2.0 tags - some of which are stored as fields here
40+
tags := make([]string, len(m.Tags)+3)
41+
copy(tags, m.Tags)
42+
tags[len(m.Tags)] = fmt.Sprintf("interval:%d")
43+
tags[len(m.Tags)+1] = "mtype:" + m.Mtype
44+
tags[len(m.Tags)+2] = "unit:" + m.Unit
45+
sort.Strings(tags)
4046
for _, k := range m.Tags {
4147
buffer.WriteString(fmt.Sprintf(";%s", k))
4248
}
@@ -54,9 +60,9 @@ type MetricDefinition struct {
5460
Metric string `json:"metric"` // kairosdb format (like graphite, but not including some tags)
5561
Interval int `json:"interval"` // minimum 10
5662
Unit string `json:"unit"`
57-
TargetType string `json:"target_type"` // an emum ["derive","gauge"] in nodejs
63+
Mtype string `json:"mtype"`
5864
Tags []string `json:"tags" elastic:"type:string,index:not_analyzed"`
59-
LastUpdate int64 `json:"lastUpdate"` // unix epoch time, per the nodejs definition
65+
LastUpdate int64 `json:"lastUpdate"` // unix timestamp
6066
Nodes map[string]string `json:"nodes"`
6167
NodeCount int `json:"node_count"`
6268
}
@@ -108,7 +114,7 @@ func MetricDefinitionFromMetricData(d *MetricData) *MetricDefinition {
108114
Name: d.Name,
109115
OrgId: d.OrgId,
110116
Metric: d.Metric,
111-
TargetType: d.TargetType,
117+
Mtype: d.Mtype,
112118
Interval: d.Interval,
113119
LastUpdate: d.Time,
114120
Unit: d.Unit,

metric_gen.go

+24-24
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ func (z *MetricData) DecodeMsg(dc *msgp.Reader) (err error) {
6464
if err != nil {
6565
return
6666
}
67-
case "TargetType":
68-
z.TargetType, err = dc.ReadString()
67+
case "Mtype":
68+
z.Mtype, err = dc.ReadString()
6969
if err != nil {
7070
return
7171
}
@@ -171,12 +171,12 @@ func (z *MetricData) EncodeMsg(en *msgp.Writer) (err error) {
171171
if err != nil {
172172
return
173173
}
174-
// write "TargetType"
175-
err = en.Append(0xaa, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65)
174+
// write "Mtype"
175+
err = en.Append(0xa5, 0x4d, 0x74, 0x79, 0x70, 0x65)
176176
if err != nil {
177177
return err
178178
}
179-
err = en.WriteString(z.TargetType)
179+
err = en.WriteString(z.Mtype)
180180
if err != nil {
181181
return
182182
}
@@ -226,9 +226,9 @@ func (z *MetricData) MarshalMsg(b []byte) (o []byte, err error) {
226226
// string "Time"
227227
o = append(o, 0xa4, 0x54, 0x69, 0x6d, 0x65)
228228
o = msgp.AppendInt64(o, z.Time)
229-
// string "TargetType"
230-
o = append(o, 0xaa, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65)
231-
o = msgp.AppendString(o, z.TargetType)
229+
// string "Mtype"
230+
o = append(o, 0xa5, 0x4d, 0x74, 0x79, 0x70, 0x65)
231+
o = msgp.AppendString(o, z.Mtype)
232232
// string "Tags"
233233
o = append(o, 0xa4, 0x54, 0x61, 0x67, 0x73)
234234
o = msgp.AppendArrayHeader(o, uint32(len(z.Tags)))
@@ -294,8 +294,8 @@ func (z *MetricData) UnmarshalMsg(bts []byte) (o []byte, err error) {
294294
if err != nil {
295295
return
296296
}
297-
case "TargetType":
298-
z.TargetType, bts, err = msgp.ReadStringBytes(bts)
297+
case "Mtype":
298+
z.Mtype, bts, err = msgp.ReadStringBytes(bts)
299299
if err != nil {
300300
return
301301
}
@@ -328,7 +328,7 @@ func (z *MetricData) UnmarshalMsg(bts []byte) (o []byte, err error) {
328328
}
329329

330330
func (z *MetricData) Msgsize() (s int) {
331-
s = 1 + 3 + msgp.StringPrefixSize + len(z.Id) + 6 + msgp.IntSize + 5 + msgp.StringPrefixSize + len(z.Name) + 7 + msgp.StringPrefixSize + len(z.Metric) + 9 + msgp.IntSize + 6 + msgp.Float64Size + 5 + msgp.StringPrefixSize + len(z.Unit) + 5 + msgp.Int64Size + 11 + msgp.StringPrefixSize + len(z.TargetType) + 5 + msgp.ArrayHeaderSize
331+
s = 1 + 3 + msgp.StringPrefixSize + len(z.Id) + 6 + msgp.IntSize + 5 + msgp.StringPrefixSize + len(z.Name) + 7 + msgp.StringPrefixSize + len(z.Metric) + 9 + msgp.IntSize + 6 + msgp.Float64Size + 5 + msgp.StringPrefixSize + len(z.Unit) + 5 + msgp.Int64Size + 6 + msgp.StringPrefixSize + len(z.Mtype) + 5 + msgp.ArrayHeaderSize
332332
for xvk := range z.Tags {
333333
s += msgp.StringPrefixSize + len(z.Tags[xvk])
334334
}
@@ -497,8 +497,8 @@ func (z *MetricDefinition) DecodeMsg(dc *msgp.Reader) (err error) {
497497
if err != nil {
498498
return
499499
}
500-
case "TargetType":
501-
z.TargetType, err = dc.ReadString()
500+
case "Mtype":
501+
z.Mtype, err = dc.ReadString()
502502
if err != nil {
503503
return
504504
}
@@ -533,7 +533,7 @@ func (z *MetricDefinition) DecodeMsg(dc *msgp.Reader) (err error) {
533533
if z.Nodes == nil && msz > 0 {
534534
z.Nodes = make(map[string]string, msz)
535535
} else if len(z.Nodes) > 0 {
536-
for key := range z.Nodes {
536+
for key, _ := range z.Nodes {
537537
delete(z.Nodes, key)
538538
}
539539
}
@@ -623,12 +623,12 @@ func (z *MetricDefinition) EncodeMsg(en *msgp.Writer) (err error) {
623623
if err != nil {
624624
return
625625
}
626-
// write "TargetType"
627-
err = en.Append(0xaa, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65)
626+
// write "Mtype"
627+
err = en.Append(0xa5, 0x4d, 0x74, 0x79, 0x70, 0x65)
628628
if err != nil {
629629
return err
630630
}
631-
err = en.WriteString(z.TargetType)
631+
err = en.WriteString(z.Mtype)
632632
if err != nil {
633633
return
634634
}
@@ -709,9 +709,9 @@ func (z *MetricDefinition) MarshalMsg(b []byte) (o []byte, err error) {
709709
// string "Unit"
710710
o = append(o, 0xa4, 0x55, 0x6e, 0x69, 0x74)
711711
o = msgp.AppendString(o, z.Unit)
712-
// string "TargetType"
713-
o = append(o, 0xaa, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65)
714-
o = msgp.AppendString(o, z.TargetType)
712+
// string "Mtype"
713+
o = append(o, 0xa5, 0x4d, 0x74, 0x79, 0x70, 0x65)
714+
o = msgp.AppendString(o, z.Mtype)
715715
// string "Tags"
716716
o = append(o, 0xa4, 0x54, 0x61, 0x67, 0x73)
717717
o = msgp.AppendArrayHeader(o, uint32(len(z.Tags)))
@@ -780,8 +780,8 @@ func (z *MetricDefinition) UnmarshalMsg(bts []byte) (o []byte, err error) {
780780
if err != nil {
781781
return
782782
}
783-
case "TargetType":
784-
z.TargetType, bts, err = msgp.ReadStringBytes(bts)
783+
case "Mtype":
784+
z.Mtype, bts, err = msgp.ReadStringBytes(bts)
785785
if err != nil {
786786
return
787787
}
@@ -816,7 +816,7 @@ func (z *MetricDefinition) UnmarshalMsg(bts []byte) (o []byte, err error) {
816816
if z.Nodes == nil && msz > 0 {
817817
z.Nodes = make(map[string]string, msz)
818818
} else if len(z.Nodes) > 0 {
819-
for key := range z.Nodes {
819+
for key, _ := range z.Nodes {
820820
delete(z.Nodes, key)
821821
}
822822
}
@@ -851,7 +851,7 @@ func (z *MetricDefinition) UnmarshalMsg(bts []byte) (o []byte, err error) {
851851
}
852852

853853
func (z *MetricDefinition) Msgsize() (s int) {
854-
s = 1 + 3 + msgp.StringPrefixSize + len(z.Id) + 6 + msgp.IntSize + 5 + msgp.StringPrefixSize + len(z.Name) + 7 + msgp.StringPrefixSize + len(z.Metric) + 9 + msgp.IntSize + 5 + msgp.StringPrefixSize + len(z.Unit) + 11 + msgp.StringPrefixSize + len(z.TargetType) + 5 + msgp.ArrayHeaderSize
854+
s = 1 + 3 + msgp.StringPrefixSize + len(z.Id) + 6 + msgp.IntSize + 5 + msgp.StringPrefixSize + len(z.Name) + 7 + msgp.StringPrefixSize + len(z.Metric) + 9 + msgp.IntSize + 5 + msgp.StringPrefixSize + len(z.Unit) + 6 + msgp.StringPrefixSize + len(z.Mtype) + 5 + msgp.ArrayHeaderSize
855855
for hct := range z.Tags {
856856
s += msgp.StringPrefixSize + len(z.Tags[hct])
857857
}

metric_serialization_bench_test.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ func getDifferentMetrics(amount int) []*MetricData {
3434
out := make([]*MetricData, amount)
3535
for i := 0; i < amount; i++ {
3636
out[i] = &MetricData{
37-
OrgId: i,
38-
Name: names[i%len(names)] + "foo.bar" + strconv.Itoa(i),
39-
Metric: names[i%len(names)],
40-
Interval: intervals[i%len(intervals)],
41-
Value: r.Float64(),
42-
Unit: "foo",
43-
Time: r.Int63(),
44-
TargetType: "bleh",
45-
Tags: tags[i%len(tags)],
37+
OrgId: i,
38+
Name: names[i%len(names)] + "foo.bar" + strconv.Itoa(i),
39+
Metric: names[i%len(names)],
40+
Interval: intervals[i%len(intervals)],
41+
Value: r.Float64(),
42+
Unit: "foo",
43+
Time: r.Int63(),
44+
Mtype: "bleh",
45+
Tags: tags[i%len(tags)],
4646
}
4747
}
4848
return out

metric_test.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ import (
66

77
func BenchmarkSetId(b *testing.B) {
88
metric := MetricData{
9-
OrgId: 1234,
10-
Name: "key1=val1.key2=val2.my.test.metric.name",
11-
Metric: "my.test.metric.name",
12-
Interval: 15,
13-
Value: 0.1234,
14-
Unit: "ms",
15-
Time: 1234567890,
16-
TargetType: "gauge",
17-
Tags: []string{"key1:val1", "key2:val2"},
9+
OrgId: 1234,
10+
Name: "key1=val1.key2=val2.my.test.metric.name",
11+
Metric: "my.test.metric.name",
12+
Interval: 15,
13+
Value: 0.1234,
14+
Unit: "ms",
15+
Time: 1234567890,
16+
Mtype: "gauge",
17+
Tags: []string{"key1:val1", "key2:val2"},
1818
}
1919
for i := 0; i < b.N; i++ {
2020
metric.SetId()

0 commit comments

Comments
 (0)