Skip to content

Commit 4e34a26

Browse files
committed
Cache otel tracing status and tracer on package load
1 parent 0af3f57 commit 4e34a26

File tree

10 files changed

+43
-23
lines changed

10 files changed

+43
-23
lines changed

DESCRIPTION

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,3 @@ Config/testthat/start-first: resp-stream, req-perform
5757
Encoding: UTF-8
5858
Roxygen: list(markdown = TRUE)
5959
RoxygenNote: 7.3.2
60-
Remotes:
61-
r-lib/otelsdk

R/otel.R

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
otel_tracer_name <- "org.r-lib.httr2"
2+
otel_tracer <- NULL
3+
otel_is_tracing <- FALSE
4+
15
# Attaches an Open Telemetry span that abides by the semantic conventions for
26
# HTTP clients to the request, including the associated W3C trace context
37
# headers.
@@ -6,11 +10,11 @@
610
req_with_span <- function(
711
req,
812
resend_count = 0,
9-
tracer = get_tracer(),
13+
tracer = otel_tracer,
1014
activation_scope = parent.frame(),
1115
activate = TRUE
1216
) {
13-
if (!is_tracing(tracer)) {
17+
if (!tracer_enabled(tracer)) {
1418
cli::cli_abort(
1519
"Cannot create request span; tracing is not enabled",
1620
.internal = TRUE
@@ -93,22 +97,24 @@ req_record_span_status <- function(req, resp = NULL) {
9397
}
9498
}
9599

96-
get_tracer <- function() {
97-
if (!is.null(the$tracer)) {
98-
return(the$tracer)
99-
}
100-
if (!is_installed("otel")) {
101-
return(NULL)
102-
}
103-
if (is_testing()) {
104-
# Don't cache the tracer in unit tests. It interferes with tracer provider
105-
# injection in otelsdk::with_otel_record().
106-
return(otel::get_tracer("httr2"))
107-
}
108-
the$tracer <- otel::get_tracer("httr2")
109-
the$tracer
100+
otel_cache_tracer <- function() {
101+
requireNamespace("otel", quietly = TRUE) || return()
102+
otel_tracer <<- otel::get_tracer(otel_tracer_name)
103+
otel_is_tracing <<- tracer_enabled(otel_tracer)
104+
}
105+
106+
tracer_enabled <- function(tracer) {
107+
.subset2(tracer, "is_enabled")()
110108
}
111109

112-
is_tracing <- function(tracer = get_tracer()) {
113-
!is.null(tracer) && tracer$is_enabled()
110+
otel_refresh_tracer <- function(pkgname) {
111+
requireNamespace("otel", quietly = TRUE) || return()
112+
ns <- getNamespace(pkgname)
113+
do.call(unlockBinding, list("otel_is_tracing", ns)) # do.call for R CMD Check
114+
do.call(unlockBinding, list("otel_tracer", ns))
115+
otel_tracer <- otel::get_tracer()
116+
ns[["otel_is_tracing"]] <- tracer_enabled(otel_tracer)
117+
ns[["otel_tracer"]] <- otel_tracer
118+
lockBinding("otel_is_tracing", ns)
119+
lockBinding("otel_tracer", ns)
114120
}

R/pooled-request.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ PooledRequest <- R6Class(
6666

6767
private$req_prep <- req_prepare(req)
6868
private$handle <- req_handle(private$req_prep)
69-
if (is_tracing()) {
69+
if (otel_is_tracing) {
7070
# Note: we need to do this before we call handle_preflight() so that
7171
# request signing works correctly with the added headers.
7272
#

R/req-perform-connection.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ req_perform_connection1 <- function(
151151
the$last_request <- req
152152
the$last_response <- NULL
153153
signal(class = "httr2_perform_connection")
154-
if (is_tracing()) {
154+
if (otel_is_tracing) {
155155
# Note: we need to do this before we call handle_preflight() so that request
156156
# signing works correctly with the added headers.
157157
req_prep <- req_with_span(req_prep, resend_count = resend_count)

R/req-perform.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ req_perform1 <- function(
190190
the$last_request <- req
191191
the$last_response <- NULL
192192
signal(class = "httr2_perform")
193-
if (is_tracing()) {
193+
if (otel_is_tracing) {
194194
# Note: we need to do this before we call handle_preflight() so that request
195195
# signing works correctly with the added headers.
196196
req_prep <- req_with_span(req_prep, resend_count = resend_count)

R/zzz.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.onLoad <- function(...) {
2+
otel_cache_tracer()
23
cache_disk_prune()
34
}

tests/testthat/test-req-perform-connection.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ test_that("tracing works as expected", {
117117
skip_if_not_installed("otelsdk")
118118

119119
spans <- otelsdk::with_otel_record({
120+
otel_refresh_tracer("httr2")
120121
# A request with no URL (which shouldn't create a span).
121122
try(req_perform_connection(request("")), silent = TRUE)
122123

@@ -152,6 +153,9 @@ test_that("tracing works as expected", {
152153
try(silent = TRUE)
153154
})[["traces"]]
154155

156+
# reset tracer after tests
157+
otel_refresh_tracer("httr2")
158+
155159
expect_length(spans, 7L)
156160

157161
# Validate the span for regular requests.

tests/testthat/test-req-perform-parallel.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ test_that("tracing works as expected", {
341341
skip_if_not_installed("otelsdk")
342342

343343
spans <- otelsdk::with_otel_record({
344+
otel_refresh_tracer("httr2")
344345
# A request with no URL (which shouldn't create a span).
345346
try(req_perform_parallel(list(request(""))), silent = TRUE)
346347

@@ -373,6 +374,9 @@ test_that("tracing works as expected", {
373374
)
374375
})[["traces"]]
375376

377+
# reset tracer after tests
378+
otel_refresh_tracer("httr2")
379+
376380
expect_length(spans, 6L)
377381

378382
# And for requests with HTTP errors.

tests/testthat/test-req-perform.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ test_that("tracing works as expected", {
226226
skip_if_not_installed("otelsdk")
227227

228228
spans <- otelsdk::with_otel_record({
229+
otel_refresh_tracer("httr2")
229230
# A request with no URL (which shouldn't create a span).
230231
try(req_perform(request("")), silent = TRUE)
231232

@@ -260,6 +261,9 @@ test_that("tracing works as expected", {
260261
try(silent = TRUE)
261262
})[["traces"]]
262263

264+
# reset tracer after tests
265+
otel_refresh_tracer("httr2")
266+
263267
expect_length(spans, 7L)
264268

265269
# Validate the span for regular requests.

tests/testthat/test-req-promise.R

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ test_that("tracing works as expected", {
176176
skip_if_not_installed("otelsdk")
177177

178178
spans <- otelsdk::with_otel_record({
179+
otel_refresh_tracer("httr2")
179180
# A request with no URL (which shouldn't create a span).
180181
try(req_perform_promise(request("")), silent = TRUE)
181182

@@ -211,6 +212,8 @@ test_that("tracing works as expected", {
211212
"traceparent" %in% names(resp_body_json(resp)[["headers"]])
212213
)
213214
})[["traces"]]
215+
# reset tracer after tests
216+
otel_refresh_tracer("httr2")
214217

215218
expect_length(spans, 5L)
216219

0 commit comments

Comments
 (0)