--- title: "OpenTelemetry logs and traces" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{OpenTelemetry logs and traces} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ## Overview OpenTelemetry sends diagnostic information to a monitoring service. Logs record events such as failed logins, while traces time the operations involved so you can locate a slow token exchange or other provider request. A span is one timed operation within a trace. For an R callback that receives events directly, see [Audit logging](audit-logging.html). shinyOAuth uses the `otel` package to create records. An exporter sends those records to the console or your monitoring service; install `otelsdk` to provide one. ## Exporter configuration Start with console output to check the setup locally. Run this in a fresh R session, before loading shinyOAuth or starting the app: ```{r, eval = FALSE} # install.packages("otelsdk") Sys.setenv( OTEL_TRACES_EXPORTER = "console", OTEL_LOGS_EXPORTER = "console", OTEL_LOG_LEVEL = "debug" ) library(shinyOAuth) ``` Sign in with the [example app](usage.html#minimal-shiny-module-example) and look for login and callback records in the console. If nothing appears, check that logging and tracing are enabled and restart R after changing the exporter. Once that works, follow the [otelsdk exporter setup](https://otelsdk.r-lib.org/reference/collecting.html) and your monitoring service's endpoint and credential instructions. ## Traces and event correlation Filter by instrumentation scope `io.github.lukakoning.shinyOAuth`. Start with `shinyOAuth.login.request` and `shinyOAuth.callback`, then inspect token exchange or profile-fetch spans to find the slow or failing operation. The `shinyoauth.trace_id` attribute connects logs and spans from the same package operation. It is separate from OpenTelemetry's own trace and span IDs. Logs describe the same events as the audit hook. ## Logging and tracing options shinyOAuth enables logging and tracing by default; an exporter collects the records. If your monitoring service only needs one, disable the other: ```{r, eval = FALSE} options( shinyOAuth.otel_logging_enabled = FALSE, shinyOAuth.otel_tracing_enabled = FALSE ) ``` ## Protecting diagnostic data By default, shinyOAuth omits raw tokens, detailed error messages, URL paths, query strings, and scope or claim names. Counts remain available. `shinyOAuth.telemetry_path_scrubber` adds approved route labels, while `shinyOAuth.expose_error_body` separately controls diagnostic text. ### Authorization metadata privacy Permission names can help explain a failed authorization. This option adds those names to the exported records: ```{r, eval = FALSE} options(shinyOAuth.otel_include_authorization_details = TRUE) ``` The added names can identify privileges, tenants or data categories. This option is independent of detailed error-message exposure. ## Asynchronous workers shinyOAuth passes exporter environment variables and trace context to its background workers. It does not replay R setup code, so exporters configured through R require their initialization in each worker. ## Advanced diagnostic fields ### Error attributes and redaction Successful operations normally have status `ok`, and failures have status `error`. For revocation and introspection, missing tokens or unsupported endpoints leave status unset. An inactive token is a successful introspection response (`oauth.active = FALSE`). Thrown errors also record an `exception` event with the error class. Log messages default to the event type. `shinyOAuth.expose_error_body` can add sanitized diagnostic text during debugging. That text can still contain private provider data. URLs omit paths unless an approved path scrubber supplies a route label. Tokens, codes and raw login state stay out of ordinary span attributes. ## Span catalog HTTP spans time network calls; worker spans identify background processing. Useful fields include `oauth.phase`, `server.address` and `http.response.status_code`, alongside provider and session digests. | Name | What it tells you | | --- | --- | | `shinyOAuth.module.init` | Authentication module startup. | | `shinyOAuth.login.request` | Preparing the authorization request and pending login state. | | `shinyOAuth.login.par` | Preparing and validating a pushed authorization request. | | `shinyOAuth.login.par.http` | The HTTP request to the PAR endpoint. | | `shinyOAuth.callback` | Processing the returning login response. | | `shinyOAuth.form_post` | Validating a POST callback before the Shiny session receives it. | | `shinyOAuth.form_post.bridge` | Consuming the one-time POST callback handle. | | `shinyOAuth.callback.validate` | Callback checks; `oauth.phase` identifies the check. | | `shinyOAuth.callback.worker` | Callback processing in an asynchronous worker. | | `shinyOAuth.token.exchange` | Exchanging an authorization code for tokens. | | `shinyOAuth.token.exchange.http` | The HTTP token request for code exchange or refresh. | | `shinyOAuth.token.verify` | Token type, scope and identity checks after a token response. | | `shinyOAuth.userinfo` | Fetching, parsing and validating the user profile. | | `shinyOAuth.userinfo.http` | The HTTP request to the profile endpoint. | | `shinyOAuth.refresh` | Refreshing tokens, including work dispatched to a worker. | | `shinyOAuth.refresh.worker` | The worker-side part of an asynchronous refresh. | | `shinyOAuth.logout` | Local logout and the start of token cleanup. | | `shinyOAuth.session.end.revoke` | Token cleanup requested when a Shiny session ends. | | `shinyOAuth.token.revoke` | A token-revocation operation. | | `shinyOAuth.token.revoke.http` | The HTTP request to the revocation endpoint. | | `shinyOAuth.token.revoke.worker` | The worker-side part of asynchronous revocation. | | `shinyOAuth.token.introspect` | A token-activity check. | | `shinyOAuth.token.introspect.http` | The HTTP request to the introspection endpoint. | | `shinyOAuth.token.introspect.worker` | The worker-side part of asynchronous introspection. |