Repository navigation
feat(telemetry): OTLP spans for workspace-builder runs - #865
Open
stewartshea wants to merge 1 commit into
Open
stewartshea wants to merge 1 commit into
stewartshea wants to merge 1 commit into
Conversation
Add optional, off-by-default OTLP telemetry wired to the standard OTEL_* environment variables. One span wraps each workspace-builder run (execute_run) with sensor-style attributes (workspace, location, components, status, slx/warning counts); OTLP log export is attached only when OTEL_LOGS_EXPORTER=otlp. Telemetry is best-effort: with no OTEL_* variables set, nothing from the OpenTelemetry SDK is imported, no exporter is built, and the run path is unchanged. Exporters are built on the startup path and any failure logs a warning and continues. This pairs with the opentelemetry-collector subchart the self-hosted chart deploys when runner.enabled is true (see deploy/scripts/registry-sync).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
RunWhen's self-hosted chart already deploys an optional OTLP collector + OpenObserve when
runner.enabledis true (seedeploy/scripts/registry-sync/sample_values.yamlandupdated_values.yaml). The receive side exists; the producer side did not — nothing in the runner emitted OTLP, so the collector had nothing to receive.This PR adds optional, off-by-default OTLP telemetry to RunWhen Local and wraps each run in a single span with sensor-style attributes, so a user can see what ran and how long it took.
The task described
runwhen-localas "the local runner that executes RunWhen SLXs / codebundle tasks." In this repository,src/is the RunWhen Local workspace builder — it indexes resources and renders workspace/SLX definitions; it does not execute codebundle tasks. That is the separaterunnerimage referenced byrunner.enabledin the chart (imagerunwhen/runner), which does not live in this repo.Because that producer code is not present here, and because the ask says to keep the change minimal and to do the producer work rather than the chart/collector work, I instrumented the closest producer-side "run" this repo owns: the workspace-builder run (
workspace_builder.run_handler.execute_run, the single entry point behindPOST /run/). This is the narrowest sensible instrumentation available in this repository.If the intent was to instrument the external runner image, this PR is not that — it is the producer-side change that fits this repo. I deliberately did not touch the chart's collector configuration (the receive side already exists).
Off-by-default contract
With no
OTEL_*variables set:telemetryimports nothing fromopentelemetry(covered by a test that runsimport telemetryin a subprocess and assertsopentelemetryis not insys.modules);Env vars (standard names only)
OTEL_TRACES_EXPORTER=otlpOTEL_LOGS_EXPORTER=otlpOTEL_EXPORTER_OTLP_ENDPOINT_TRACES_/_LOGS_variants honored by the exporters)OTEL_EXPORTER_OTLP_PROTOCOLgrpc(default) orhttp/protobufOTEL_SERVICE_NAMErunwhen-local)OTEL_TRACES_SAMPLER/OTEL_TRACES_SAMPLER_ARGOTEL_PROPAGATORSWhat is instrumented
src/telemetry.py(new) — lazy, best-effort OTLP setup (traces and, only if requested, logs).init_telemetry()is called on the startup path (workspace_builder/startup.py:bootstrap()); any failure logs a warning and continues without telemetry. Exporter construction sits behind_make_span_exporter()/_make_log_exporter()seams so tests can patch it with in-memory stubs (no network).src/workspace_builder/run_handler.py—execute_runnow wraps the run in one span namedrunwhen.workspace_builder.runwith attributes:runwhen.workspace_name,runwhen.location_id,runwhen.location_namerunwhen.components,runwhen.namespacesrunwhen.status(ok/error),runwhen.slx_count,runwhen.warnings_countOK/ERROR; exceptions recorded viarecord_exception.The original body is unchanged apart from being renamed to
_execute_run_pipeline(request_data, run_span); behaviour with telemetry off is byte-identical. This is one span per run — name/attributes are sensor-style, and duration is the span duration.Dependencies
opentelemetry-api,opentelemetry-sdk,opentelemetry-exporter-otlp-proto-grpc,opentelemetry-exporter-otlp-proto-httpadded tosrc/pyproject.toml;src/poetry.lockregenerated with the Poetry version pinned insrc/Dockerfile(2.5.1).poetry check --lockpasses.How I tested it
src/test_telemetry.py(12 tests), hermetic (exporters patched with an in-memory exporter / failing stub, no network):get_tracer()isNone, span handle inert, no crash;import telemetryin a fresh subprocess does not importopentelemetry;execute_runwrapper is transparent when disabled and recordsok/errorspans otherwise.src/: 506 passed, 4 subtests passed, 0 failed (python -m pytest -q).How to use it with the existing collector
Set the standard env vars on the container (e.g. via the chart's
runwhenLocalenv /extraEnv):Deliberately left out
deploy/scripts/registry-sync/*values.yaml) — the receive side already exists.runnerimage (not in this repo) — see the assumption above.OTEL_PROPAGATORShandling — only relevant for cross-process propagation, and this process is the root of each run.