diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index b54bac97..b7191e35 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -53,7 +53,9 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: any::rcmdcheck + extra-packages: | + any::rcmdcheck + otelsdk=?ignore-before-r=4.3.0 needs: check - uses: r-lib/actions/check-r-package@v2 diff --git a/DESCRIPTION b/DESCRIPTION index f39d9894..0ead3522 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -38,6 +38,8 @@ Suggests: covr, httpuv, knitr, + otel, + otelsdk, rmarkdown, sodium, spelling, @@ -49,4 +51,4 @@ Config/testthat/edition: 3 Encoding: UTF-8 Language: en-US Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.2.9000 +RoxygenNote: 7.3.3 diff --git a/R/otel.R b/R/otel.R new file mode 100644 index 00000000..aeedebca --- /dev/null +++ b/R/otel.R @@ -0,0 +1,53 @@ +otel_tracer_name <- "org.r-lib.gargle" + +otel_cache_tracer <- NULL +otel_local_active_span <- NULL +otel_span_add_events <- NULL + +local({ + otel_is_tracing <- FALSE + otel_tracer <- NULL + + otel_cache_tracer <<- function() { + requireNamespace("otel", quietly = TRUE) || return() + otel_tracer <<- otel::get_tracer(otel_tracer_name) + otel_is_tracing <<- tracer_enabled(otel_tracer) + } + + otel_local_active_span <<- function( + name, + attributes = list(), + links = NULL, + options = NULL, + return_ctx = FALSE, + scope = parent.frame() + ) { + otel_is_tracing || return() + otel::start_local_active_span( + name, + attributes = otel::as_attributes(attributes), + links = links, + options = options, + tracer = otel_tracer, + activation_scope = scope + ) + } + + otel_span_add_events <<- function(text) { + otel_is_tracing || return() + spn <- otel::get_active_span() + lapply(cli::ansi_strip(text), spn$add_event) + } +}) + +tracer_enabled <- function(tracer) { + .subset2(tracer, "is_enabled")() +} + +with_otel_record <- function(expr) { + on.exit(otel_cache_tracer()) + otelsdk::with_otel_record({ + otel_cache_tracer() + expr + }) +} diff --git a/R/token_fetch.R b/R/token_fetch.R index 5be5579b..21e59b84 100644 --- a/R/token_fetch.R +++ b/R/token_fetch.R @@ -21,6 +21,7 @@ #' token_fetch(scopes = "https://www.googleapis.com/auth/userinfo.email") #' } token_fetch <- function(scopes = NULL, ...) { + gargle_span <- otel_local_active_span("token fetch") gargle_debug("trying {.fun token_fetch}") for (f in gargle_env$cred_funs) { token <- NULL diff --git a/R/utils-ui.R b/R/utils-ui.R index 0a06cb08..715e2ea9 100644 --- a/R/utils-ui.R +++ b/R/utils-ui.R @@ -91,6 +91,9 @@ with_gargle_verbosity <- function(level, code) { } gargle_debug <- function(text, .envir = caller_env()) { + otel_span_add_events( + cli::cli_fmt(cli::cli_bullets(text, .envir = .envir)) + ) if (gargle_verbosity() == "debug") { cli::cli_div(theme = gargle_theme()) cli::cli_bullets(text, .envir = .envir) diff --git a/R/zzz.R b/R/zzz.R index 0675ba14..d6bd64ba 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,5 +1,6 @@ .onLoad <- function(lib, pkg) { # nocov start + otel_cache_tracer() cred_funs_set_default() invisible() } # nocov end