@@ -5,16 +5,20 @@ Status:
55
66## Overview
77
8- OpenTelemetry (OTel) Logs support differs from Metrics and Traces as it does not
9- introduce a new logging API for end users. Instead, OTel recommends leveraging
10- existing logging libraries such as ` log ` and ` tracing ` , while providing bridges
11- (appenders) to route logs through OpenTelemetry.
12-
13- Unlike Traces and Metrics, which introduced new APIs, Logs took a different
14- approach due to the long history of existing logging solutions. In Rust, the
15- most widely used logging libraries are ` log ` and ` tracing ` . OTel Rust maintains
16- appenders for these libraries, allowing users to seamlessly integrate with
17- OpenTelemetry without changing their existing logging instrumentation.
8+ [ OpenTelemetry (OTel)
9+ Logs] ( https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/README.md )
10+ support differs from Metrics and Traces as it does not introduce a new logging
11+ API for end users. Instead, OTel recommends leveraging existing logging
12+ libraries such as [ log] ( https://crates.io/crates/log ) and
13+ [ tracing] ( https://crates.io/crates/tracing ) , while providing bridges (appenders)
14+ to route logs through OpenTelemetry.
15+
16+ OTel took this different approach due to the long history of existing logging
17+ solutions. In Rust, these are [ log] ( https://crates.io/crates/log ) and
18+ [ tracing] ( https://crates.io/crates/tracing ) , and have been embraced in the
19+ community for some time. OTel Rust maintains appenders for these libraries,
20+ allowing users to seamlessly integrate with OpenTelemetry without changing their
21+ existing logging instrumentation.
1822
1923The ` tracing ` appender is particularly optimized for performance due to its
2024widespread adoption and the fact that ` tracing ` itself has a bridge from the
@@ -29,21 +33,55 @@ prioritize `tracing`.
2933- ** Automatic correlation** with Traces.
3034- ** Consistent Resource attributes** across signals.
3135- ** Multiple destinations support** : Logs can continue flowing to existing
32- destinations like stdout while also being sent to an OpenTelemetry-capable
33- backend, typically via an OTLP Exporter or exporters that export to operating
34- system native systems like ` Windows ETW ` or ` Linux user_events ` .
36+ destinations like stdout etc. while also being sent to an
37+ OpenTelemetry-capable backend, typically via an OTLP Exporter or exporters
38+ that export to operating system native systems like ` Windows ETW ` or `Linux
39+ user_events`.
3540- ** Standalone logging support** for applications that use OpenTelemetry as
3641 their primary logging mechanism.
3742
3843## Key Design Principles
3944
40- - High performance - no locks/contention in the hot path, minimal/no heap
41- allocation.
42- - Capped resource usage - well-defined behavior when overloaded.
43- - Self-observable.
44- - Well defined Error handling, returning Result as appropriate instead of panic.
45+ - High performance - no locks/contention in the hot path with minimal/no heap
46+ allocation where possible.
47+ - Capped resource (memory) usage - well-defined behavior when overloaded.
48+ - Self-observable - exposes telemetry about itself to aid in troubleshooting
49+ etc.
50+ - Robust error handling, returning Result where possible instead of panicking.
4551- Minimal public API, exposing based on need only.
4652
53+ ## Architecture Overview
54+
55+ ``` mermaid
56+ graph TD
57+ subgraph Application
58+ A1[Application Code]
59+ end
60+ subgraph Logging Libraries
61+ B1[log crate]
62+ B2[tracing crate]
63+ end
64+ subgraph OpenTelemetry
65+ C1[OpenTelemetry Appender for log]
66+ C2[OpenTelemetry Appender for tracing]
67+ C3[OpenTelemetry Logs API]
68+ C4[OpenTelemetry Logs SDK]
69+ C5[OTLP Exporter]
70+ end
71+ subgraph Observability Backend
72+ D1[OTLP-Compatible Backend]
73+ end
74+ A1 --> |Emits Logs| B1
75+ A1 --> |Emits Logs| B2
76+ B1 --> |Bridged by| C1
77+ B2 --> |Bridged by| C2
78+ C1 --> |Sends to| C3
79+ C2 --> |Sends to| C3
80+ C3 --> |Processes with| C4
81+ C4 --> |Exports via| C5
82+ C5 --> |Sends to| D1
83+ ```
84+
4785## Logs API
4886
4987The OTel Logs API is not intended for direct end-user usage. Instead, it is
@@ -53,9 +91,10 @@ end-users.
5391
5492### API Components
5593
56- 1 . ** Key-Value Structs** : Used in ` LogRecord ` , where keys are shared across
57- signals but values differ from Metrics and Traces. This is because values in
58- Logs can contain more complex structures than those in Traces and Metrics.
94+ 1 . ** Key-Value Structs** : Used in ` LogRecord ` , where ` Key ` struct is shared
95+ across signals but ` Value ` struct differ from Metrics and Traces. This is
96+ because values in Logs can contain more complex structures than those in
97+ Traces and Metrics.
59982 . ** Traits** :
6099 - ` LoggerProvider ` - provides methods to obtain Logger.
61100 - ` Logger ` - provides methods to create LogRecord and emit the created
@@ -88,6 +127,9 @@ implementation of the Logs API, handling log processing and export.
88127
89128#### ` SdkLoggerProvider `
90129
130+ This is the implementation of the ` LoggerProvider ` and deals with concerns such
131+ as processing and exporting Logs.
132+
91133- Implements the ` LoggerProvider ` trait.
92134- Creates and manages ` SdkLogger ` instances.
93135- Holds logging configuration, including ` Resource ` and processors.
@@ -97,22 +139,25 @@ implementation of the Logs API, handling log processing and export.
97139- Uses an ` Arc<LoggerProviderInner> ` and delegates all configuration to
98140 ` LoggerProviderInner ` . This allows cheap cloning of itself and ensures all
99141 clones point to the same underlying configuration.
100- - As ` SdkLoggerProvider ` only holds an ` Arc ` of its inner, it can only accept
142+ - As ` SdkLoggerProvider ` only holds an ` Arc ` of its inner, it can only take
101143 ` &self ` in its methods like flush and shutdown. Else it needs to rely on
102144 interior mutability that comes with runtime performance costs. Since methods
103- like shutdown usually need to mutate interior state, components like exporter
104- use interior mutability to handle shutdown. (More on this in the exporter
105- section)
145+ like shutdown usually need to mutate interior state, but this component can
146+ only take ` &self ` , it defers to components like exporter to use interior
147+ mutability to handle shutdown. (More on this in the exporter section)
106148- An alternative design was to let ` SdkLogger ` hold a ` Weak ` reference to the
107- ` SdkLoggerProvider ` . This would be a ` weak->arc ` upgrade in every log emission,
108- significantly affecting throughput.
149+ ` SdkLoggerProvider ` . This would be a ` weak->arc ` upgrade in every log
150+ emission, significantly affecting throughput.
109151- ` LoggerProviderInner ` implements ` Drop ` , triggering ` shutdown() ` when no
110152 references remain. However, in practice, loggers are often stored statically
111153 inside appenders (like tracing-appender), so explicit shutdown by the user is
112154 required.
113155
114156#### ` SdkLogger `
115157
158+ This is an implementation of the ` Logger ` , and contains functionality to create
159+ and emit logs.
160+
116161- Implements the ` Logger ` trait.
117162- Creates ` SdkLogRecord ` instances and emits them.
118163- Calls ` OnEmit() ` on all registered processors when emitting logs.
@@ -204,9 +249,9 @@ include:
204249
205250## ` tracing ` Log Appender
206251
207- The ` tracing ` appender bridges ` tracing ` logs to OpenTelemetry. Logs emitted via
208- ` tracing ` macros (` info! ` , ` warn! ` , etc.) are forwarded to OpenTelemetry through
209- this integration.
252+ The ` tracing ` appender bridges ` tracing ` logs (events) to OpenTelemetry. Logs
253+ emitted via ` tracing ` macros (` info! ` , ` warn! ` , etc.) are forwarded to
254+ OpenTelemetry through this integration.
210255
211256- ` tracing ` is designed for high performance, using * layers* or * subscribers* to
212257 handle emitted logs (events).
@@ -215,6 +260,13 @@ this integration.
215260 ` Logger.emit(LogRecord) ` .
216261- If no Logs SDK is present, the process is a no-op.
217262
263+ Note on terminology: Within OpenTelemetry, "tracing" refers to distributed
264+ tracing (i.e creation of Spans) and not in-process structured logging and
265+ execution traces. The crate "tracing" has notion of creating Spans as well as
266+ Events. The events from "tracing" crate is what gets converted to OTel Logs,
267+ when using this appender. Spans created using "tracing" crate is not handled by
268+ this crate.
269+
218270## Performance
219271
220272// Call out things done specifically for performance
0 commit comments