-
Notifications
You must be signed in to change notification settings - Fork 28
feat(plane-enterprise): native OpenTelemetry APM support (v2.5.1) #241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,6 +43,10 @@ stringData: | |
| {{- if include "plane.s3CAEnabled" . }} | ||
| AWS_CA_BUNDLE: "/etc/ssl/certs/ca-certificates.crt" | ||
| {{- end }} | ||
|
|
||
| {{- if and .Values.observability.otel.enabled .Values.observability.otel.headers }} | ||
| OTEL_EXPORTER_OTLP_HEADERS: {{ .Values.observability.otel.headers | quote }} | ||
| {{- end }} | ||
| {{- end }} | ||
| --- | ||
|
|
||
|
|
@@ -104,3 +108,25 @@ data: | |
| {{- else}} | ||
| CORS_ALLOWED_ORIGINS: "http://{{ .Values.license.licenseDomain }},https://{{ .Values.license.licenseDomain }}" | ||
| {{- end }} | ||
|
|
||
| {{- /* OpenTelemetry APM for the Django backend (api, worker, beat-worker, | ||
| automation-consumer, outbox-poller, migrator). No-op in the app unless | ||
| OTEL_ENABLED=1 and an endpoint is set. Auth headers, if any, live in the | ||
| app-secrets Secret above. See docs/otel-api-observability in plane-ee. */}} | ||
| {{- if .Values.observability.otel.enabled }} | ||
| OTEL_ENABLED: "1" | ||
| OTEL_SERVICE_NAME: {{ .Values.observability.otel.serviceName | default "plane-api" | quote }} | ||
| {{- if .Values.observability.otel.endpoint }} | ||
| OTEL_EXPORTER_OTLP_ENDPOINT: {{ .Values.observability.otel.endpoint | quote }} | ||
| {{- else if .Values.observability.otel.collector.enabled }} | ||
| OTEL_EXPORTER_OTLP_ENDPOINT: "http://{{ .Release.Name }}-otel-collector.{{ .Release.Namespace }}.svc.cluster.local:4317" | ||
| {{- else }} | ||
| OTEL_EXPORTER_OTLP_ENDPOINT: "" | ||
| {{- end }} | ||
| OTEL_EXPORTER_OTLP_PROTOCOL: {{ .Values.observability.otel.protocol | default "grpc" | quote }} | ||
|
Comment on lines
+121
to
+126
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Auto-target endpoint hardcodes gRPC port 4317, ignoring When 🐛 Proposed fix: pick port by protocol {{- else if .Values.observability.otel.collector.enabled }}
- OTEL_EXPORTER_OTLP_ENDPOINT: "http://{{ .Release.Name }}-otel-collector.{{ .Release.Namespace }}.svc.cluster.local:4317"
+ {{- if eq (.Values.observability.otel.protocol | default "grpc") "grpc" }}
+ OTEL_EXPORTER_OTLP_ENDPOINT: "http://{{ .Release.Name }}-otel-collector.{{ .Release.Namespace }}.svc.cluster.local:4317"
+ {{- else }}
+ OTEL_EXPORTER_OTLP_ENDPOINT: "http://{{ .Release.Name }}-otel-collector.{{ .Release.Namespace }}.svc.cluster.local:4318"
+ {{- end }}
{{- else }}🤖 Prompt for AI Agents |
||
| OTEL_TRACES_SAMPLER: {{ .Values.observability.otel.tracesSampler | default "parentbased_traceidratio" | quote }} | ||
| OTEL_TRACES_SAMPLER_ARG: {{ .Values.observability.otel.tracesSamplerArg | default "0.1" | quote }} | ||
| {{- if .Values.observability.otel.resourceAttributes }} | ||
| OTEL_RESOURCE_ATTRIBUTES: {{ .Values.observability.otel.resourceAttributes | quote }} | ||
| {{- end }} | ||
| {{- end }} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| {{- /* | ||
| Bundled OpenTelemetry Collector. Rendered only when OTEL is enabled AND the | ||
| bundled collector is requested. Self-hosters pointing at an external collector | ||
| (Datadog Agent, Grafana Cloud, an existing cluster collector) leave | ||
| observability.otel.collector.enabled=false and these resources are omitted. | ||
|
|
||
| When enabled with an empty observability.otel.endpoint, the backend auto-targets | ||
| this collector's in-cluster Service (see config-secrets/app-env.yaml). | ||
| */}} | ||
| {{- if and .Values.observability.otel.enabled .Values.observability.otel.collector.enabled }} | ||
| apiVersion: v1 | ||
| kind: ConfigMap | ||
| metadata: | ||
| namespace: {{ .Release.Namespace }} | ||
| name: {{ .Release.Name }}-otel-collector-config | ||
| labels: | ||
| app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-otel-collector | ||
| data: | ||
| config.yaml: | | ||
| {{- if .Values.observability.otel.collector.config }} | ||
| {{ .Values.observability.otel.collector.config | indent 4 }} | ||
| {{- else }} | ||
| # Default pipeline: receive OTLP, log via `debug`. Override the whole config | ||
| # with observability.otel.collector.config to export to a real backend. | ||
| receivers: | ||
| otlp: | ||
| protocols: | ||
| grpc: | ||
| endpoint: 0.0.0.0:4317 | ||
| http: | ||
| endpoint: 0.0.0.0:4318 | ||
| processors: | ||
| batch: | ||
| timeout: 10s | ||
| send_batch_size: 1024 | ||
| exporters: | ||
| debug: | ||
| verbosity: detailed | ||
| service: | ||
| pipelines: | ||
| traces: | ||
| receivers: [otlp] | ||
| processors: [batch] | ||
| exporters: [debug] | ||
| metrics: | ||
| receivers: [otlp] | ||
| processors: [batch] | ||
| exporters: [debug] | ||
| {{- end }} | ||
|
|
||
| --- | ||
|
|
||
| apiVersion: v1 | ||
| kind: Service | ||
| metadata: | ||
| namespace: {{ .Release.Namespace }} | ||
| name: {{ .Release.Name }}-otel-collector | ||
| labels: | ||
| app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-otel-collector | ||
| spec: | ||
| type: ClusterIP | ||
| ports: | ||
| - name: otlp-grpc | ||
| port: 4317 | ||
| protocol: TCP | ||
| targetPort: 4317 | ||
| - name: otlp-http | ||
| port: 4318 | ||
| protocol: TCP | ||
| targetPort: 4318 | ||
| selector: | ||
| app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-otel-collector | ||
|
|
||
| --- | ||
|
|
||
| apiVersion: apps/v1 | ||
| kind: Deployment | ||
| metadata: | ||
| namespace: {{ .Release.Namespace }} | ||
| name: {{ .Release.Name }}-otel-collector | ||
| {{- include "plane.labelsAndAnnotations" .Values.observability.otel.collector }} | ||
| spec: | ||
| replicas: {{ .Values.observability.otel.collector.replicas | default 1 }} | ||
| selector: | ||
| matchLabels: | ||
| app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-otel-collector | ||
| template: | ||
| metadata: | ||
| namespace: {{ .Release.Namespace }} | ||
| labels: | ||
| app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-otel-collector | ||
| annotations: | ||
| timestamp: {{ now | quote }} | ||
| spec: | ||
| {{- include "plane.podScheduling" .Values.observability.otel.collector }} | ||
| containers: | ||
| - name: {{ .Release.Name }}-otel-collector | ||
| imagePullPolicy: {{ .Values.observability.otel.collector.pullPolicy | default "IfNotPresent" }} | ||
| image: {{ .Values.observability.otel.collector.image | default "otel/opentelemetry-collector-contrib:0.115.1" }} | ||
| args: ["--config=/etc/otel/config.yaml"] | ||
| ports: | ||
| - name: otlp-grpc | ||
| containerPort: 4317 | ||
| - name: otlp-http | ||
| containerPort: 4318 | ||
| resources: | ||
| requests: | ||
| memory: {{ .Values.observability.otel.collector.memoryRequest | default "128Mi" | quote }} | ||
| cpu: {{ .Values.observability.otel.collector.cpuRequest | default "100m" | quote }} | ||
| limits: | ||
| memory: {{ .Values.observability.otel.collector.memoryLimit | default "512Mi" | quote }} | ||
| cpu: {{ .Values.observability.otel.collector.cpuLimit | default "500m" | quote }} | ||
| volumeMounts: | ||
| - name: config | ||
| mountPath: /etc/otel | ||
| volumes: | ||
| - name: config | ||
| configMap: | ||
| name: {{ .Release.Name }}-otel-collector-config | ||
| {{- end }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoded
cluster.localbreaks custom cluster domains.Elsewhere in this same template the cluster domain is parameterized (e.g. Line 36 and Line 97 use
{{ .Values.env.default_cluster_domain | default "cluster.local" }}). The auto-target endpoint here pinscluster.local, so clusters with a custom DNS domain won't resolve the collector Service.♻️ Align with the existing pattern
🤖 Prompt for AI Agents