/
models.go
148 lines (130 loc) · 3.2 KB
/
models.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package influxdb
import (
"sort"
"time"
lp "github.com/influxdata/line-protocol"
)
// Metric is just a github.com/influxdata/line-protocol.Metric.
// We alias here to keep abstractions from leaking.
type Metric = lp.Metric
// Tag is just a github.com/influxdata/line-protocol.Tag.
// We alias here to keep abstractions from leaking.
type Tag = lp.Tag
// Field is just a github.com/influxdata/line-protocol.Field.
// We alias here to keep abstractions from leaking.
type Field = lp.Field
// RowMetric is a Metric,
// that has methods to make it easy to add tags and fields
type RowMetric struct {
NameStr string
Tags []*lp.Tag
Fields []*lp.Field
TS time.Time
}
// TagList returns a slice containing Tags of a Metric.
func (m *RowMetric) TagList() []*lp.Tag {
return m.Tags
}
// FieldList returns a slice containing the Fields of a Metric.
func (m *RowMetric) FieldList() []*lp.Field {
return m.Fields
}
// Time is the timestamp of a metric.
func (m *RowMetric) Time() time.Time {
return m.TS
}
// SortTags orders the tags of a metric alphnumerically by key.
// This is just here as a helper, to make it easy to keep tags sorted if you are creating a RowMetric manually.
func (m *RowMetric) SortTags() {
sort.Slice(m.Tags, func(i, j int) bool { return m.Tags[i].Key < m.Tags[j].Key })
}
// SortFields orders the fields of a metric alphnumerically by key.
func (m *RowMetric) SortFields() {
sort.Slice(m.Fields, func(i, j int) bool { return m.Fields[i].Key < m.Fields[j].Key })
}
// AddTag adds an lp.Tag to a metric.
func (m *RowMetric) AddTag(k, v string) {
for i, tag := range m.Tags {
if k == tag.Key {
m.Tags[i].Value = v
return
}
}
m.Tags = append(m.Tags, &lp.Tag{Key: k, Value: v})
}
// AddField adds an lp.Field to a metric.
func (m *RowMetric) AddField(k string, v interface{}) {
for i, field := range m.Fields {
if k == field.Key {
m.Fields[i].Value = v
return
}
}
m.Fields = append(m.Fields, &lp.Field{Key: k, Value: convertField(v)})
}
// Name returns the name of the metric.
func (m *RowMetric) Name() string {
return m.NameStr
}
func convertField(v interface{}) interface{} {
switch v := v.(type) {
case bool, int64, string, float64:
return v
case int:
return int64(v)
case uint:
return uint64(v)
case uint64:
return uint64(v)
case []byte:
return string(v)
case int32:
return int64(v)
case int16:
return int64(v)
case int8:
return int64(v)
case uint32:
return uint64(v)
case uint16:
return uint64(v)
case uint8:
return uint64(v)
case float32:
return float64(v)
default:
panic("unsupported type")
}
}
// NewRowMetric creates a *RowMetric from tags, fields and a timestamp.
func NewRowMetric(
fields map[string]interface{},
name string,
tags map[string]string,
ts time.Time,
) *RowMetric {
m := &RowMetric{
NameStr: name,
Tags: nil,
Fields: nil,
TS: ts,
}
if len(tags) > 0 {
m.Tags = make([]*lp.Tag, 0, len(tags))
for k, v := range tags {
m.Tags = append(m.Tags,
&lp.Tag{Key: k, Value: v})
}
}
m.Fields = make([]*lp.Field, 0, len(fields))
for k, v := range fields {
v := convertField(v)
if v == nil {
continue
}
m.Fields = append(m.Fields, &lp.Field{Key: k, Value: v})
}
m.SortFields()
m.SortTags()
return m
}