Skip to content

Conversation

schloerke
Copy link
Collaborator

@schloerke schloerke commented Aug 4, 2025

Related: #4258

Fixes #4265 - bindOtel(x), withOtel(expr, ..., bind = "all")
Fixes #4268 - options(shiny.otel.bind = "all") (and "none")

Possible future support:

Fixes #4268 - options(shiny.otel.bind = c("reactiveVal", "reacitveValues", "reactiveExpr", "observe", "output")
Fixes #4266 - options(shiny.otel.bind = "reactive-update")
Fixes #4282 - options(shiny.otel.binnd = "session")

Introduces bindOtel() and withOtelShiny() to enable OpenTelemetry tracing for reactive objects and observers. Adds options shiny.otel.bindall and shiny.otel.graphlocked for automatic binding and graph locking. Updates reactiveVal, reactiveValues, reactive, and observe to support automatic OpenTelemetry binding. Documentation and NAMESPACE updated accordingly.
Included r-lib/otelsdk in the Remotes field to enable installation from GitHub. This supports dependencies required for development or testing.
@schloerke schloerke changed the title feat(otel): Add bindOtel() feat(otel): Add bindOtel() support Aug 5, 2025
@schloerke
Copy link
Collaborator Author

Current test script:

devtools::load_all(); barret() |> runApp(port = 8080)

After clicking a few times... logfire gives this output:

Screenshot 2025-08-05 at 5 01 25 PM
  • Should maybe disable logging of init state for input values.
  • Need to fix reactiveExpr label
  • Should probably integrate better labels from known reactlog label info?

@jcheng5
Copy link
Member

jcheng5 commented Sep 3, 2025

After live discussion with @schloerke:

  1. If the right env vars are present, that's enough to turn on otel logging/tracing with sensible defaults
  2. Don't export bindOtel methods; users should use withr::with_options instead
  3. Two options: 1) traces for session/reactive update, 2) traces for all reactive objects
  4. Set a flag in the impl of Observable/Observer to enable/disable tracing (similar to reactiveVal). Will reduce complexity
  5. Set otel handoff promise domain at withReactiveDomain by wrapping the body of runApp

@schloerke
Copy link
Collaborator Author

5. Set otel handoff promise domain at withReactiveDomain by wrapping the body of runApp

Using rstudio/promises#176, ✅ within Shiny. Works great! 🥳🥳

R/otel.R Outdated
if (!is.null(tracer)) {
return(tracer)
}
if (testthat::is_testing()) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must also check if testthat is installed. No need to use a perfect / fast reproducible call here as it is only possibly repeated during testing.

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.

feat: Add Otel span for session duration feat: Bind all reactivity to Otel feat: Add Otel span for reactive graph update feat: Add bindOtel(x)
2 participants