forked from aws/aws-lambda-runtime-interface-emulator
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathtracer.go
More file actions
131 lines (109 loc) · 4.39 KB
/
tracer.go
File metadata and controls
131 lines (109 loc) · 4.39 KB
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
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package telemetry
import (
"context"
"encoding/json"
"fmt"
"strings"
"go.amzn.com/lambda/appctx"
"go.amzn.com/lambda/interop"
)
type traceContextKey int
const (
traceIDKey traceContextKey = iota
documentIDKey
)
type Tracer interface {
Configure(invoke *interop.Invoke)
CaptureInvokeSegment(ctx context.Context, criticalFunction func(context.Context) error) error
CaptureInitSubsegment(ctx context.Context, criticalFunction func(context.Context) error) error
CaptureInvokeSubsegment(ctx context.Context, criticalFunction func(context.Context) error) error
CaptureOverheadSubsegment(ctx context.Context, criticalFunction func(context.Context) error) error
RecordInitStartTime()
RecordInitEndTime()
SendInitSubsegmentWithRecordedTimesOnce(ctx context.Context)
MarkError(ctx context.Context)
AttachErrorCause(ctx context.Context, errorCause json.RawMessage)
WithErrorCause(ctx context.Context, appCtx appctx.ApplicationContext, criticalFunction func(ctx context.Context) error) func(ctx context.Context) error
WithError(ctx context.Context, appCtx appctx.ApplicationContext, criticalFunction func(ctx context.Context) error) func(ctx context.Context) error
TracingHeaderParser() func(context.Context, *interop.Invoke) string
}
type NoOpTracer struct{}
func (t *NoOpTracer) Configure(invoke *interop.Invoke) {}
func (t *NoOpTracer) CaptureInvokeSegment(ctx context.Context, criticalFunction func(context.Context) error) error {
criticalFunction(ctx)
return nil
}
func (t *NoOpTracer) CaptureInitSubsegment(ctx context.Context, criticalFunction func(context.Context) error) error {
criticalFunction(ctx)
return nil
}
func (t *NoOpTracer) CaptureInvokeSubsegment(ctx context.Context, criticalFunction func(context.Context) error) error {
criticalFunction(ctx)
return nil
}
func (t *NoOpTracer) CaptureOverheadSubsegment(ctx context.Context, criticalFunction func(context.Context) error) error {
criticalFunction(ctx)
return nil
}
func (t *NoOpTracer) RecordInitStartTime() {}
func (t *NoOpTracer) RecordInitEndTime() {}
func (t *NoOpTracer) SendInitSubsegmentWithRecordedTimesOnce(ctx context.Context) {}
func (t *NoOpTracer) MarkError(ctx context.Context) {}
func (t *NoOpTracer) AttachErrorCause(ctx context.Context, errorCause json.RawMessage) {}
func (t *NoOpTracer) WithErrorCause(ctx context.Context, appCtx appctx.ApplicationContext, criticalFunction func(ctx context.Context) error) func(ctx context.Context) error {
return criticalFunction
}
func (t *NoOpTracer) WithError(ctx context.Context, appCtx appctx.ApplicationContext, criticalFunction func(ctx context.Context) error) func(ctx context.Context) error {
return criticalFunction
}
func (t *NoOpTracer) TracingHeaderParser() func(context.Context, *interop.Invoke) string {
return GetCustomerTracingHeader
}
func NewNoOpTracer() *NoOpTracer {
return &NoOpTracer{}
}
// NewTraceContext returns new derived context with trace config set for testing
func NewTraceContext(ctx context.Context, root string, parent string) context.Context {
ctxWithRoot := context.WithValue(ctx, traceIDKey, root)
return context.WithValue(ctxWithRoot, documentIDKey, parent)
}
// GetCustomerTracingHeader extracts the trace config from trace context and constructs header
func GetCustomerTracingHeader(ctx context.Context, invoke *interop.Invoke) string {
var root, parent string
var ok bool
if root, ok = ctx.Value(traceIDKey).(string); !ok {
return invoke.TraceID
}
if parent, ok = ctx.Value(documentIDKey).(string); !ok {
return invoke.TraceID
}
return fmt.Sprintf("Root=%s;Parent=%s;Sampled=1", root, parent)
}
// ParseTraceID helps client to get TraceID, ParentID, Sampled information from a full trace
func ParseTraceID(fullTraceID string) (rootID, parentID, sample string) {
traceIDInfo := strings.Split(fullTraceID, ";")
for i := 0; i < len(traceIDInfo); i++ {
if len(traceIDInfo[i]) == 0 {
continue
} else {
var key string
var value string
keyValuePair := strings.Split(traceIDInfo[i], "=")
if len(keyValuePair) == 2 {
key = keyValuePair[0]
value = keyValuePair[1]
}
switch key {
case "Root":
rootID = value
case "Parent":
parentID = value
case "Sampled":
sample = value
}
}
}
return
}