Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/integrations/v2/app_agent_receiver/payload.go
5363 views
1
package app_agent_receiver
2
3
import (
4
"fmt"
5
"sort"
6
"strings"
7
"time"
8
9
"go.opentelemetry.io/collector/pdata/pcommon"
10
"go.opentelemetry.io/collector/pdata/ptrace"
11
)
12
13
// Payload is the body of the receiver request
14
type Payload struct {
15
Exceptions []Exception `json:"exceptions,omitempty"`
16
Logs []Log `json:"logs,omitempty"`
17
Measurements []Measurement `json:"measurements,omitempty"`
18
Events []Event `json:"events,omitempty"`
19
Meta Meta `json:"meta,omitempty"`
20
Traces *Traces `json:"traces,omitempty"`
21
}
22
23
// Frame struct represents a single stacktrace frame
24
type Frame struct {
25
Function string `json:"function,omitempty"`
26
Module string `json:"module,omitempty"`
27
Filename string `json:"filename,omitempty"`
28
Lineno int `json:"lineno,omitempty"`
29
Colno int `json:"colno,omitempty"`
30
}
31
32
// String function converts a Frame into a human readable string
33
func (frame Frame) String() string {
34
module := ""
35
if len(frame.Module) > 0 {
36
module = frame.Module + "|"
37
}
38
return fmt.Sprintf("\n at %s (%s%s:%v:%v)", frame.Function, module, frame.Filename, frame.Lineno, frame.Colno)
39
}
40
41
// Stacktrace is a collection of Frames
42
type Stacktrace struct {
43
Frames []Frame `json:"frames,omitempty"`
44
}
45
46
// Exception struct controls all the data regarding an exception
47
type Exception struct {
48
Type string `json:"type,omitempty"`
49
Value string `json:"value,omitempty"`
50
Stacktrace *Stacktrace `json:"stacktrace,omitempty"`
51
Timestamp time.Time `json:"timestamp"`
52
Trace TraceContext `json:"trace,omitempty"`
53
}
54
55
// Message string is concatenating of the Exception.Type and Exception.Value
56
func (e Exception) Message() string {
57
return fmt.Sprintf("%s: %s", e.Type, e.Value)
58
}
59
60
// String is the string representation of an Exception
61
func (e Exception) String() string {
62
var stacktrace = e.Message()
63
if e.Stacktrace != nil {
64
for _, frame := range e.Stacktrace.Frames {
65
stacktrace += frame.String()
66
}
67
}
68
return stacktrace
69
}
70
71
// KeyVal representation of the exception object
72
func (e Exception) KeyVal() *KeyVal {
73
kv := NewKeyVal()
74
KeyValAdd(kv, "timestamp", e.Timestamp.String())
75
KeyValAdd(kv, "kind", "exception")
76
KeyValAdd(kv, "type", e.Type)
77
KeyValAdd(kv, "value", e.Value)
78
KeyValAdd(kv, "stacktrace", e.String())
79
MergeKeyVal(kv, e.Trace.KeyVal())
80
return kv
81
}
82
83
// TraceContext holds trace id and span id associated to an entity (log, exception, measurement...).
84
type TraceContext struct {
85
TraceID string `json:"trace_id"`
86
SpanID string `json:"span_id"`
87
}
88
89
// KeyVal representation of the trace context object.
90
func (tc TraceContext) KeyVal() *KeyVal {
91
retv := NewKeyVal()
92
KeyValAdd(retv, "traceID", tc.TraceID)
93
KeyValAdd(retv, "spanID", tc.SpanID)
94
return retv
95
}
96
97
// Traces wraps the otel traces model.
98
type Traces struct {
99
ptrace.Traces
100
}
101
102
// UnmarshalJSON unmarshals Traces model.
103
func (t *Traces) UnmarshalJSON(b []byte) error {
104
unmarshaler := &ptrace.JSONUnmarshaler{}
105
td, err := unmarshaler.UnmarshalTraces(b)
106
if err != nil {
107
return err
108
}
109
*t = Traces{td}
110
return nil
111
}
112
113
// MarshalJSON marshals Traces model to json.
114
func (t Traces) MarshalJSON() ([]byte, error) {
115
marshaler := &ptrace.JSONMarshaler{}
116
return marshaler.MarshalTraces(t.Traces)
117
}
118
119
// SpanSlice unpacks Traces entity into a slice of Spans.
120
func (t Traces) SpanSlice() []ptrace.Span {
121
spans := make([]ptrace.Span, 0)
122
rss := t.ResourceSpans()
123
for i := 0; i < rss.Len(); i++ {
124
rs := rss.At(i)
125
ilss := rs.ScopeSpans()
126
for j := 0; j < ilss.Len(); j++ {
127
s := ilss.At(j).Spans()
128
for si := 0; si < s.Len(); si++ {
129
spans = append(spans, s.At(si))
130
}
131
}
132
}
133
return spans
134
}
135
136
// SpanToKeyVal returns KeyVal representation of a Span.
137
func SpanToKeyVal(s ptrace.Span) *KeyVal {
138
kv := NewKeyVal()
139
if s.StartTimestamp() > 0 {
140
KeyValAdd(kv, "timestamp", s.StartTimestamp().AsTime().String())
141
}
142
if s.EndTimestamp() > 0 {
143
KeyValAdd(kv, "end_timestamp", s.StartTimestamp().AsTime().String())
144
}
145
KeyValAdd(kv, "kind", "span")
146
KeyValAdd(kv, "traceID", s.TraceID().HexString())
147
KeyValAdd(kv, "spanID", s.SpanID().HexString())
148
KeyValAdd(kv, "span_kind", s.Kind().String())
149
KeyValAdd(kv, "name", s.Name())
150
KeyValAdd(kv, "parent_spanID", s.ParentSpanID().HexString())
151
s.Attributes().Range(func(k string, v pcommon.Value) bool {
152
KeyValAdd(kv, "attr_"+k, fmt.Sprintf("%v", v))
153
return true
154
})
155
156
return kv
157
}
158
159
// LogLevel is log level enum for incoming app logs
160
type LogLevel string
161
162
const (
163
// LogLevelTrace is "trace"
164
LogLevelTrace LogLevel = "trace"
165
// LogLevelDebug is "debug"
166
LogLevelDebug LogLevel = "debug"
167
// LogLevelInfo is "info"
168
LogLevelInfo LogLevel = "info"
169
// LogLevelWarning is "warning"
170
LogLevelWarning LogLevel = "warning"
171
// LogLevelError is "error"
172
LogLevelError LogLevel = "error"
173
)
174
175
// LogContext is a string to string map structure that
176
// represents the context of a log message
177
type LogContext map[string]string
178
179
// Log struct controls the data that come into a Log message
180
type Log struct {
181
Message string `json:"message,omitempty"`
182
LogLevel LogLevel `json:"level,omitempty"`
183
Context LogContext `json:"context,omitempty"`
184
Timestamp time.Time `json:"timestamp"`
185
Trace TraceContext `json:"trace,omitempty"`
186
}
187
188
// KeyVal representation of a Log object
189
func (l Log) KeyVal() *KeyVal {
190
kv := NewKeyVal()
191
KeyValAdd(kv, "timestamp", l.Timestamp.String())
192
KeyValAdd(kv, "kind", "log")
193
KeyValAdd(kv, "message", l.Message)
194
KeyValAdd(kv, "level", string(l.LogLevel))
195
MergeKeyValWithPrefix(kv, KeyValFromMap(l.Context), "context_")
196
MergeKeyVal(kv, l.Trace.KeyVal())
197
return kv
198
}
199
200
// Measurement holds the data for user provided measurements
201
type Measurement struct {
202
Values map[string]float64 `json:"values,omitempty"`
203
Timestamp time.Time `json:"timestamp,omitempty"`
204
Trace TraceContext `json:"trace,omitempty"`
205
}
206
207
// KeyVal representation of the exception object
208
func (m Measurement) KeyVal() *KeyVal {
209
kv := NewKeyVal()
210
211
KeyValAdd(kv, "timestamp", m.Timestamp.String())
212
KeyValAdd(kv, "kind", "measurement")
213
214
keys := make([]string, 0, len(m.Values))
215
for k := range m.Values {
216
keys = append(keys, k)
217
}
218
sort.Strings(keys)
219
for _, k := range keys {
220
KeyValAdd(kv, k, fmt.Sprintf("%f", m.Values[k]))
221
}
222
MergeKeyVal(kv, m.Trace.KeyVal())
223
return kv
224
}
225
226
// SDK holds metadata about the app agent that produced the event
227
type SDK struct {
228
Name string `json:"name,omitempty"`
229
Version string `json:"version,omitempty"`
230
Integrations []SDKIntegration `json:"integrations,omitempty"`
231
}
232
233
// KeyVal produces key->value representation of Sdk metadata
234
func (sdk SDK) KeyVal() *KeyVal {
235
kv := NewKeyVal()
236
KeyValAdd(kv, "name", sdk.Name)
237
KeyValAdd(kv, "version", sdk.Version)
238
239
if len(sdk.Integrations) > 0 {
240
integrations := make([]string, len(sdk.Integrations))
241
242
for i, integration := range sdk.Integrations {
243
integrations[i] = integration.String()
244
}
245
246
KeyValAdd(kv, "integrations", strings.Join(integrations, ","))
247
}
248
249
return kv
250
}
251
252
// SDKIntegration holds metadata about a plugin/integration on the app agent that collected and sent the event
253
type SDKIntegration struct {
254
Name string `json:"name,omitempty"`
255
Version string `json:"version,omitempty"`
256
}
257
258
func (i SDKIntegration) String() string {
259
return fmt.Sprintf("%s:%s", i.Name, i.Version)
260
}
261
262
// User holds metadata about the user related to an app event
263
type User struct {
264
Email string `json:"email,omitempty"`
265
ID string `json:"id,omitempty"`
266
Username string `json:"username,omitempty"`
267
Attributes map[string]string `json:"attributes,omitempty"`
268
}
269
270
// KeyVal produces a key->value representation User metadata
271
func (u User) KeyVal() *KeyVal {
272
kv := NewKeyVal()
273
KeyValAdd(kv, "email", u.Email)
274
KeyValAdd(kv, "id", u.ID)
275
KeyValAdd(kv, "username", u.Username)
276
MergeKeyValWithPrefix(kv, KeyValFromMap(u.Attributes), "attr_")
277
return kv
278
}
279
280
// Meta holds metadata about an app event
281
type Meta struct {
282
SDK SDK `json:"sdk,omitempty"`
283
App App `json:"app,omitempty"`
284
User User `json:"user,omitempty"`
285
Session Session `json:"session,omitempty"`
286
Page Page `json:"page,omitempty"`
287
Browser Browser `json:"browser,omitempty"`
288
View View `json:"view,omitempty"`
289
}
290
291
// KeyVal produces key->value representation of the app event metadata
292
func (m Meta) KeyVal() *KeyVal {
293
kv := NewKeyVal()
294
MergeKeyValWithPrefix(kv, m.SDK.KeyVal(), "sdk_")
295
MergeKeyValWithPrefix(kv, m.App.KeyVal(), "app_")
296
MergeKeyValWithPrefix(kv, m.User.KeyVal(), "user_")
297
MergeKeyValWithPrefix(kv, m.Session.KeyVal(), "session_")
298
MergeKeyValWithPrefix(kv, m.Page.KeyVal(), "page_")
299
MergeKeyValWithPrefix(kv, m.Browser.KeyVal(), "browser_")
300
MergeKeyValWithPrefix(kv, m.View.KeyVal(), "view_")
301
return kv
302
}
303
304
// Session holds metadata about the browser session the event originates from
305
type Session struct {
306
ID string `json:"id,omitempty"`
307
Attributes map[string]string `json:"attributes,omitempty"`
308
}
309
310
// KeyVal produces key->value representation of the Session metadata
311
func (s Session) KeyVal() *KeyVal {
312
kv := NewKeyVal()
313
KeyValAdd(kv, "id", s.ID)
314
MergeKeyValWithPrefix(kv, KeyValFromMap(s.Attributes), "attr_")
315
return kv
316
}
317
318
// Page holds metadata about the web page event originates from
319
type Page struct {
320
ID string `json:"id,omitempty"`
321
URL string `json:"url,omitempty"`
322
Attributes map[string]string `json:"attributes,omitempty"`
323
}
324
325
// KeyVal produces key->val representation of Page metadata
326
func (p Page) KeyVal() *KeyVal {
327
kv := NewKeyVal()
328
KeyValAdd(kv, "id", p.ID)
329
KeyValAdd(kv, "url", p.URL)
330
MergeKeyValWithPrefix(kv, KeyValFromMap(p.Attributes), "attr_")
331
return kv
332
}
333
334
// App holds metadata about the application event originates from
335
type App struct {
336
Name string `json:"name,omitempty"`
337
Release string `json:"release,omitempty"`
338
Version string `json:"version,omitempty"`
339
Environment string `json:"environment,omitempty"`
340
}
341
342
// Event holds RUM event data
343
type Event struct {
344
Name string `json:"name"`
345
Domain string `json:"domain,omitempty"`
346
Attributes map[string]string `json:"attributes,omitempty"`
347
Timestamp time.Time `json:"timestamp,omitempty"`
348
Trace TraceContext `json:"trace,omitempty"`
349
}
350
351
// KeyVal produces key -> value representation of Event metadata
352
func (e Event) KeyVal() *KeyVal {
353
kv := NewKeyVal()
354
KeyValAdd(kv, "timestamp", e.Timestamp.String())
355
KeyValAdd(kv, "kind", "event")
356
KeyValAdd(kv, "event_name", e.Name)
357
KeyValAdd(kv, "event_domain", e.Domain)
358
if e.Attributes != nil {
359
MergeKeyValWithPrefix(kv, KeyValFromMap(e.Attributes), "event_data_")
360
}
361
MergeKeyVal(kv, e.Trace.KeyVal())
362
return kv
363
}
364
365
// KeyVal produces key-> value representation of App metadata
366
func (a App) KeyVal() *KeyVal {
367
kv := NewKeyVal()
368
KeyValAdd(kv, "name", a.Name)
369
KeyValAdd(kv, "release", a.Release)
370
KeyValAdd(kv, "version", a.Version)
371
KeyValAdd(kv, "environment", a.Environment)
372
return kv
373
}
374
375
// Browser holds metadata about a client's browser
376
type Browser struct {
377
Name string `json:"name,omitempty"`
378
Version string `json:"version,omitempty"`
379
OS string `json:"os,omitempty"`
380
Mobile bool `json:"mobile,omitempty"`
381
}
382
383
// KeyVal produces key->value representation of the Browser metadata
384
func (b Browser) KeyVal() *KeyVal {
385
kv := NewKeyVal()
386
KeyValAdd(kv, "name", b.Name)
387
KeyValAdd(kv, "version", b.Version)
388
KeyValAdd(kv, "os", b.OS)
389
KeyValAdd(kv, "mobile", fmt.Sprintf("%v", b.Mobile))
390
return kv
391
}
392
393
// View holds metadata about a view
394
type View struct {
395
Name string `json:"name,omitempty"`
396
}
397
398
func (v View) KeyVal() *KeyVal {
399
kv := NewKeyVal()
400
KeyValAdd(kv, "name", v.Name)
401
return kv
402
}
403
404