Skip to content

Commit a9d5902

Browse files
committed
OpenTelemetry instrumentation concept
1 parent 560d658 commit a9d5902

File tree

5 files changed

+82
-0
lines changed

5 files changed

+82
-0
lines changed

DESCRIPTION

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ Suggests:
4242
digest (>= 0.6.33),
4343
gh,
4444
knitr,
45+
otel,
46+
otelsdk,
4547
rmarkdown,
4648
rstudioapi,
4749
S7,

R/otel.R

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
otel_tracer_name <- "org.r-lib.testthat"
2+
otel_is_tracing <- FALSE
3+
otel_tracer <- NULL
4+
5+
# generic otel helpers ---------------------------------------------------------
6+
7+
# nocov start
8+
9+
otel_cache_tracer <- function() {
10+
requireNamespace("otel", quietly = TRUE) || return()
11+
otel_tracer <<- otel::get_tracer(otel_tracer_name)
12+
otel_is_tracing <<- tracer_enabled(otel_tracer)
13+
}
14+
15+
# nocov end
16+
17+
tracer_enabled <- function(tracer) {
18+
.subset2(tracer, "is_enabled")()
19+
}
20+
21+
otel_refresh_tracer <- function() {
22+
requireNamespace("otel", quietly = TRUE) || return()
23+
tracer <- otel::get_tracer()
24+
modify_binding(
25+
topenv(),
26+
list(otel_tracer = tracer, otel_is_tracing = tracer_enabled(tracer))
27+
)
28+
}
29+
30+
modify_binding <- function(env, lst) {
31+
lapply(names(lst), unlockBinding, env)
32+
list2env(lst, envir = env)
33+
lapply(names(lst), lockBinding, env)
34+
}
35+
36+
otel_local_active_span <- function(
37+
name,
38+
label,
39+
attributes = list(),
40+
links = NULL,
41+
options = NULL,
42+
scope = parent.frame()
43+
) {
44+
otel_is_tracing || return()
45+
spn <- otel::start_local_active_span(
46+
sprintf("%s %s", name, label),
47+
attributes = otel::as_attributes(attributes),
48+
links = links,
49+
options = options,
50+
tracer = otel_tracer,
51+
activation_scope = scope
52+
)
53+
}

R/test-that.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#' }
3636
test_that <- function(desc, code) {
3737
local_description_push(desc)
38+
otel_local_active_span("test that", desc)
3839

3940
code <- substitute(code)
4041
test_code(code, parent.frame())

R/testthat-package.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,11 @@ the$in_check_reporter <- FALSE
3030
#' @importFrom lifecycle deprecated
3131
## usethis namespace: end
3232
NULL
33+
34+
# nocov start
35+
36+
.onLoad <- function(libname, pkgname) {
37+
otel_cache_tracer()
38+
}
39+
40+
# nocov end

tests/testthat/test-otel.R

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
test_that("otel instrumentation works", {
2+
skip_if_not_installed("otelsdk")
3+
4+
record <- otelsdk::with_otel_record({
5+
otel_refresh_tracer()
6+
test_that("otel testing", {
7+
expect_equal(1, 1)
8+
expect_error(stop("otel error"))
9+
})
10+
})
11+
# reset tracer after tests
12+
otel_refresh_tracer()
13+
14+
traces <- record$traces
15+
expect_length(traces, 1L)
16+
expect_equal(traces[[1L]]$name, "test that otel testing")
17+
expect_equal(traces[[1L]]$instrumentation_scope$name , "org.r-lib.testthat")
18+
})

0 commit comments

Comments
 (0)