-
Notifications
You must be signed in to change notification settings - Fork 460
/
Copy pathinstrumentation.go
170 lines (141 loc) · 5.06 KB
/
instrumentation.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
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2024 Datadog, Inc.
package instrumentation
import (
"context"
"math"
"github.com/DataDog/dd-trace-go/v2/ddtrace/tracer"
"github.com/DataDog/dd-trace-go/v2/instrumentation/internal/namingschema"
"github.com/DataDog/dd-trace-go/v2/internal"
"github.com/DataDog/dd-trace-go/v2/internal/appsec"
"github.com/DataDog/dd-trace-go/v2/internal/globalconfig"
"github.com/DataDog/dd-trace-go/v2/internal/normalizer"
"github.com/DataDog/dd-trace-go/v2/internal/telemetry"
)
// OperationContext holds metadata about an instrumentation operation.
type OperationContext map[string]string
// Load attempts to load the requested package instrumentation. It panics if the package has not been registered.
func Load(pkg Package) *Instrumentation {
info, ok := packages[pkg]
if !ok {
panic("instrumentation package: " + pkg + " was not found. If this is an external package, you must" +
"call instrumentation.Register first")
}
telemetry.LoadIntegration(string(pkg))
tracer.MarkIntegrationImported(info.TracedPackage)
return &Instrumentation{
pkg: pkg,
logger: logger{},
info: info,
}
}
func Register(name string, info PackageInfo) error {
info.external = true
return nil
}
// Instrumentation represents instrumentation for a package.
type Instrumentation struct {
pkg Package
logger Logger
info PackageInfo
}
// ServiceName returns the default service name to be set for the given instrumentation component.
func (i *Instrumentation) ServiceName(component Component, opCtx OperationContext) string {
cfg := namingschema.GetConfig()
n, ok := i.info.naming[component]
if !ok {
return cfg.DDService
}
useDDService := cfg.NamingSchemaVersion == namingschema.VersionV1 || cfg.RemoveFakeServiceNames || n.useDDServiceV0 || n.buildServiceNameV0 == nil
if useDDService && cfg.DDService != "" {
return cfg.DDService
}
return n.buildServiceNameV0(opCtx)
}
// OperationName returns the operation name to be set for the given instrumentation component.
func (i *Instrumentation) OperationName(component Component, opCtx OperationContext) string {
op, ok := i.info.naming[component]
if !ok {
return ""
}
switch namingschema.GetVersion() {
case namingschema.VersionV1:
return op.buildOpNameV1(opCtx)
default:
return op.buildOpNameV0(opCtx)
}
}
func (i *Instrumentation) Logger() Logger {
return i.logger
}
func (i *Instrumentation) AnalyticsRate(defaultGlobal bool) float64 {
if internal.BoolEnv("DD_TRACE_"+i.info.EnvVarPrefix+"_ANALYTICS_ENABLED", false) {
return 1.0
}
if defaultGlobal {
return i.GlobalAnalyticsRate()
}
return math.NaN()
}
func (i *Instrumentation) GlobalAnalyticsRate() float64 {
return globalconfig.AnalyticsRate()
}
func (i *Instrumentation) AppSecEnabled() bool {
return appsec.Enabled()
}
func (i *Instrumentation) AppSecRASPEnabled() bool {
return appsec.RASPEnabled()
}
func (i *Instrumentation) DataStreamsEnabled() bool {
return internal.BoolEnv("DD_DATA_STREAMS_ENABLED", false)
}
// TracerInitialized returns whether the global tracer has been initialized or not.
func (i *Instrumentation) TracerInitialized() bool {
return internal.TracerInitialized()
}
// WithExecutionTraced marks ctx as being associated with an execution trace
// task. It is assumed that ctx already contains a trace task. The caller is
// responsible for ending the task.
//
// This is intended for a specific case where the database/sql contrib package
// only creates spans *after* an operation, in case the operation was
// unavailable, and thus execution trace tasks tied to the span only capture the
// very end. This function enables creating a task *before* creating a span, and
// communicating to the APM tracer that it does not need to create a task. In
// general, APM instrumentation should prefer creating tasks around the
// operation rather than after the fact, if possible.
func (i *Instrumentation) WithExecutionTraced(ctx context.Context) context.Context {
return internal.WithExecutionTraced(ctx)
}
type StatsdClient = internal.StatsdClient
func (i *Instrumentation) StatsdClient(extraTags []string) (StatsdClient, error) {
addr := globalconfig.DogstatsdAddr()
tags := globalconfig.StatsTags()
for _, tag := range extraTags {
tags = append(tags, tag)
}
return internal.NewStatsdClient(addr, tags)
}
type HeaderTags interface {
Iter(f func(header string, tag string))
}
func NewHeaderTags(headers []string) HeaderTags {
headerTagsMap := normalizer.HeaderTagSlice(headers)
return internal.NewLockMap(headerTagsMap)
}
func (i *Instrumentation) HTTPHeadersAsTags() HeaderTags {
return globalconfig.HeaderTagMap()
}
func (i *Instrumentation) ActiveSpanKey() any {
return internal.ActiveSpanKey
}
func (i *Instrumentation) Disabled() bool {
// TODO
// either:
// internal.BoolEnv("DD_TRACE_"+i.info.EnvVarPrefix+"_INTEGRATION_DISABLED", false)
// or:
// check if internal.SliceEnv("DD_TRACE_DISABLED_INTEGRATIONS") contains i.pkg
return false
}