OpenTelemetry

OpenTelemetry

OpenTelemetry is a vendor-neutral standard for collecting telemetry data from running services. Posit Workbench can export structured log events and trace spans over OpenTelemetry Protocol (OTLP) HTTP to any compatible backend.

The OpenTelemetry export sits alongside the existing Prometheus metrics endpoint. Both can be enabled at once, since they cover different signals and answer different questions.

Prerequisites

Using OpenTelemetry to export data requires the Monitoring feature, which is included in the Basic, Enhanced, and Advanced license tiers. Without an active license at one of these tiers, the server accepts the configuration options below but emits no signals.

You also need an OTLP/HTTP-compatible receiver. The OpenTelemetry Collector is one option. Many observability platforms also accept OTLP/HTTP directly.

Configuration

Configure OpenTelemetry export in rserver.conf. The primary option otel-enabled gates all signals. Per-signal options (otel-logs-enabled, otel-traces-enabled) decide which signal types are active.

To send both logs and traces to a single OTLP/HTTP receiver, set:

# /etc/rstudio/rserver.conf
otel-enabled=1
otel-endpoint=http://collector.example.org:4318
otel-logs-enabled=1
otel-traces-enabled=1

Workbench appends /v1/logs and /v1/traces to otel-endpoint automatically. Restart Workbench with rstudio-server restart after changing these options.

To send logs and traces to different receivers, set otel-logs-endpoint and otel-traces-endpoint explicitly. Pass headers (for example, authentication tokens) with otel-logs-headers and otel-traces-headers, comma-separated key=value pairs. If otel-traces-headers is empty, Workbench reuses otel-logs-headers for traces.

Below is the full set of OpenTelemetry configuration options:

Config Option Description Possible Values Default Value
otel-enabled Primary switch for OpenTelemetry export. When 0, no OTLP signals are emitted regardless of per-signal options. 0 or 1 0
otel-endpoint Base OTLP/HTTP endpoint URL. /v1/logs and /v1/traces are appended automatically. Takes precedence over otel-logs-endpoint for logs. A valid URL, for example http://collector:4318 empty
otel-logs-enabled Enable export of OpenTelemetry log events. Requires otel-enabled=1. 0 or 1 0
otel-logs-endpoint OTLP/HTTP endpoint for log events. Required when otel-logs-enabled=1 and otel-endpoint is not set. A valid URL empty
otel-logs-headers Comma-separated key=value headers for OTLP log export requests. For example Authorization=Bearer xyz,X-Tenant=acme empty
otel-logs-batch-interval-ms Interval in milliseconds between log batch exports. Integer ≥ 500 5000
otel-traces-enabled Enable trace export for session launches. Requires otel-enabled=1. 0 or 1 0
otel-traces-endpoint OTLP/HTTP endpoint for traces. Takes precedence over otel-endpoint for traces when set. A valid URL empty
otel-traces-headers Comma-separated key=value headers for OTLP trace export requests. Falls back to otel-logs-headers when empty. For example Authorization=Bearer xyz empty
otel-traces-batch-interval-ms Interval in milliseconds between trace batch exports. Clamped to [500, 60000]. Integer in [500, 60000] 5000

See the rserver.conf reference for the canonical descriptions of each option.

Disabling OpenTelemetry

Set otel-enabled=0 in rserver.conf and restart Workbench. The per-signal options do not need to change; the primary option suppresses all export.

Signal catalog

Workbench exports two signal types:

  • Log events for sign-in, session lifecycle, session state transitions, and browser-side IDE launch performance.
  • Trace spans that wrap each session launch with one child span per launch phase.

This section lists every signal Workbench emits, including event names, attributes, types, and allowed values. Operators building dashboards, alerts, or queries against the OTLP stream should treat this section as the contract.

Conventions

Attribute names follow the OpenTelemetry semantic conventions where one applies. Workbench-specific attributes use the session.*, browser.*, and transition_type namespaces.

In every table:

  • Required attributes are present on every emission of the event.
  • Optional attributes are emitted only when a value is available (for example, session.r_version is emitted only for R sessions, and only after the version has been resolved).
  • Type uses OTLP attribute types: string, int64, or bool.

Every log event also carries an event.name attribute equal to the event name in the heading. The event.name row is omitted from each table for brevity.

Log events

workbench.user.login

Emitted on each successful sign-in.

Severity: INFO

Attribute Type Required Description
user.id string yes The user’s Globally Unique Identifier (GUID), resolved server-side.

workbench.session

Emitted when a session starts, suspends, completes normally, fails, or is terminated.

Severity: INFO

Attribute Type Required Description
session.id string yes Workbench session identifier.
user.id string yes The user’s GUID.
session.type string yes Normalized IDE name. Allowed values: RStudio, Positron, JupyterLab, VS Code.
session.status string yes Lifecycle status. Allowed values: Started, Suspended, Terminated, Failed, Completed.
session.r_version string no R version, when applicable. Emitted only when non-empty.
session.project string no Initial project path. Emitted only when non-empty.
session.cluster string no Job Launcher cluster name in load-balanced deployments. Emitted only when non-empty.
session.exit_code int64 no Process exit code, on terminal events.
session.exit_reason string no Human-readable exit classification. Allowed values: NormalExit, Killed, Crashed, MemoryLimitExceeded, TooManyOpenFiles, NotEnoughMemory, Unknown.
session.startup_duration_ms int64 no Time from launch request to running, on Started events.

workbench.session.transition

Emitted on every session state change. Use this event to reconstruct per-session timelines without enabling traces.

Severity: INFO

Attribute Type Required Description
session.id string yes Workbench session identifier.
session.status string yes The state the session has transitioned to.
session.previous_status string no The state the session transitioned from. Emitted only when non-empty.
transition_type string yes Classification of the transition. Allowed values: milestone, internal.
user.id string no The user’s GUID. Emitted only when resolvable from the username.

milestone transitions correspond to user-visible state changes (for example, running, suspended, finished); internal transitions cover intermediate states such as starting or resuming.

browser.session.launch

Emitted by the IDE-launch performance beacon in the user’s browser. Each session launch produces multiple events, one per phase. Heartbeat events fire periodically while the IDE is open.

Severity: DEBUG for heartbeat, INFO for all other phases.

Attribute Type Required Description
session.id string yes Workbench session identifier.
user.id string no The user’s GUID, resolved server-side from the authenticated username. Never trusted from the client payload.
browser.ide string yes IDE type, emitted as a lowercase identifier rather than a display name. Allowed values: rstudio, jupyterlab, positron, vscode.
browser.phase string yes Launch phase or heartbeat. Allowed values: fcp, load, app_init, ready, heartbeat, pagehide.
browser.nav_id string yes Browser-generated ID for one IDE navigation. Use to correlate the phase events from a single launch.
browser.last_phase_reached string no The most recent phase the browser observed before this event was sent.
browser.click_to_phase_ms int64 no Milliseconds from the user’s click on the launch link to this phase. Present when click-time is known.
browser.nav_start_to_phase_ms int64 no Milliseconds from navigationStart to this phase. Always derivable in modern browsers.
browser.launch_t0_ms int64 no Browser-side T0 timestamp (ms since epoch).
browser.timings.<key> int64 | string no Detailed PerformanceTiming-style breakdown attached to the first beacon of a launch only. The <key> suffix matches the underlying timing field.

The launch milestones, in chronological order, are fcp (first contentful paint), load, app_init, and ready. heartbeat fires periodically while the IDE is active. pagehide fires when the user navigates away or closes the tab.

Trace spans

session.launch

Wraps a single session launch from request to running (or to terminal failure). The root span carries identity and routing attributes; one child span is open at a time, named after the current launch phase.

Span hierarchy:

session.launch                          (root)
├── session.launch.launching            (child, first phase)
├── session.launch.starting             (child, next phase)
├── session.launch.running              (child, terminal on success)
└── session.launch.<other-state>        (one child per intermediate state)

Child spans close as the session transitions out of the matching state. The root span closes when the session reaches running or fails.

Root span attributes:

Attribute Type Required Description
session.id string yes Workbench session identifier.
user.id string yes The user’s GUID.
session.type string yes Normalized IDE name (see workbench.session for allowed values).
session.cluster string yes Job Launcher cluster name. Empty string for non-load-balanced deployments.

Child span names take the form session.launch.<state> where <state> is the activity state. Common values include launching, starting, running, suspending, and resuming. Child spans inherit the trace context from the root and carry no additional attributes; phase identity is encoded by the span name.

A failed launch closes the root span with status ERROR. A relaunch attempt arriving during an active launch closes the previous root span with status ERROR and message "overwritten", then opens a new one.

Back to top