-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtelemetry.go
226 lines (190 loc) · 5.27 KB
/
telemetry.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
package telemetry
import (
"log/slog"
"github.com/SUSE/telemetry/pkg/client"
"github.com/SUSE/telemetry/pkg/config"
"github.com/SUSE/telemetry/pkg/types"
)
type TelemetryType = types.TelemetryType
type Tags = types.Tags
type TelemetryClass = types.TelemetryClass
const (
MANDATORY_TELEMETRY = types.MANDATORY_TELEMETRY
OPT_OUT_TELEMETRY = types.OPT_OUT_TELEMETRY
OPT_IN_TELEMETRY = types.OPT_IN_TELEMETRY
)
type GenerateFlags uint64
const (
GENERATE GenerateFlags = iota
SUBMIT GenerateFlags = 1 << (iota - 1)
)
func (gf *GenerateFlags) String() string {
flags := "GENERATE"
switch {
case gf.FlagSet(SUBMIT):
flags += "|SUBMIT"
fallthrough
default:
// nothing to do
}
return flags
}
func (gf GenerateFlags) FlagSet(flag GenerateFlags) bool {
return (gf & flag) == flag
}
func (gf GenerateFlags) SubmitRequested() bool {
return gf.FlagSet(SUBMIT)
}
func Generate(telemetry types.TelemetryType, class TelemetryClass, content []byte, tags types.Tags, flags GenerateFlags) (err error) {
// check that the telemetry type is valid
if valid, err := telemetry.Valid(); !valid {
slog.Error(
"Invalid telemetry type",
slog.String("type", string(telemetry)),
)
return err
}
// check that the telemetry content is valid
blob := types.NewTelemetryBlob(content)
// attempt to load the default config file
cfg, err := config.NewConfig(client.CONFIG_PATH)
if err != nil {
slog.Error(
"Failed to load telemetry client config",
slog.String("path", client.CONFIG_PATH),
slog.String("error", err.Error()),
)
return
}
// check if the telemetry client is enabled in config
if !cfg.Enabled {
slog.Warn("The telemetry client is disabled in the configuration; no telemetry generated")
return
}
// check that the telemetry class is enabled for generation
if !cfg.TelemetryClassEnabled(class) {
slog.Warn(
"Telemetry class generation is disabled",
slog.String("class", class.String()),
)
return
}
// check that the telemetry type is enabled for generation
if !cfg.TelemetryTypeEnabled(telemetry) {
slog.Warn(
"Telemetry class generation is disabled",
slog.String("class", class.String()),
)
return
}
// instantiate a telemetry client
tc, err := client.NewTelemetryClient(cfg)
if err != nil {
slog.Warn(
"Failed to instantiate a TelemetryClient",
slog.String("error", err.Error()),
)
return
}
// ensure the client is registered
err = tc.Register()
if err != nil {
slog.Warn(
"Failed to register TelemetryClient with upstream server",
slog.String("error", err.Error()),
)
return
}
// generate the telemetry, storing it in the local data store
err = tc.Generate(telemetry, blob, tags)
if err != nil {
slog.Warn(
"Failed to generate telemetry",
slog.String("error", err.Error()),
)
return
}
// check if immediate submission requested
if flags.SubmitRequested() {
// TODO: implement immediate submission
slog.Info("Immediate Telemetry Submission requested")
}
return
}
type ClientStatus int64
const (
CLIENT_UNINITIALIZED ClientStatus = iota
CLIENT_CONFIG_ACCESSIBLE
CLIENT_DISABLED
CLIENT_MISCONFIGURED
CLIENT_DATASTORE_ACCESSIBLE
CLIENT_INSTANCE_ID_ACCESSIBLE
CLIENT_REGISTERED
)
func (cs *ClientStatus) String() string {
switch *cs {
case CLIENT_UNINITIALIZED:
return "UNITITIALIZED"
case CLIENT_CONFIG_ACCESSIBLE:
return "CONFIG_ACCESSIBLE"
case CLIENT_DISABLED:
return "DISABLED"
case CLIENT_MISCONFIGURED:
return "MISCONFIGURED"
case CLIENT_DATASTORE_ACCESSIBLE:
return "DATASTORE_ACCESSIBLE"
case CLIENT_INSTANCE_ID_ACCESSIBLE:
return "INSTANCE_ID_ACCESSIBLE"
case CLIENT_REGISTERED:
return "REGISTERED"
}
return "UNKNOWN_TELEMETRY_CLIENT_STATUS"
}
func Status() (status ClientStatus) {
// default to being uninitialised
status = CLIENT_UNINITIALIZED
// attempt to load the default config
cfg, err := config.NewConfig(client.CONFIG_PATH)
if err != nil {
slog.Warn(
"Failed to load telemetry client config",
slog.String("path", client.CONFIG_PATH),
slog.String("error", err.Error()),
)
return
}
// update status to indicate that telemetry client configuration is accessible
status = CLIENT_CONFIG_ACCESSIBLE
// check if the telemetry client is enabled in config
if !cfg.Enabled {
slog.Info("The telemetry client is disabled in the configuration")
return CLIENT_DISABLED
}
// instantiate a telemetry client using provided config
tc, err := client.NewTelemetryClient(cfg)
if err != nil {
slog.Warn(
"Failed to setup telemetry client using provided config",
slog.String("path", client.CONFIG_PATH),
slog.String("error", err.Error()),
)
return CLIENT_MISCONFIGURED
}
// update status to indicate that telemetry client datastore is accessible
status = CLIENT_DATASTORE_ACCESSIBLE
// check that an instance id is available
if !tc.InstanceIdAccessible() {
slog.Warn("Telemetry client instance id has not been setup", slog.String("path", tc.InstIdPath()))
return
}
// update status to indicate client has instance id
status = CLIENT_INSTANCE_ID_ACCESSIBLE
// check that we have obtained a telemetry auth token
if !tc.AuthAccessible() {
slog.Warn("Telemetry client has not been registered", slog.String("path", tc.AuthPath()))
return
}
// update status to indicate telemetry client is registered
status = CLIENT_REGISTERED
return
}