Skip to content

Commit 79c27c7

Browse files
Merge branch 'main' of github.com:mohammadVatandoost/opentelemetry-rust
2 parents b8b97ac + 369b952 commit 79c27c7

File tree

132 files changed

+5021
-1876
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+5021
-1876
lines changed

.github/ISSUE_TEMPLATE/BUG-REPORT.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ body:
2828
- type: textarea
2929
id: sdk-version
3030
attributes:
31-
label: label: OpenTelemetry SDK Version (i.e version of `opentelemetry_sdk` crate)
31+
label: OpenTelemetry SDK Version (i.e version of `opentelemetry_sdk` crate)
3232
description: What version of the `opentelemetry_sdk` crate are you using?
3333
placeholder: 0.x, 1.x, etc.
3434
validations:

.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/ci.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,8 @@ jobs:
6262
- uses: arduino/setup-protoc@v3
6363
with:
6464
repo-token: ${{ secrets.GITHUB_TOKEN }}
65-
- uses: actions-rs/cargo@v1
66-
with:
67-
command: fmt
68-
args: --all -- --check
65+
- name: Format
66+
run: cargo fmt --all -- --check
6967
- name: Lint
7068
run: bash ./scripts/lint.sh
7169
external-types:

.github/workflows/integration_tests.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,7 @@ jobs:
2323
with:
2424
components: rustfmt
2525
- uses: arduino/setup-protoc@v3
26+
with:
27+
repo-token: ${{ secrets.GITHUB_TOKEN }}
2628
- name: Run integration tests
2729
run: ./scripts/integration_tests.sh

.github/workflows/pr_criterion.yaml

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

.github/workflows/pr_naming.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-latest
1010
steps:
1111
- name: PR Conventional Commit Validation
12-
uses: ytanikin/[email protected].0
12+
uses: ytanikin/[email protected].1
1313
with:
1414
task_types: '["build","chore","ci","docs","feat","fix","perf","refactor","revert","test"]'
1515
add_label: 'false'

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ for specific dates and for Zoom meeting links. "OTel Rust SIG" is the name of
88
meeting for this group.
99

1010
Meeting notes are available as a public [Google
11-
doc](https://docs.google.com/document/d/1tGKuCsSnyT2McDncVJrMgg74_z8V06riWZa0Sr79I_4/edit).
11+
doc](https://docs.google.com/document/d/12upOzNk8c3SFTjsL6IRohCWMgzLKoknSCOOdMakbWo4/edit).
1212
If you have trouble accessing the doc, please get in touch on
1313
[Slack](https://cloud-native.slack.com/archives/C03GDP0H023).
1414

@@ -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>`

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,12 @@ opentelemetry = { path = "opentelemetry" }
8585
opentelemetry_sdk = { path = "opentelemetry-sdk" }
8686
opentelemetry-stdout = { path = "opentelemetry-stdout" }
8787

88+
[workspace.lints.rust]
89+
rust_2024_compatibility = { level = "warn", priority = -1 }
90+
# No need to enable those, because it either not needed or results in ugly syntax
91+
edition_2024_expr_fragment_specifier = "allow"
92+
if_let_rescope = "allow"
93+
tail_expr_drop_order = "allow"
94+
8895
[workspace.lints.clippy]
8996
all = { level = "warn", priority = 1 }

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,13 @@ documentation.
3030

3131
| Signal/Component | Overall Status |
3232
| -------------------- | ------------------ |
33+
| Context | Beta |
34+
| Baggage | RC |
35+
| Propagators | Beta |
3336
| Logs-API | Stable* |
34-
| Logs-SDK | RC |
37+
| Logs-SDK | Stable |
3538
| Logs-OTLP Exporter | RC |
36-
| Logs-Appender-Tracing | RC |
39+
| Logs-Appender-Tracing | Stable |
3740
| Metrics-API | Stable |
3841
| Metrics-SDK | RC |
3942
| Metrics-OTLP Exporter | RC |
@@ -178,7 +181,6 @@ you're more than welcome to participate!
178181

179182
* [Cijo Thomas](https://github.com/cijothomas)
180183
* [Harold Dost](https://github.com/hdost)
181-
* [Julian Tescher](https://github.com/jtescher)
182184
* [Lalit Kumar Bhasin](https://github.com/lalitb)
183185
* [Utkarsh Umesan Pillai](https://github.com/utpilla)
184186
* [Zhongyang Wu](https://github.com/TommyCpp)
@@ -192,6 +194,7 @@ you're more than welcome to participate!
192194

193195
* [Dirkjan Ochtman](https://github.com/djc)
194196
* [Jan Kühle](https://github.com/frigus02)
197+
* [Julian Tescher](https://github.com/jtescher)
195198
* [Isobel Redelmeier](https://github.com/iredelmeier)
196199
* [Mike Goldsmith](https://github.com/MikeGoldsmith)
197200

docs/adr/001_error_handling.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# Error handling patterns in public API interfaces
2+
## Date
3+
27 Feb 2025
4+
5+
## Summary
6+
7+
This ADR describes the general pattern we will follow when modelling errors in public API interfaces - that is, APIs that are exposed to users of the project's published crates. It summarises the discussion and final option from [#2571](https://github.com/open-telemetry/opentelemetry-rust/issues/2571); for more context check out that issue.
8+
9+
We will focus on the exporter traits in this example, but the outcome should be applied to _all_ public traits and their fallible operations.
10+
11+
These include [SpanExporter](https://github.com/open-telemetry/opentelemetry-rust/blob/eca1ce87084c39667061281e662d5edb9a002882/opentelemetry-sdk/src/trace/export.rs#L18), [LogExporter](https://github.com/open-telemetry/opentelemetry-rust/blob/eca1ce87084c39667061281e662d5edb9a002882/opentelemetry-sdk/src/logs/export.rs#L115), and [PushMetricExporter](https://github.com/open-telemetry/opentelemetry-rust/blob/eca1ce87084c39667061281e662d5edb9a002882/opentelemetry-sdk/src/metrics/exporter.rs#L11) which form part of the API surface of `opentelemetry-sdk`.
12+
13+
There are various ways to handle errors on trait methods, including swallowing them and logging, panicing, returning a shared global error, or returning a method-specific error. We strive for consistency, and we want to be sure that we've put enough thought into what this looks like that we don't have to make breaking interface changes unecessarily in the future.
14+
15+
## Design Guidance
16+
17+
### 1. No panics from SDK APIs
18+
Failures during regular operation should not panic, instead returning errors to the caller where appropriate, _or_ logging an error if not appropriate.
19+
Some of the opentelemetry SDK interfaces are dictated by the specification in way such that they may not return errors.
20+
21+
### 2. Consolidate error types within a trait where we can, let them diverge when we can't**
22+
23+
We aim to consolidate error types where possible _without indicating a function may return more errors than it can actually return_.
24+
25+
**Don't do this** - each function's signature indicates that it returns errors it will _never_ return, forcing the caller to write handlers for dead paths:
26+
```rust
27+
enum MegaError {
28+
TooBig,
29+
TooSmall,
30+
TooLong,
31+
TooShort
32+
}
33+
34+
trait MyTrait {
35+
36+
// Will only ever return TooBig,TooSmall errors
37+
fn action_one() -> Result<(), MegaError>;
38+
39+
// These will only ever return TooLong,TooShort errors
40+
fn action_two() -> Result<(), MegaError>;
41+
fn action_three() -> Result<(), MegaError>;
42+
}
43+
```
44+
45+
**Instead, do this** - each function's signature indicates only the errors it can return, providing an accurate contract to the caller:
46+
47+
```rust
48+
enum ErrorOne {
49+
TooBig,
50+
TooSmall,
51+
}
52+
53+
enum ErrorTwo {
54+
TooLong,
55+
TooShort
56+
}
57+
58+
trait MyTrait {
59+
fn action_one() -> Result<(), ErrorOne>;
60+
61+
// Action two and three share the same error type.
62+
// We do not introduce a common error MyTraitError for all operations, as this would
63+
// force all methods on the trait to indicate they return errors they do not return,
64+
// complicating things for the caller.
65+
fn action_two() -> Result<(), ErrorTwo>;
66+
fn action_three() -> Result<(), ErrorTwo>;
67+
}
68+
```
69+
70+
## 3. Consolidate error types between signals where we can, let them diverge where we can't
71+
72+
Consider the `Exporter`s mentioned earlier. Each of them has the same failure indicators - as dicated by the OpenTelemetry spec - and we will
73+
share the error types accordingly:
74+
75+
**Don't do this** - each signal has its own error type, despite having exactly the same failure cases:
76+
77+
```rust
78+
#[derive(Error, Debug)]
79+
pub enum OtelTraceError {
80+
#[error("Shutdown already invoked")]
81+
AlreadyShutdown,
82+
83+
#[error("Operation failed: {0}")]
84+
InternalFailure(String),
85+
86+
/** ... additional errors ... **/
87+
}
88+
89+
#[derive(Error, Debug)]
90+
pub enum OtelLogError {
91+
#[error("Shutdown already invoked")]
92+
AlreadyShutdown,
93+
94+
#[error("Operation failed: {0}")]
95+
InternalFailure(String),
96+
97+
/** ... additional errors ... **/
98+
}
99+
```
100+
101+
**Instead, do this** - error types are consolidated between signals where this can be done appropriately:
102+
103+
```rust
104+
105+
/// opentelemetry-sdk::error
106+
107+
#[derive(Error, Debug)]
108+
pub enum OTelSdkError {
109+
#[error("Shutdown already invoked")]
110+
AlreadyShutdown,
111+
112+
#[error("Operation failed: {0}")]
113+
InternalFailure(String),
114+
115+
/** ... additional errors ... **/
116+
}
117+
118+
pub type OTelSdkResult = Result<(), OTelSdkError>;
119+
120+
/// signal-specific exporter traits all share the same
121+
/// result types for the exporter operations.
122+
123+
// pub trait LogExporter {
124+
// pub trait SpanExporter {
125+
pub trait PushMetricExporter {
126+
fn export(&self, /* ... */) -> OtelSdkResult;
127+
fn force_flush(&self, /* ... */ ) -> OTelSdkResult;
128+
fn shutdown(&self, /* ... */ ) -> OTelSdkResult;
129+
```
130+
131+
If this were _not_ the case - if we needed to mark an extra error for instance for `LogExporter` that the caller could reasonably handle -
132+
we would let that error traits diverge at that point.
133+
134+
### 4. Box custom errors where a savvy caller may be able to handle them, stringify them if not
135+
136+
Note above that we do not box any `Error` into `InternalFailure`. Our rule here is that if the caller cannot reasonably be expected to handle a particular error variant, we will use a simplified interface that returns only a descriptive string. In the concrete example we are using with the exporters, we have a [strong signal in the opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/sdk.md#export) that indicates that the error types _are not actionable_ by the caller.
137+
138+
If the caller may potentially recover from an error, we will follow the generally-accepted best practice (e.g., see [canonical's guide](https://canonical.github.io/rust-best-practices/error-and-panic-discipline.html) and instead preserve the nested error:
139+
140+
**Don't do this if the OtherError is potentially recoverable by a savvy caller**:
141+
```rust
142+
143+
#[derive(Debug, Error)]
144+
pub enum MyError {
145+
#[error("Error one occurred")]
146+
ErrorOne,
147+
148+
#[error("Operation failed: {0}")]
149+
OtherError(String),
150+
```
151+
152+
**Instead, do this**, allowing the caller to match on the nested error:
153+
154+
```rust
155+
#[derive(Debug, Error)]
156+
pub enum MyError {
157+
#[error("Error one occurred")]
158+
ErrorOne,
159+
160+
#[error("Operation failed: {source}")]
161+
OtherError {
162+
#[from]
163+
source: Box<dyn Error + Send + Sync>,
164+
},
165+
}
166+
```
167+
168+
Note that at the time of writing, there is no instance we have identified within the project that has required this.
169+
170+
### 5. Use thiserror by default
171+
We will use [thiserror](https://docs.rs/thiserror/latest/thiserror/) by default to implement Rust's [error trait](https://doc.rust-lang.org/core/error/trait.Error.html).
172+
This keeps our code clean, and as it does not appear in our interface, we can choose to replace any particular usage with a hand-rolled implementation should we need to.
173+

0 commit comments

Comments
 (0)