forked from influxdata/telegraf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
metric.go
148 lines (127 loc) · 3.14 KB
/
metric.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 starlark
import (
"errors"
"fmt"
"strings"
"time"
"github.com/influxdata/telegraf"
"go.starlark.net/starlark"
)
type Metric struct {
metric telegraf.Metric
tagIterCount int
fieldIterCount int
frozen bool
}
// Wrap updates the starlark.Metric to wrap a new telegraf.Metric.
func (m *Metric) Wrap(metric telegraf.Metric) {
m.metric = metric
m.tagIterCount = 0
m.fieldIterCount = 0
m.frozen = false
}
// Unwrap removes the telegraf.Metric from the startlark.Metric.
func (m *Metric) Unwrap() telegraf.Metric {
return m.metric
}
// String returns the starlark representation of the Metric.
//
// The String function is called by both the repr() and str() functions, and so
// it behaves more like the repr function would in Python.
func (m *Metric) String() string {
buf := new(strings.Builder)
buf.WriteString("Metric(")
buf.WriteString(m.Name().String())
buf.WriteString(", tags=")
buf.WriteString(m.Tags().String())
buf.WriteString(", fields=")
buf.WriteString(m.Fields().String())
buf.WriteString(", time=")
buf.WriteString(m.Time().String())
buf.WriteString(")")
return buf.String()
}
func (m *Metric) Type() string {
return "Metric"
}
func (m *Metric) Freeze() {
m.frozen = true
}
func (m *Metric) Truth() starlark.Bool {
return true
}
func (m *Metric) Hash() (uint32, error) {
return 0, errors.New("not hashable")
}
// AttrNames implements the starlark.HasAttrs interface.
func (m *Metric) AttrNames() []string {
return []string{"name", "tags", "fields", "time"}
}
// Attr implements the starlark.HasAttrs interface.
func (m *Metric) Attr(name string) (starlark.Value, error) {
switch name {
case "name":
return m.Name(), nil
case "tags":
return m.Tags(), nil
case "fields":
return m.Fields(), nil
case "time":
return m.Time(), nil
default:
// Returning nil, nil indicates "no such field or method"
return nil, nil
}
}
// SetField implements the starlark.HasSetField interface.
func (m *Metric) SetField(name string, value starlark.Value) error {
if m.frozen {
return fmt.Errorf("cannot modify frozen metric")
}
switch name {
case "name":
return m.SetName(value)
case "time":
return m.SetTime(value)
case "tags":
return errors.New("cannot set tags")
case "fields":
return errors.New("cannot set fields")
default:
return starlark.NoSuchAttrError(
fmt.Sprintf("cannot assign to field '%s'", name))
}
}
func (m *Metric) Name() starlark.String {
return starlark.String(m.metric.Name())
}
func (m *Metric) SetName(value starlark.Value) error {
if str, ok := value.(starlark.String); ok {
m.metric.SetName(str.GoString())
return nil
}
return errors.New("type error")
}
func (m *Metric) Tags() TagDict {
return TagDict{m}
}
func (m *Metric) Fields() FieldDict {
return FieldDict{m}
}
func (m *Metric) Time() starlark.Int {
return starlark.MakeInt64(m.metric.Time().UnixNano())
}
func (m *Metric) SetTime(value starlark.Value) error {
switch v := value.(type) {
case starlark.Int:
ns, ok := v.Int64()
if !ok {
return errors.New("type error: unrepresentable time")
}
tm := time.Unix(0, ns)
m.metric.SetTime(tm)
return nil
default:
return errors.New("type error")
}
}