Skip to main content

Overview

The opentelemetry-appender-tracing crate bridges the tracing crate to OpenTelemetry logs. It provides a tracing::Layer implementation that converts tracing events into OpenTelemetry LogRecords, enabling seamless integration for async Rust applications.
Unlike traces and metrics, OpenTelemetry does not provide a dedicated logging API for end-users. Instead, it recommends using existing logging libraries like tracing and bridging them to OpenTelemetry logs.

Key Features

  • Integrates as a tracing-subscriber Layer alongside other layers (e.g., fmt)
  • Automatically attaches OpenTelemetry trace context (TraceId, SpanId, TraceFlags) to logs
  • Automatically associates OpenTelemetry Resource to logs
  • Supports exporting to OpenTelemetry-compatible backends (OTLP, stdout, etc.)
  • Optional: Capture span attributes in log records (experimental)

Installation

Add the following to your Cargo.toml:

Quick Start

1

Create a LoggerProvider

Set up the OpenTelemetry logger provider:
2

Create the tracing bridge layer

Create the OpenTelemetryTracingBridge layer:
3

Register with tracing subscriber

Combine with other layers and initialize:
4

Emit logs

Use standard tracing macros:
5

Shutdown

Flush remaining logs:

Complete Example

Field Mapping

The appender maps tracing::Event to OpenTelemetry LogRecord:

Basic Mapping

If a field named message exists, it’s used as the log body. Otherwise, the body is empty or derived from the event’s formatted message.

Severity Mapping

Type Mapping

tracing field types are mapped to AnyValue:

Event Names and Targets

Event Names

You can specify event names explicitly:
Without an explicit name, tracing generates a default based on source location:

Targets

Targets group logs by module:
Without an explicit target, tracing uses the module path:
Exporters use the target field as the OpenTelemetry instrumentation scope name.

Trace Context Integration

When logs are emitted within an active OpenTelemetry span, the trace context is automatically attached:
The log record will contain:
  • trace_id: Links the log to the distributed trace
  • span_id: Links the log to the specific span
  • trace_flags: Sampling information

Span Attributes (Experimental)

With the experimental_span_attributes feature, span fields are automatically captured as log attributes:
Example:
The log attributes will include:
  • user_id = 12345 (from span)
  • session_id = "abc-def" (from span)
  • status = 500 (from event)

Nested Spans

Attributes from all parent spans are collected:

Attribute Allowlist

Filter which span attributes to capture:
Only user_id and request_id span attributes will be captured in logs.

Filtering

By Level

Use tracing-subscriber filters:

Suppress Telemetry Loops

When using OTLP exporters, prevent telemetry-induced-telemetry loops:
This filters out logs from HTTP/gRPC libraries used by the OTLP exporter.
This filtering also drops logs from these libraries when used outside of the exporter. For more targeted filtering, see the open issue.

Advanced Configuration

Builder Pattern

Use the builder for advanced configuration:

Multiple Layers

Combine with other tracing layers:

Batch Processing

For production, use batch processing:

Custom Log Processor

You can create custom processors to enrich logs:
Use it in the provider:

Comparison with log Appender

Choose the tracing appender if:
  • You’re building async applications (tokio, async-std)
  • You want hierarchical span context
  • You need advanced filtering capabilities
  • You want automatic trace correlation
Choose the log appender if:
  • You have existing code using the log crate
  • You need simple, synchronous logging
  • You don’t need span correlation

Feature Flags

Limitations

  1. No Valuable support: The appender does not currently support the valuable crate for efficient serialization. See issue #2819.
  2. tracing-opentelemetry: This appender converts tracing events into logs, not spans. For converting tracing spans to OpenTelemetry spans, use the third-party tracing-opentelemetry crate.

Troubleshooting

Logs not appearing

  1. Check that the layer is registered:
  2. Verify filtering isn’t too restrictive:
  3. Always shutdown the provider:

Trace context not attached

Ensure you’re using OpenTelemetry’s tracing, not just tracing:

Span attributes not captured

Enable the feature flag:

See Also

log Appender

Alternative appender for the log crate

Log Processors

Configure batch and simple processors

Bridge API

Understanding the underlying API

Overview

Return to logs overview