Skip to content

Commit 105a46d

Browse files
authored
Merge branch 'main' into cijothomas/addscott-approver
2 parents 98eccc6 + ee76205 commit 105a46d

File tree

16 files changed

+85
-37
lines changed

16 files changed

+85
-37
lines changed

docs/design/logs.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,22 @@ this crate.
280280
## Performance
281281

282282
// Call out things done specifically for performance
283+
// Rough draft
284+
285+
1. `LogRecord` is stack allocated and not Boxed unless required by the component
286+
needing to store it beyond the logging call. (eg: BatchProcessor)
287+
2. LogRecords's Attribute storage is specially designed struct, that holds up to
288+
five attributes in stack.
289+
3. When passing `LogRecord`s to processor, a mutable ref is passed. This allows
290+
calling multiple processors one after another, without the need for cloning.
291+
4. `Logger` provides a `Enabled` check which can optimize performance when
292+
no-one is interested in the log. The check is passed from `Logger` to the
293+
processor, which may consult its exporter to make the decision. An example use
294+
case - an ETW or user-events exporter can check for the presence of listener and
295+
convey that decision back to logger, allowing appender to avoid even the cost of
296+
creating a `LogRecord` in the first place if there is no listener. This check is
297+
done for each log emission, and can react dynamically to changes in interest, by
298+
enabling/disabling ETW/user-event listener.
283299

284300
### Perf test - benchmarks
285301

@@ -289,6 +305,23 @@ this crate.
289305

290306
// Share ~~ numbers
291307

308+
## Internal logs
309+
310+
OTel itself is instrumented with `tracing` crate to emit internal logs about its
311+
operations. This is feature gated under "internal-logs", and is enabled by
312+
default for all components. The `opentelemetry` provide few helper macros
313+
`otel_warn` etc., which in turn invokes various `tracing` macros like `warn!`
314+
etc. The cargo package name will be set as `target` when using `tracing`. For
315+
example, logs from `opentelemetry-otlp` will have target set to
316+
"opentelemetry-otlp".
317+
318+
The helper macros are part of public API, so can be used by anyone. But it is
319+
only meant for OTel components itself and anyone writing extensions like custom
320+
Exporters etc.
321+
322+
// TODO: Document the principles followed when selecting severity for internal
323+
logs // TODO: Document how this can cause circular loop and plans to address it.
324+
292325
## Summary
293326

294327
- OpenTelemetry Logs does not provide a user-facing logging API.

opentelemetry-otlp/src/exporter/http/trace.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use opentelemetry_sdk::{
99
};
1010

1111
impl SpanExporter for OtlpHttpClient {
12-
async fn export(&mut self, batch: Vec<SpanData>) -> OTelSdkResult {
12+
async fn export(&self, batch: Vec<SpanData>) -> OTelSdkResult {
1313
let client = match self
1414
.client
1515
.lock()

opentelemetry-otlp/src/exporter/tonic/trace.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use core::fmt;
2+
use tokio::sync::Mutex;
23

34
use opentelemetry::otel_debug;
45
use opentelemetry_proto::tonic::collector::trace::v1::{
@@ -23,7 +24,7 @@ pub(crate) struct TonicTracesClient {
2324

2425
struct ClientInner {
2526
client: TraceServiceClient<Channel>,
26-
interceptor: BoxInterceptor,
27+
interceptor: Mutex<BoxInterceptor>,
2728
}
2829

2930
impl fmt::Debug for TonicTracesClient {
@@ -50,26 +51,27 @@ impl TonicTracesClient {
5051
TonicTracesClient {
5152
inner: Some(ClientInner {
5253
client,
53-
interceptor,
54+
interceptor: Mutex::new(interceptor),
5455
}),
5556
resource: Default::default(),
5657
}
5758
}
5859
}
5960

6061
impl SpanExporter for TonicTracesClient {
61-
async fn export(&mut self, batch: Vec<SpanData>) -> OTelSdkResult {
62-
let (mut client, metadata, extensions) = match &mut self.inner {
62+
async fn export(&self, batch: Vec<SpanData>) -> OTelSdkResult {
63+
let (mut client, metadata, extensions) = match &self.inner {
6364
Some(inner) => {
64-
let (m, e, _) = match inner.interceptor.call(Request::new(())) {
65-
Ok(res) => res.into_parts(),
66-
Err(e) => return Err(OTelSdkError::InternalFailure(e.to_string())),
67-
};
65+
let (m, e, _) = inner
66+
.interceptor
67+
.lock()
68+
.await // tokio::sync::Mutex doesn't return a poisoned error, so we can safely use the interceptor here
69+
.call(Request::new(()))
70+
.map_err(|e| OTelSdkError::InternalFailure(format!("error: {:?}", e)))?
71+
.into_parts();
6872
(inner.client.clone(), m, e)
6973
}
70-
None => {
71-
return Err(OTelSdkError::AlreadyShutdown);
72-
}
74+
None => return Err(OTelSdkError::AlreadyShutdown),
7375
};
7476

7577
let resource_spans = group_spans_by_resource_and_scope(batch, &self.resource);

opentelemetry-otlp/src/span.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ impl SpanExporter {
141141
}
142142

143143
impl opentelemetry_sdk::trace::SpanExporter for SpanExporter {
144-
async fn export(&mut self, batch: Vec<SpanData>) -> OTelSdkResult {
145-
match &mut self.client {
144+
async fn export(&self, batch: Vec<SpanData>) -> OTelSdkResult {
145+
match &self.client {
146146
#[cfg(feature = "grpc-tonic")]
147147
SupportedTransportClient::Tonic(client) => client.export(batch).await,
148148
#[cfg(any(feature = "http-proto", feature = "http-json"))]

opentelemetry-sdk/CHANGELOG.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,17 @@
3333
}
3434
}
3535
```
36-
36+
- **Breaking** The SpanExporter::export() method no longer requires a mutable reference to self.
37+
Before:
38+
```rust
39+
async fn export(&mut self, batch: Vec<SpanData>) -> OTelSdkResult
40+
```
41+
After:
42+
```rust
43+
async fn export(&self, batch: Vec<SpanData>) -> OTelSdkResult
44+
```
45+
Custom exporters will need to internally synchronize any mutable state, if applicable.
46+
3747
## 0.28.0
3848

3949
Released 2025-Feb-10

opentelemetry-sdk/benches/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ fn parent_sampled_tracer(inner_sampler: Sampler) -> (SdkTracerProvider, BoxedTra
136136
struct NoopExporter;
137137

138138
impl SpanExporter for NoopExporter {
139-
async fn export(&mut self, _spans: Vec<SpanData>) -> OTelSdkResult {
139+
async fn export(&self, _spans: Vec<SpanData>) -> OTelSdkResult {
140140
Ok(())
141141
}
142142
}

opentelemetry-sdk/benches/span_builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ fn not_sampled_provider() -> (sdktrace::SdkTracerProvider, sdktrace::SdkTracer)
6565
struct NoopExporter;
6666

6767
impl SpanExporter for NoopExporter {
68-
async fn export(&mut self, _spans: Vec<SpanData>) -> OTelSdkResult {
68+
async fn export(&self, _spans: Vec<SpanData>) -> OTelSdkResult {
6969
Ok(())
7070
}
7171
}

opentelemetry-sdk/benches/trace.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ fn criterion_benchmark(c: &mut Criterion) {
5959
struct VoidExporter;
6060

6161
impl SpanExporter for VoidExporter {
62-
async fn export(&mut self, _spans: Vec<SpanData>) -> OTelSdkResult {
62+
async fn export(&self, _spans: Vec<SpanData>) -> OTelSdkResult {
6363
Ok(())
6464
}
6565
}

opentelemetry-sdk/src/testing/trace/span_exporters.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub struct TokioSpanExporter {
4141
}
4242

4343
impl SpanExporter for TokioSpanExporter {
44-
async fn export(&mut self, batch: Vec<SpanData>) -> OTelSdkResult {
44+
async fn export(&self, batch: Vec<SpanData>) -> OTelSdkResult {
4545
batch.into_iter().try_for_each(|span_data| {
4646
self.tx_export
4747
.send(span_data)
@@ -110,7 +110,7 @@ impl NoopSpanExporter {
110110
}
111111

112112
impl SpanExporter for NoopSpanExporter {
113-
async fn export(&mut self, _: Vec<SpanData>) -> OTelSdkResult {
113+
async fn export(&self, _: Vec<SpanData>) -> OTelSdkResult {
114114
Ok(())
115115
}
116116
}

opentelemetry-sdk/src/trace/export.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub trait SpanExporter: Send + Sync + Debug {
2828
/// Any retry logic that is required by the exporter is the responsibility
2929
/// of the exporter.
3030
fn export(
31-
&mut self,
31+
&self,
3232
batch: Vec<SpanData>,
3333
) -> impl std::future::Future<Output = OTelSdkResult> + Send;
3434

0 commit comments

Comments
 (0)