Files
shiny/R/otel-with.R
2025-10-14 15:40:36 -04:00

78 lines
1.8 KiB
R

otel_bind_choices <- c(
"none",
"session",
"reactive_update",
"reactivity",
"all"
)
# Check if the bind level is sufficient
otel_bind_is_enabled <- function(
impl_level,
# Listen to option and fall back to the env var
opt_bind_level = getOption("shiny.otel.bind", Sys.getenv("SHINY_OTEL_BIND", "all"))
) {
opt_bind_level <- as_otel_bind(opt_bind_level)
which(opt_bind_level == otel_bind_choices) >=
which(impl_level == otel_bind_choices)
}
# Check if tracing is enabled and if the bind level is sufficient
has_otel_bind <- function(bind) {
# Only check pkg author input iff loaded with pkgload
if (IS_SHINY_LOCAL_PKG) {
stopifnot(length(bind) == 1, any(bind == otel_bind_choices))
}
otel_is_tracing_enabled() && otel_bind_is_enabled(bind)
}
# with_otel_bind <- function(
# expr,
# ...,
# # bind = getOption("shiny.otel.bind", "all")
# bind
# ) {
# rlang::check_dots_empty()
# bind <- as_otel_bind(bind)
# withr::with_options(
# list(
# shiny.otel.bind = bind
# ),
# expr
# )
# }
# Run expr with otel binding disabled
with_no_otel_bind <- function(expr) {
withr::with_options(
list(
shiny.otel.bind = "none"
),
expr
)
}
## -- Helpers -----------------------------------------------------
# shiny.otel.bind can be:
# "none"; To do nothing / fully opt-out
# "session" for session/start events
# "reactive_update" (includes "session" features) and reactive_update spans
# "reactivity" (includes "reactive_update" features) and spans for all reactive things
# "all" - Anything that Shiny can do. (Currently equivalent to the "reactivity" level)
as_otel_bind <- function(bind = "all") {
if (!is.character(bind)) {
stop("`bind` must be a character vector.")
}
# Match to bind enum
bind <- match.arg(bind, otel_bind_choices, several.ok = FALSE)
return(bind)
}