Expand description
§OpenTelemetry-Appender-Tracing
This crate provides a bridge between the tracing crate and OpenTelemetry logs.
It converts tracing events into OpenTelemetry LogRecords, allowing applications using tracing to seamlessly integrate
with OpenTelemetry logging backends.
§Background
Unlike traces and metrics, OpenTelemetry does not provide a dedicated logging API for end-users. Instead, it recommends using
existing logging libraries and bridging them to OpenTelemetry logs. This crate serves as such a bridge for tracing users.
§Features
- Converts
tracingevents into OpenTelemetryLogRecords - Integrates as a
Layerfromtracing-subscriber, allowing to be used alongside othertracinglayers, such asfmt - Automatically attaches OpenTelemetry trace context (
TraceId,SpanId,TraceFlags) to logs - Automatically associates OpenTelemetry Resource to logs
- Supports exporting logs to OpenTelemetry-compatible backends (OTLP, stdout, etc.)
§Getting Started
§1. Install Dependencies
Add the following dependencies to your Cargo.toml:
[dependencies]
tracing = ">=0.1.40"
tracing-core = { version = ">=0.1.33" }
tracing-subscriber = { version = "0.3", features = ["registry", "std", "fmt"] }
opentelemetry = { version = "0.31", features = ["logs"] }
opentelemetry-sdk = { version = "0.31", features = ["logs"] }
opentelemetry-appender-tracing = { version = "0.31.1" }§2. Set Up the OpenTelemetry Logger Provider
Before integrating with tracing, create an OpenTelemetry SdkLoggerProvider:
use opentelemetry_sdk::logs::SdkLoggerProvider;
use opentelemetry_stdout::LogExporter;
let exporter = LogExporter::default();
let provider = SdkLoggerProvider::builder()
.with_simple_exporter(exporter)
.build();In this example, SdkLoggerProvider is configured to use the opentelemetry_stdout crate to export logs to stdout. You can replace it with any other OpenTelemetry-compatible exporter.
Any additional OpenTelemetry configuration (e.g., setting up a resource, additional processors etc.) can be done at this stage.
§3. Create the OpenTelemetry-Tracing Bridge
Create OpenTelemetryTracingBridge layer using the SdkLoggerProvider created in the previous step.
let otel_layer = OpenTelemetryTracingBridge::new(&provider);§4. Register the tracing Subscriber
Since this crate provides a Layer for tracing, you can register it with the tracing subscriber as shown below.
use tracing_subscriber::prelude::*;
tracing_subscriber::registry()
.with(otel_layer)
.with(tracing_subscriber::fmt::layer()) // In this example, `fmt` layer is also added.
.init();§5. Log Events Using tracing
use tracing::error;
error!(name: "my-event-name1", target: "my-system", event_id = 10, user_name = "otel", user_email = "otel@opentelemetry.io", message = "This is an example message");§Mapping details
Since OpenTelemetry and tracing have their own data models, this bridge performs the following mappings:
tracing | OpenTelemetry | Notes |
|---|---|---|
| name of the event | EventName | OpenTelemetry defines logs with name as Events, so every tracing Event is actually an OTel Event |
| target | target | Groups logs from the same module/crate. At recording time, target is stored in a top-level field. But exporters treat this information as OpenTelemetry InstrumentationScope |
| level of the event | Severity, SeverityText | |
| Fields | Attributes | Converted into OpenTelemetry log attributes. Field with “message” as key is specially treated and stored as LogRecord::Body |
| Message | Body | The body/message of the log. This is done only if body was not already populated from “message” field above |
§Data Type Mapping
The data types supported by tracing and OpenTelemetry are different and the following conversions are applied:
tracing Type | OpenTelemetry AnyValue Type |
|---|---|
i64 | Int |
f32, f64 | Double |
u64,u128 ,i128 | Int (if convertible to i64 without loss) else String |
&str | String |
bool | Bool |
&[u8] | Bytes |
&dyn Debug | String (via Debug formatting) |
&dyn Error | String (via Debug formatting). This is stored into an attribute with key “exception.message”, following OTel conventions |
In future, additional types may be supported.
Note: This crate does not support
tracingSpans. One may usetracing-opentelemetryto converttracingspans into OpenTelemetry spans. This is a third-party crate that is not maintained by the OpenTelemetry project.tracing-opentelemetry:
- Converts
tracingspans into OpenTelemetry spans- Converts
tracingevents into OpenTelemetrySpanEventsrather than logs Depending on the outcome of the discussion, the OpenTelemetry project may provide direct support to maptracingspans to OpenTelemetry in the future.
§Feature Flags
spec_unstable_logs_enabled: TODO
experimental_metadata_attributes: TODO
experimental_use_tracing_span_context: TODO
§Limitations
- There is no support for
Valuablecrate. 2819
§Stability Guarantees
// TODO
§Further Reading
- OpenTelemetry Rust: opentelemetry-rust
- Tracing: tracing
- OpenTelemetry Logs: OpenTelemetry Logging Specification