feat(plane-enterprise): add OpenTelemetry traces/logs/metrics support#248
feat(plane-enterprise): add OpenTelemetry traces/logs/metrics support#248pratapalakshmi wants to merge 3 commits into
Conversation
Adds native, opt-in OTel wiring to the chart (mirrors the kustomize
otel-observability component used in commercial-deployments). Off by default.
- observability.otel.* values block: enabled, endpoint, protocol, headers,
environment, resourceAttributes, debugConsole, sampler, samplerArg, and a
frontend.{enabled,endpoint,headers} block for browser tracing.
- Shared <release>-otel-vars ConfigMap (templates/config-secrets/otel.yaml),
rendered only when observability.otel.enabled.
- Wires the 11 backend workloads (api, worker, beat-worker,
automation-consumer, outbox-poller, silo, live, space, pi-api, pi-beat,
pi-worker) via envFrom + an inline per-workload OTEL_SERVICE_NAME so each
reports its own service.name. web/admin are intentionally not wired — their
only OTel is browser tracing, served to them by the API via the frontend.* keys.
- Helpers: plane.otel.enabled / plane.otel.envFrom / plane.otel.serviceEnv.
Defaults encode two hard-won lessons:
- sampler defaults to always_on: parentbased_* defers to an upstream
traceparent's sampled flag (dropping browser-initiated POST traces even at
ratio 1.0); always_on captures everything for test/debug. Switch to
parentbased_traceidratio for prod.
- environment maps to deployment.environment.name (current semconv key) so the
tag matches the other services for cross-service filtering.
- frontend.headers defaults to a non-empty value to force the browser OTLP
exporter onto XHR (sendBeacon fails CORS against a wildcard ACAO).
Verified with `helm template` in both enabled and disabled states: all
workloads wire correctly when enabled, and no OTel env / null env blocks render
when disabled.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 46 minutes and 34 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughAdds OpenTelemetry support to the ChangesOpenTelemetry Integration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@charts/plane-enterprise/templates/config-secrets/otel.yaml`:
- Around line 15-17: The OTEL_EXPORTER_OTLP_HEADERS field containing
authentication credentials is currently stored in a ConfigMap, which is not
encrypted and poses a security risk. Remove the OTEL_EXPORTER_OTLP_HEADERS
variable from the otel.yaml ConfigMap template and instead create a separate
Secret resource to store sensitive OTEL header values. Update the pod
specification to mount these values from the Secret using secretRef instead of
configMapRef, ensuring the ingestion credentials are properly protected.
- Around line 33-37: The FRONTEND_OTEL_ENABLED configuration variable is
currently being set to "1" based only on the frontend.enabled flag, but
according to the values contract it should only be enabled when both
frontend.enabled is true AND frontend.endpoint is set. Update the conditional
check at line 33 to verify both conditions are met by combining the check for
observability.otel.frontend.enabled with a check that
observability.otel.frontend.endpoint is also defined and not empty before
setting FRONTEND_OTEL_ENABLED to "1".
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 8ae0949c-79b7-4363-a629-2000d2232b49
📒 Files selected for processing (14)
charts/plane-enterprise/templates/_helpers.tplcharts/plane-enterprise/templates/config-secrets/otel.yamlcharts/plane-enterprise/templates/workloads/api.deployment.yamlcharts/plane-enterprise/templates/workloads/automation-consumer.deployment.yamlcharts/plane-enterprise/templates/workloads/beat-worker.deployment.yamlcharts/plane-enterprise/templates/workloads/live.deployment.yamlcharts/plane-enterprise/templates/workloads/outbox-poller.deployment.yamlcharts/plane-enterprise/templates/workloads/pi-api.deployment.yamlcharts/plane-enterprise/templates/workloads/pi-beat.deployment.yamlcharts/plane-enterprise/templates/workloads/pi-worker.deployment.yamlcharts/plane-enterprise/templates/workloads/silo.deployment.yamlcharts/plane-enterprise/templates/workloads/space.deployment.yamlcharts/plane-enterprise/templates/workloads/worker.deployment.yamlcharts/plane-enterprise/values.yaml
| {{- with .Values.observability.otel.headers }} | ||
| OTEL_EXPORTER_OTLP_HEADERS: {{ . | quote }} | ||
| {{- end }} |
There was a problem hiding this comment.
Move OTLP auth headers out of ConfigMap
OTEL_EXPORTER_OTLP_HEADERS can carry ingestion credentials, but this template stores it in a ConfigMap. That weakens secret handling and broadens accidental exposure. Use a Secret for sensitive OTEL header values and mount via secretRef instead.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@charts/plane-enterprise/templates/config-secrets/otel.yaml` around lines 15 -
17, The OTEL_EXPORTER_OTLP_HEADERS field containing authentication credentials
is currently stored in a ConfigMap, which is not encrypted and poses a security
risk. Remove the OTEL_EXPORTER_OTLP_HEADERS variable from the otel.yaml
ConfigMap template and instead create a separate Secret resource to store
sensitive OTEL header values. Update the pod specification to mount these values
from the Secret using secretRef instead of configMapRef, ensuring the ingestion
credentials are properly protected.
| {{- if .Values.observability.otel.frontend.enabled }} | ||
| FRONTEND_OTEL_ENABLED: "1" | ||
| {{- with .Values.observability.otel.frontend.endpoint }} | ||
| FRONTEND_OTLP_ENDPOINT: {{ . | quote }} | ||
| {{- end }} |
There was a problem hiding this comment.
Frontend OTEL enablement is missing endpoint gating
Line 33 enables frontend OTEL based only on frontend.enabled, but the values contract says it should turn on only when both enabled and endpoint are set. This can emit FRONTEND_OTEL_ENABLED without a usable endpoint and produce broken browser exporter config.
Suggested template fix
- {{- if .Values.observability.otel.frontend.enabled }}
+ {{- if and .Values.observability.otel.frontend.enabled .Values.observability.otel.frontend.endpoint }}
FRONTEND_OTEL_ENABLED: "1"
{{- with .Values.observability.otel.frontend.endpoint }}
FRONTEND_OTLP_ENDPOINT: {{ . | quote }}
{{- end }}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {{- if .Values.observability.otel.frontend.enabled }} | |
| FRONTEND_OTEL_ENABLED: "1" | |
| {{- with .Values.observability.otel.frontend.endpoint }} | |
| FRONTEND_OTLP_ENDPOINT: {{ . | quote }} | |
| {{- end }} | |
| {{- if and .Values.observability.otel.frontend.enabled .Values.observability.otel.frontend.endpoint }} | |
| FRONTEND_OTEL_ENABLED: "1" | |
| {{- with .Values.observability.otel.frontend.endpoint }} | |
| FRONTEND_OTLP_ENDPOINT: {{ . | quote }} | |
| {{- end }} |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@charts/plane-enterprise/templates/config-secrets/otel.yaml` around lines 33 -
37, The FRONTEND_OTEL_ENABLED configuration variable is currently being set to
"1" based only on the frontend.enabled flag, but according to the values
contract it should only be enabled when both frontend.enabled is true AND
frontend.endpoint is set. Update the conditional check at line 33 to verify both
conditions are met by combining the check for
observability.otel.frontend.enabled with a check that
observability.otel.frontend.endpoint is also defined and not empty before
setting FRONTEND_OTEL_ENABLED to "1".
…s.yml Surfaces the new observability.otel.* values as a Rancher catalog "OpenTelemetry" question group: an enable toggle with subquestions for endpoint, protocol, headers, environment, resource attributes, sampler (+ ratio), debug console, and the browser tracing block. Defaults mirror values.yaml. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…y support Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What
Adds native, opt-in OpenTelemetry support to the
plane-enterprisechart, mirroring theotel-observabilitykustomize component already used incommercial-deployments. Off by default — no behavior change unlessobservability.otel.enabled=true.Changes
values.yaml— newobservability.otelblock:enabled,endpoint,protocol(grpc),headers,environment,resourceAttributes,debugConsole,sampler,samplerArgfrontend.{enabled,endpoint,headers}for browser tracing (web/admin/space), served to browsers by the API.templates/config-secrets/otel.yaml— shared<release>-otel-varsConfigMap, rendered only when enabled.templates/_helpers.tpl—plane.otel.enabled/plane.otel.envFrom/plane.otel.serviceEnv.api, worker, beat-worker, automation-consumer, outbox-poller, silo, live, space, pi-api, pi-beat, pi-worker): the shared ConfigMap viaenvFrom+ an inline per-workloadOTEL_SERVICE_NAMEso each reports its ownservice.name.web/adminare intentionally not wired (browser-only tracing, configured from the API's instance config).Why these defaults
Three lessons from validating tracing on a live cluster:
sampler: always_on—parentbased_*defers to an incomingtraceparent's sampled flag and ignores the ratio, so browser-initiated POST/user-action traces get dropped even at1.0(you see only root GET traffic).always_oncaptures everything for test/debug. Useparentbased_traceidratiofor prod.environment→deployment.environment.name— the current semconv key, so the API's environment tag matches the node/pi/browser services for cross-service filtering (the legacydeployment.environmentdoes not).frontend.headersnon-empty — forces the browser OTLP exporter onto XHR;sendBeaconfails CORS against a wildcardAccess-Control-Allow-Origin.Testing
helm templatein both states:otel-varsconfigMapRef+ correct distinctOTEL_SERVICE_NAME; ConfigMap rendersdeployment.environment.name=…andOTEL_TRACES_SAMPLER: always_on.env/envFromblocks; all rendered manifests parse as valid Kubernetes YAML.🤖 Generated with Claude Code
Summary by CodeRabbit