Skip to content

Commit 0cdf9c7

Browse files
committed
address feedback and add mermaid
1 parent fc275c1 commit 0cdf9c7

File tree

1 file changed

+82
-30
lines changed

1 file changed

+82
-30
lines changed

docs/design/logs.md

Lines changed: 82 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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

1923
The `tracing` appender is particularly optimized for performance due to its
2024
widespread 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

4987
The 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.
5998
2. **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

Comments
 (0)