Skip to content

Commit 7f6407b

Browse files
authored
Merge branch 'main' into cijothomas/simple-log-fix1
2 parents 999146b + 31b494b commit 7f6407b

File tree

21 files changed

+489
-281
lines changed

21 files changed

+489
-281
lines changed

.github/workflows/benchmark.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# This workflow runs a Criterion benchmark on a PR and compares the results against the base branch.
2+
# It is triggered on a PR or a push to main.
3+
#
4+
# The workflow is gated on the presence of the "performance" label on the PR.
5+
#
6+
# The workflow runs on a self-hosted runner pool. We can't use the shared runners for this,
7+
# because they are only permitted to run on the default branch to preserve resources.
8+
#
9+
# In the future, we might like to consider using bencher.dev or the framework used by otel-golang here.
10+
on:
11+
pull_request:
12+
push:
13+
branches:
14+
- main
15+
name: benchmark pull requests
16+
jobs:
17+
runBenchmark:
18+
name: run benchmark
19+
permissions:
20+
pull-requests: write
21+
22+
# If we're running on a PR, use ubuntu-latest - a shared runner. We can't use the self-hosted
23+
# runners on arbitrary PRs, and we don't want to unleash that load on the pool anyway.
24+
# If we're running on main, use the OTEL self-hosted runner pool.
25+
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-latest' || 'self-hosted' }}
26+
if: ${{ (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'performance')) || github.event_name == 'push' }}
27+
env:
28+
# For PRs, compare against the base branch - e.g., 'main'.
29+
# For pushes to main, compare against the previous commit
30+
BRANCH_NAME: ${{ github.event_name == 'pull_request' && github.base_ref || github.event.before }}
31+
steps:
32+
- uses: actions/checkout@v4
33+
with:
34+
fetch-depth: 10 # Fetch current commit and its parent
35+
- uses: arduino/setup-protoc@v3
36+
with:
37+
repo-token: ${{ secrets.GITHUB_TOKEN }}
38+
- uses: dtolnay/rust-toolchain@master
39+
with:
40+
toolchain: stable
41+
- uses: boa-dev/criterion-compare-action@v3
42+
with:
43+
cwd: opentelemetry
44+
branchName: ${{ env.BRANCH_NAME }}
45+
- uses: boa-dev/criterion-compare-action@v3
46+
with:
47+
cwd: opentelemetry-appender-tracing
48+
features: spec_unstable_logs_enabled
49+
branchName: ${{ env.BRANCH_NAME }}
50+
- uses: boa-dev/criterion-compare-action@v3
51+
with:
52+
cwd: opentelemetry-sdk
53+
features: rt-tokio,testing,metrics,logs,spec_unstable_metrics_views
54+
branchName: ${{ env.BRANCH_NAME }}

.github/workflows/pr_criterion.yaml

Lines changed: 0 additions & 31 deletions
This file was deleted.

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ It's important to regularly review and remove the `otel_unstable` flag from the
172172

173173
The potential features include:
174174

175-
- Stable and non-experimental features that compliant to specification, and have a feature flag to minimize compilation size. Example: feature flags for signals (like `logs`, `traces`, `metrics`) and runtimes (`rt-tokio`, `rt-tokio-current-thread`, `rt-async-std`).
175+
- Stable and non-experimental features that are compliant with the specification and have a feature flag to minimize compilation size. Example: feature flags for signals (like `logs`, `traces`, `metrics`) and runtimes (`rt-tokio`, `rt-tokio-current-thread`).
176176
- Stable and non-experimental features, although not part of the specification, are crucial for enhancing the tracing/log crate's functionality or boosting performance. These features are also subject to discussion and approval by the OpenTelemetry Rust Maintainers.
177177

178178
All such features should adhere to naming convention `<signal>_<feature_name>`
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,153 @@
1+
//! # OpenTelemetry-Appender-Tracing
2+
//!
3+
//! This crate provides a bridge between the [`tracing`](https://docs.rs/tracing/latest/tracing/) crate and OpenTelemetry logs.
4+
//! It converts `tracing` events into OpenTelemetry `LogRecords`, allowing applications using `tracing` to seamlessly integrate
5+
//! with OpenTelemetry logging backends.
6+
//!
7+
//! ## Background
8+
//!
9+
//! Unlike traces and metrics, OpenTelemetry does not provide a dedicated logging API for end-users. Instead, it recommends using
10+
//! existing logging libraries and bridging them to OpenTelemetry logs. This crate serves as such a bridge for `tracing` users.
11+
//!
12+
//! ## Features
13+
//!
14+
//! - Converts `tracing` events into OpenTelemetry [`LogRecords`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#log-and-event-record-definition)
15+
//! - Integrates as a [`Layer`](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/layer/trait.Layer.html)
16+
//! from [`tracing-subscriber`](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/), allowing
17+
//! to be used alongside other `tracing` layers, such as `fmt`
18+
//! - Automatically attaches OpenTelemetry trace context (`TraceId`, `SpanId`, `TraceFlags`) to logs
19+
//! - Automatically associates OpenTelemetry Resource to logs
20+
//! - Supports exporting logs to OpenTelemetry-compatible backends (OTLP, stdout, etc.)
21+
//!
22+
//! ## Getting Started
23+
//!
24+
//! ### 1. Install Dependencies
25+
//!
26+
//! Add the following dependencies to your `Cargo.toml`:
27+
//!
28+
//! ```toml
29+
//! [dependencies]
30+
//! tracing = ">=0.1.40"
31+
//! tracing-core = { version = ">=0.1.33" }
32+
//! tracing-subscriber = { version = "0.3", features = ["registry", "std", "fmt"] }
33+
//! opentelemetry = { version = "0.28", features = ["logs"] }
34+
//! opentelemetry-sdk = { version = "0.28", features = ["logs"] }
35+
//! opentelemetry-appender-tracing = { version = "0.28.1" }
36+
//! ```
37+
//!
38+
//! ### 2. Set Up the OpenTelemetry Logger Provider
39+
//!
40+
//! Before integrating with `tracing`, create an OpenTelemetry [`SdkLoggerProvider`](https://docs.rs/opentelemetry_sdk/latest/opentelemetry_sdk/logs/struct.SdkLoggerProvider.html):
41+
//!
42+
//! ```rust
43+
//! use opentelemetry_sdk::logs::SdkLoggerProvider;
44+
//! use opentelemetry_stdout::LogExporter;
45+
//!
46+
//! let exporter = LogExporter::default();
47+
//! let provider = SdkLoggerProvider::builder()
48+
//! .with_simple_exporter(exporter)
49+
//! .build();
50+
//! ```
51+
//!
52+
//! 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.
53+
//! Any additional OpenTelemetry configuration (e.g., setting up a resource, additional processors etc.) can be done at this stage.
54+
//!
55+
//! ### 3. Create the OpenTelemetry-Tracing Bridge
56+
//!
57+
//! ```rust
58+
//! # use opentelemetry_sdk::logs::SdkLoggerProvider;
59+
//! # use opentelemetry_stdout::LogExporter;
60+
//! # use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
61+
//! # let exporter = LogExporter::default();
62+
//! # let provider = SdkLoggerProvider::builder()
63+
//! .with_simple_exporter(exporter)
64+
//! .build();
65+
//! let otel_layer = OpenTelemetryTracingBridge::new(&provider);
66+
//! ```
67+
//!
68+
//! ### 4. Register the `tracing` Subscriber
69+
//!
70+
//! Since this crate provides a `Layer` for `tracing`, you can register it with the `tracing` subscriber as shown below.
71+
//!
72+
//! ```rust
73+
//! # use opentelemetry_sdk::logs::SdkLoggerProvider;
74+
//! # use opentelemetry_stdout::LogExporter;
75+
//! # let exporter = LogExporter::default();
76+
//! # let provider = SdkLoggerProvider::builder().with_simple_exporter(exporter).build();
77+
//! # use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
78+
//! # let otel_layer = OpenTelemetryTracingBridge::new(&provider);
79+
//! use tracing_subscriber::prelude::*;
80+
//!
81+
//! tracing_subscriber::registry()
82+
//! .with(otel_layer)
83+
//! .with(tracing_subscriber::fmt::layer())
84+
//! .init();
85+
//! ```
86+
//!
87+
//! ### 5. Log Events Using `tracing`
88+
//!
89+
//! ```rust
90+
//! use tracing::error;
91+
//! error!(name: "my-event-name1", target: "my-system", event_id = 10, user_name = "otel", user_email = "[email protected]", message = "This is an example message");
92+
//! ```
93+
//!
94+
//!
95+
//! ## Mapping details
96+
//!
97+
//! Since OpenTelemetry and `tracing` have their own data models, this bridge performs the following mappings:
98+
//!
99+
//! | `tracing` | OpenTelemetry | Notes |
100+
//! |-----------------------|-------------------------|-----------------------------------------------------------------------------------------|
101+
//! | name of the event | `EventName` | OpenTelemetry defines logs with name as Events, so every `tracing` Event is actually an OTel Event |
102+
//! | 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` |
103+
//! | level of the event | `Severity`, `SeverityText` | |
104+
//! | Fields | `Attributes` | Converted into OpenTelemetry log attributes. Field with "message" as key is specially treated and stored as `LogRecord::Body` |
105+
//! | Message | `Body` | The body/message of the log. This is done only if body was not already populated from "message" field above |
106+
//!
107+
//! ### Data Type Mapping
108+
//!
109+
//! The data types supported by `tracing` and OpenTelemetry are different and the following conversions are applied:
110+
//!
111+
//! | `tracing` Type | OpenTelemetry `AnyValue` Type |
112+
//! |----------------|-------------------------------|
113+
//! | `i64` | `Int` |
114+
//! | `f32`, `f64` | `Double` |
115+
//! | `u64` | `Int` (if convertible without loss) else `String` |
116+
//! | `&str` | `String` |
117+
//! | `bool` | `Bool` |
118+
//! | `&[u8]` | `Bytes` |
119+
//! | `&dyn Debug` | `String` (via `Debug` formatting) |
120+
//! | `&dyn Error` | `String` (via `Debug` formatting). This is stored into an attribute with key "exception.message", following [OTel conventions](https://opentelemetry.io/docs/specs/semconv/attributes-registry/exception/) |
121+
//!
122+
//! In future, additional types may be supported.
123+
//!
124+
//! > **Note:** This crate does not support `tracing` Spans. One may use [`tracing-opentelemetry`](https://docs.rs/tracing-opentelemetry/latest/tracing_opentelemetry/) to
125+
//! > convert `tracing` spans into OpenTelemetry spans. This is a third-party crate
126+
//! > that is not maintained by the OpenTelemetry project.
127+
//! > `tracing-opentelemetry`:
128+
//! > - Converts `tracing` spans into OpenTelemetry spans
129+
//! > - Converts `tracing` events into OpenTelemetry `SpanEvents` rather than logs
130+
//! > Depending on the outcome of the
131+
//! > [discussion](https://github.com/open-telemetry/opentelemetry-rust/issues/1571),
132+
//! > the OpenTelemetry project may provide direct support to map `tracing`
133+
//! > spans to OpenTelemetry in the future.
134+
//!
135+
//! ## Feature Flags
136+
//! `spec_unstable_logs_enabled`: TODO
137+
//!
138+
//! `experimental_metadata_attributes`: TODO
139+
//!
140+
//! `experimental_use_tracing_span_context`: TODO
141+
//!
142+
//! ## Limitations
143+
//! 1. There is no support for `Valuable` crate. [2819](https://github.com/open-telemetry/opentelemetry-rust/issues/2819)
144+
//!
145+
//! ## Stability Guarantees
146+
//! // TODO
147+
//!
148+
//! ## Further Reading
149+
//!
150+
//! - OpenTelemetry Rust: [opentelemetry-rust](https://github.com/open-telemetry/opentelemetry-rust)
151+
//! - Tracing: [tracing](https://docs.rs/tracing/)
152+
//! - OpenTelemetry Logs: [OpenTelemetry Logging Specification](https://opentelemetry.io/docs/specs/otel/logs/)
1153
pub mod layer;

opentelemetry-otlp/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@
1717
`Error` which contained many variants unrelated to building an exporter, the
1818
new one returns specific variants applicable to building an exporter. Some
1919
variants might be applicable only on select features.
20+
- **Breaking** `ExportConfig`'s `timeout` field is now optional(`Option<Duration>`)
21+
- **Breaking** Export configuration done via code is final. ENV variables cannot be used to override the code config.
22+
Do not use code based config, if there is desire to control the settings via ENV variables.
23+
List of ENV variables and corresponding setting being affected by this change.
24+
- `OTEL_EXPORTER_OTLP_ENDPOINT` -> `ExportConfig.endpoint`
25+
- `OTEL_EXPORTER_OTLP_TIMEOUT` -> `ExportConfig.timeout`
2026

2127
## 0.28.0
2228

0 commit comments

Comments
 (0)