Skip to content

feat(otel): Zero-code auto-instrumentation via opentelemetry-distro - #2349

Merged
schloerke merged 12 commits into
mainfrom
schloerke/otel-instrument-docs-2274
Jul 9, 2026
Merged

feat(otel): Zero-code auto-instrumentation via opentelemetry-distro#2349
schloerke merged 12 commits into
mainfrom
schloerke/otel-instrument-docs-2274

Conversation

@schloerke

Copy link
Copy Markdown
Collaborator

Closes #2274

Summary

Makes opentelemetry-instrument shiny run app.py the standard, documented way to enable OpenTelemetry, per #2274:

  • pyproject.toml: the shiny[otel] extra now includes opentelemetry-distro[otlp], so the opentelemetry-instrument wrapper and the OTLP exporters ship with it and the bare command works without extra flags. The explicit opentelemetry-sdk>=1.24.0 floor is kept (sanitized-stack-trace requirement from ci: Test oldest supported Python and dependency versions #2335). Note: opentelemetry-distro pins the SDK to a matching minor version, so combining shiny[otel] with other SDK-pinning packages (e.g. logfire) may require matching versions.
  • shiny/otel/__init__.py docstring (source of the /py/api/core/OpenTelemetry.html reference page): auto-instrumentation is now the standard setup throughout — Quick Start, best practices, and all backend recipes (Jaeger, Honeycomb, Datadog, New Relic, console) use OTEL_* env vars + the wrapper with unmodified apps. In-code trace.set_tracer_provider() setup is documented as discouraged, kept only as a guarded fallback for SDK-managed setups (logfire) and platforms without launch-command control. Troubleshooting covers the Overriding of current TracerProvider is not allowed conflict.
  • examples/open-telemetry/: the example app now contains no OpenTelemetry setup code at all; the README and app docstring show the wrapper-based launch.

No runtime code changes were needed: Shiny already resolves the global tracer provider lazily at span-creation time (shiny/otel/_core.py), so the provider installed by opentelemetry-instrument is picked up automatically.

Companion PRs: posit-dev/py-shiny-site#380 (user-facing docs) and posit-dev/shiny-vscode#112 (VS Code/Positron run integration, posit-dev/shiny-vscode#111).

Verification

pip install -e ".[otel]"
opentelemetry-instrument --traces_exporter console --logs_exporter console --metrics_exporter none shiny run examples/open-telemetry/app.py

Interacting with the app prints Shiny's spans (session_start, reactive_update, session_end) and value-update log records (e.g. Set reactive.value normal_counter) to the console, with no provider-override warnings. Verified with and without --reload, and that in-code set_tracer_provider() under the wrapper reproduces the documented override warning. Otel unit tests pass (tests/pytest/test_otel_*).

schloerke added 4 commits July 8, 2026 17:03
…distro (#2274)

The shiny[otel] extra now includes opentelemetry-distro[otlp], so
`opentelemetry-instrument shiny run app.py` works out of the box. Document
the zero-code path as the recommended setup and warn that manual
trace.set_tracer_provider() is ignored (with a warning) when running under
opentelemetry-instrument.
…Tel configuration

The example unconditionally called trace.set_tracer_provider() and
set_logger_provider() at import time. Providers can only be installed once
per process, so under opentelemetry-instrument (or after logfire.configure())
those calls were ignored with an 'Overriding of current TracerProvider is not
allowed' warning and the in-code console setup silently had no effect. The
app now detects an already-configured provider and skips its in-code setup,
and the docs note that OpenTelemetry must be configured in exactly one place.
…age in-code SDK config

Within-app provider setup (trace.set_tracer_provider) is now documented as
discouraged: it couples the app to an observability setup and conflicts with
external instrumentation. All docs, best practices, backend recipes, and the
open-telemetry example now use 'opentelemetry-instrument shiny run app.py'
with standard OTEL_* environment variables. The example app contains no OTel
setup code at all. In-code setup remains documented as a guarded fallback for
platforms without launch-command control and for SDKs like logfire that
manage OpenTelemetry themselves.
schloerke added 3 commits July 8, 2026 17:51
Drops the lazy-initialization implementation detail, keeps a compact note on
why in-code provider setup was removed from the docs (silently ignored when a
provider is already installed), and points the entry at PR #2349.
The example app now displays the active SHINY_OTEL_COLLECT level in its UI,
the module docstring and README document the precedence rule, and a comment
at the otel.collect block explains why collect-stamped outputs still produce
spans when the global level is lowered: suppress/collect are absolute
per-object settings captured at creation time, taking precedence over the
global level, while infrastructure spans follow only the environment
variable.
@schloerke
schloerke merged commit 0a8f604 into main Jul 9, 2026
174 checks passed
@schloerke
schloerke deleted the schloerke/otel-instrument-docs-2274 branch July 9, 2026 15:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

shiny[otel] should include opentelemetry-distro for auto-instrumentation support

1 participant