forked from open-telemetry/opentelemetry-operator
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpython.go
More file actions
140 lines (121 loc) · 4.89 KB
/
python.go
File metadata and controls
140 lines (121 loc) · 4.89 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
132
133
134
135
136
137
138
139
140
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package instrumentation
import (
"fmt"
corev1 "k8s.io/api/core/v1"
"github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1"
)
const (
envPythonPath = "PYTHONPATH"
envOtelTracesExporter = "OTEL_TRACES_EXPORTER"
envOtelMetricsExporter = "OTEL_METRICS_EXPORTER"
envOtelLogsExporter = "OTEL_LOGS_EXPORTER"
envOtelExporterOTLPProtocol = "OTEL_EXPORTER_OTLP_PROTOCOL"
glibcLinuxAutoInstrumentationSrc = "/autoinstrumentation/."
muslLinuxAutoInstrumentationSrc = "/autoinstrumentation-musl/."
pythonPathPrefix = "/otel-auto-instrumentation-python/opentelemetry/instrumentation/auto_instrumentation"
pythonPathSuffix = "/otel-auto-instrumentation-python"
pythonInstrMountPath = "/otel-auto-instrumentation-python"
pythonVolumeName = volumeName + "-python"
pythonInitContainerName = initContainerName + "-python"
glibcLinux = "glibc"
muslLinux = "musl"
)
func pythonPlatformSrc(platform string) (string, error) {
// Validate platform
switch platform {
case "", glibcLinux:
return glibcLinuxAutoInstrumentationSrc, nil
case muslLinux:
return muslLinuxAutoInstrumentationSrc, nil
default:
return "", fmt.Errorf("provided instrumentation.opentelemetry.io/otel-python-platform annotation value '%s' is not supported", platform)
}
}
func injectPythonSDKToContainer(pythonSpec v1alpha1.Python, container *corev1.Container, platform string) error {
volume := instrVolume(pythonSpec.VolumeClaimTemplate, pythonVolumeName, pythonSpec.VolumeSizeLimit)
err := validateContainerEnv(container.Env, envPythonPath)
if err != nil {
return err
}
_, err = pythonPlatformSrc(platform)
if err != nil {
return err
}
// inject Python instrumentation spec env vars.
container.Env = appendIfNotSet(container.Env, pythonSpec.Env...)
idx := getIndexOfEnv(container.Env, envPythonPath)
if idx == -1 {
container.Env = append(container.Env, corev1.EnvVar{
Name: envPythonPath,
Value: fmt.Sprintf("%s:%s", pythonPathPrefix, pythonPathSuffix),
})
} else if idx > -1 {
container.Env[idx].Value = fmt.Sprintf("%s:%s:%s", pythonPathPrefix, container.Env[idx].Value, pythonPathSuffix)
}
container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
Name: volume.Name,
MountPath: pythonInstrMountPath,
})
return nil
}
func injectPythonSDKToPod(pythonSpec v1alpha1.Python, pod corev1.Pod, firstContainerName, platform string, instSpec v1alpha1.InstrumentationSpec) corev1.Pod {
volume := instrVolume(pythonSpec.VolumeClaimTemplate, pythonVolumeName, pythonSpec.VolumeSizeLimit)
// This has been validated already
autoInstrumentationSrc, _ := pythonPlatformSrc(platform)
// We just inject Volumes and init containers for the first processed container.
if isInitContainerMissing(pod, pythonInitContainerName) {
pod.Spec.Volumes = append(pod.Spec.Volumes, volume)
initContainer := corev1.Container{
Name: pythonInitContainerName,
Image: pythonSpec.Image,
Command: []string{"cp", "-r", autoInstrumentationSrc, pythonInstrMountPath},
Resources: pythonSpec.Resources,
VolumeMounts: []corev1.VolumeMount{{
Name: volume.Name,
MountPath: pythonInstrMountPath,
}},
ImagePullPolicy: instSpec.ImagePullPolicy,
}
pod.Spec.InitContainers = insertInitContainer(&pod, initContainer, firstContainerName)
}
return pod
}
// injectPythonSDK injects Python instrumentation into the specified containers.
// Containers must point into the provided pod and be ordered with init containers first.
func injectPythonSDK(pythonSpec v1alpha1.Python, pod *corev1.Pod, containers []*corev1.Container, platform string, instSpec v1alpha1.InstrumentationSpec) error {
for _, container := range containers {
if err := injectPythonSDKToContainer(pythonSpec, container, platform); err != nil {
return err
}
}
if len(containers) > 0 {
*pod = injectPythonSDKToPod(pythonSpec, *pod, containers[0].Name, platform, instSpec)
}
return nil
}
func getDefaultPythonEnvVars() []corev1.EnvVar {
return []corev1.EnvVar{
// Set OTEL_EXPORTER_OTLP_PROTOCOL to http/protobuf if not set by user because it is what our autoinstrumentation supports.
{
Name: envOtelExporterOTLPProtocol,
Value: "http/protobuf",
},
// Set OTEL_TRACES_EXPORTER to otlp exporter if not set by user because it is what our autoinstrumentation supports.
{
Name: envOtelTracesExporter,
Value: "otlp",
},
// Set OTEL_METRICS_EXPORTER to otlp exporter if not set by user because it is what our autoinstrumentation supports.
{
Name: envOtelMetricsExporter,
Value: "otlp",
},
// Set OTEL_LOGS_EXPORTER to otlp exporter if not set by user because it is what our autoinstrumentation supports.
{
Name: envOtelLogsExporter,
Value: "otlp",
},
}
}