Skip to content

Commit 154b765

Browse files
committed
merge main
2 parents ef87ca7 + 902baa9 commit 154b765

File tree

48 files changed

+2577
-586
lines changed

Some content is hidden

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

48 files changed

+2577
-586
lines changed

examples/logs-basic/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ publish = false
99
opentelemetry = { path = "../../opentelemetry", features = ["logs"] }
1010
opentelemetry_sdk = { path = "../../opentelemetry-sdk", features = ["logs"] }
1111
opentelemetry-stdout = { path = "../../opentelemetry-stdout", features = ["logs"]}
12-
opentelemetry-appender-log = { path = "../../opentelemetry-appender-log", default-features = false}
12+
opentelemetry-appender-tracing = { path = "../../opentelemetry-appender-tracing", default-features = false}
1313
opentelemetry-semantic-conventions = { path = "../../opentelemetry-semantic-conventions" }
14-
log = { workspace = true }
15-
serde_json = { workspace = true }
14+
tracing = { workspace = true, features = ["std"]}
15+
tracing-subscriber = { workspace = true, features = ["registry", "std"] }

examples/logs-basic/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
# OpenTelemetry Log Appender for log - Example
1+
# OpenTelemetry Log Appender for tracing - Example
22

3-
This example shows how to use the opentelemetry-appender-log crate, which is a
3+
This example shows how to use the opentelemetry-appender-tracing crate, which is a
44
[logging
55
appender](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#log-appender--bridge)
6-
that bridges logs from the [log crate](https://docs.rs/log/latest/log/) to
6+
that bridges logs from the [tracing crate](https://tracing.rs/tracing/#events) to
77
OpenTelemetry. The example setups a LoggerProvider with stdout exporter, so logs
88
are emitted to stdout.
99

1010
## Usage
1111

12-
Run the following, and Logs emitted using [log](https://docs.rs/log/latest/log/)
12+
Run the following, and Logs emitted using [tracing](https://docs.rs/tracing/latest/tracing/)
1313
will be written out to stdout.
1414

1515
```shell

examples/logs-basic/src/main.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
1-
use log::{error, Level};
21
use opentelemetry::KeyValue;
3-
use opentelemetry_appender_log::OpenTelemetryLogBridge;
2+
use opentelemetry_appender_tracing::layer;
43
use opentelemetry_sdk::logs::LoggerProvider;
54
use opentelemetry_sdk::Resource;
6-
use opentelemetry_semantic_conventions::resource::SERVICE_NAME;
5+
use tracing::error;
6+
use tracing_subscriber::prelude::*;
77

88
fn main() {
9-
// Setup LoggerProvider with a stdout exporter
109
let exporter = opentelemetry_stdout::LogExporter::default();
11-
let logger_provider = LoggerProvider::builder()
12-
.with_resource(Resource::new([KeyValue::new(
13-
SERVICE_NAME,
14-
"logs-basic-example",
10+
let provider: LoggerProvider = LoggerProvider::builder()
11+
.with_resource(Resource::new(vec![KeyValue::new(
12+
"service.name",
13+
"log-appender-tracing-example",
1514
)]))
1615
.with_simple_exporter(exporter)
1716
.build();
17+
let layer = layer::OpenTelemetryTracingBridge::new(&provider);
18+
tracing_subscriber::registry().with(layer).init();
1819

19-
// Setup Log Appender for the log crate.
20-
let otel_log_appender = OpenTelemetryLogBridge::new(&logger_provider);
21-
log::set_boxed_logger(Box::new(otel_log_appender)).unwrap();
22-
log::set_max_level(Level::Error.to_level_filter());
23-
24-
// Emit logs using macros from the log crate.
25-
// These logs gets piped through OpenTelemetry bridge and gets exported to stdout.
26-
error!(target: "my-target", "hello from {}. My price is {}", "apple", 2.99);
20+
error!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "[email protected]", message = "This is an example message");
21+
let _ = provider.shutdown();
2722
}

opentelemetry-appender-tracing/benches/logs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct NoopExporter {
3434

3535
#[async_trait]
3636
impl LogExporter for NoopExporter {
37-
async fn export(&mut self, _: LogBatch<'_>) -> LogResult<()> {
37+
async fn export(&self, _: LogBatch<'_>) -> LogResult<()> {
3838
LogResult::Ok(())
3939
}
4040

opentelemetry-appender-tracing/src/layer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ mod tests {
247247

248248
#[async_trait]
249249
impl LogExporter for ReentrantLogExporter {
250-
async fn export(&mut self, _batch: LogBatch<'_>) -> LogResult<()> {
250+
async fn export(&self, _batch: LogBatch<'_>) -> LogResult<()> {
251251
// This will cause a deadlock as the export itself creates a log
252252
// while still within the lock of the SimpleLogProcessor.
253253
warn!(name: "my-event-name", target: "reentrant", event_id = 20, user_name = "otel", user_email = "[email protected]");

opentelemetry-otlp/examples/basic-otlp-http/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ http-body-util = { workspace = true, optional = true }
2727
tokio = { workspace = true, features = ["full"] }
2828
tracing = { workspace = true, features = ["std"]}
2929
tracing-core = { workspace = true }
30-
tracing-subscriber = { workspace = true, features = ["env-filter","registry", "std"] }
30+
tracing-subscriber = { workspace = true, features = ["env-filter","registry", "std", "fmt"] }

opentelemetry-otlp/examples/basic-otlp-http/README.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
1-
# Basic OTLP exporter Example
1+
# Basic OTLP Exporter Example
22

3-
This example shows how to setup OpenTelemetry OTLP exporter for logs, metrics
4-
and traces to export them to the [OpenTelemetry
3+
This example demonstrates how to set up an OpenTelemetry OTLP exporter for logs,
4+
metrics, and traces to send data to the [OpenTelemetry
55
Collector](https://github.com/open-telemetry/opentelemetry-collector) via OTLP
6-
over selected protocol such as HTTP/protobuf or HTTP/json. The Collector then sends the data to the appropriate
7-
backend, in this case, the logging Exporter, which displays data to console.
6+
over HTTP (using `protobuf` encoding by default but can be changed to use
7+
`json`). The Collector then forwards the data to the configured backend, which
8+
in this case is the logging exporter, displaying data on the console.
9+
Additionally, the example configures a `tracing::fmt` layer to output logs
10+
emitted via `tracing` to `stdout`. For demonstration, this layer uses a filter
11+
to display `DEBUG` level logs from various OpenTelemetry components. In real
12+
applications, these filters should be adjusted appropriately.
13+
14+
The example employs a `BatchExporter` for logs and traces, which is the
15+
recommended approach when using OTLP exporters. While it can be modified to use
16+
a `SimpleExporter`, this requires enabling feature flag `reqwest-blocking-client` and
17+
making the `main()` a normal main and *not* `tokio::main`
18+
19+
// TODO: Metrics does not work with non tokio main when using `reqwest-blocking-client` today, fix that when switching
20+
// default to use own thread.
21+
// TODO: Document `hyper` feature flag when using SimpleProcessor.
822

923
## Usage
1024

opentelemetry-otlp/examples/basic-otlp-http/src/main.rs

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fn init_logs() -> Result<sdklogs::LoggerProvider, opentelemetry_sdk::logs::LogEr
4343
.build())
4444
}
4545

46-
fn init_tracer_provider() -> Result<sdktrace::TracerProvider, TraceError> {
46+
fn init_traces() -> Result<sdktrace::TracerProvider, TraceError> {
4747
let exporter = SpanExporter::builder()
4848
.with_http()
4949
.with_protocol(Protocol::HttpBinary) //can be changed to `Protocol::HttpJson` to export in JSON format
@@ -71,51 +71,48 @@ fn init_metrics() -> Result<opentelemetry_sdk::metrics::SdkMeterProvider, Metric
7171

7272
#[tokio::main]
7373
async fn main() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
74-
let result = init_tracer_provider();
75-
assert!(
76-
result.is_ok(),
77-
"Init tracer failed with error: {:?}",
78-
result.err()
79-
);
80-
81-
let tracer_provider = result.unwrap();
74+
let tracer_provider = init_traces()?;
8275
global::set_tracer_provider(tracer_provider.clone());
8376

84-
let result = init_metrics();
85-
assert!(
86-
result.is_ok(),
87-
"Init metrics failed with error: {:?}",
88-
result.err()
89-
);
90-
91-
let meter_provider = result.unwrap();
77+
let meter_provider = init_metrics()?;
9278
global::set_meter_provider(meter_provider.clone());
9379

94-
// Opentelemetry will not provide a global API to manage the logger
95-
// provider. Application users must manage the lifecycle of the logger
96-
// provider on their own. Dropping logger providers will disable log
97-
// emitting.
98-
let logger_provider = init_logs().unwrap();
80+
let logger_provider = init_logs()?;
9981

10082
// Create a new OpenTelemetryTracingBridge using the above LoggerProvider.
101-
let layer = OpenTelemetryTracingBridge::new(&logger_provider);
83+
let otel_layer = OpenTelemetryTracingBridge::new(&logger_provider);
10284

103-
// Add a tracing filter to filter events from crates used by opentelemetry-otlp.
104-
// The filter levels are set as follows:
85+
// For the OpenTelemetry layer, add a tracing filter to filter events from
86+
// OpenTelemetry and its dependent crates (opentelemetry-otlp uses crates
87+
// like reqwest/tonic etc.) from being sent back to OTel itself, thus
88+
// preventing infinite telemetry generation. The filter levels are set as
89+
// follows:
10590
// - Allow `info` level and above by default.
106-
// - Restrict `hyper`, `tonic`, and `reqwest` to `error` level logs only.
107-
// This ensures events generated from these crates within the OTLP Exporter are not looped back,
108-
// thus preventing infinite event generation.
109-
// Note: This will also drop events from these crates used outside the OTLP Exporter.
110-
// For more details, see: https://github.com/open-telemetry/opentelemetry-rust/issues/761
111-
let filter = EnvFilter::new("info")
112-
.add_directive("hyper=error".parse().unwrap())
113-
.add_directive("tonic=error".parse().unwrap())
114-
.add_directive("reqwest=error".parse().unwrap());
115-
91+
// - Restrict `opentelemetry`, `hyper`, `tonic`, and `reqwest` completely.
92+
// Note: This will also drop events from crates like `tonic` etc. even when
93+
// they are used outside the OTLP Exporter. For more details, see:
94+
// https://github.com/open-telemetry/opentelemetry-rust/issues/761
95+
let filter_otel = EnvFilter::new("info")
96+
.add_directive("hyper=off".parse().unwrap())
97+
.add_directive("opentelemetry=off".parse().unwrap())
98+
.add_directive("tonic=off".parse().unwrap())
99+
.add_directive("h2=off".parse().unwrap())
100+
.add_directive("reqwest=off".parse().unwrap());
101+
let otel_layer = otel_layer.with_filter(filter_otel);
102+
103+
// Create a new tracing::Fmt layer to print the logs to stdout. It has a
104+
// default filter of `info` level and above, and `debug` and above for logs
105+
// from OpenTelemtry crates. The filter levels can be customized as needed.
106+
let filter_fmt = EnvFilter::new("info").add_directive("opentelemetry=debug".parse().unwrap());
107+
let fmt_layer = tracing_subscriber::fmt::layer()
108+
.with_thread_names(true)
109+
.with_filter(filter_fmt);
110+
111+
// Initialize the tracing subscriber with the OpenTelemetry layer and the
112+
// Fmt layer.
116113
tracing_subscriber::registry()
117-
.with(filter)
118-
.with(layer)
114+
.with(otel_layer)
115+
.with(fmt_layer)
119116
.init();
120117

121118
let common_scope_attributes = vec![KeyValue::new("scope-key", "scope-value")];

opentelemetry-otlp/examples/basic-otlp/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ tokio = { version = "1.0", features = ["full"] }
1515
opentelemetry-appender-tracing = { path = "../../../opentelemetry-appender-tracing", default-features = false}
1616
tracing = { workspace = true, features = ["std"]}
1717
tracing-core = { workspace = true }
18-
tracing-subscriber = { workspace = true, features = ["env-filter","registry", "std"] }
18+
tracing-subscriber = { workspace = true, features = ["env-filter","registry", "std", "fmt"] }

opentelemetry-otlp/examples/basic-otlp/README.md

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,43 @@
1-
# Basic OTLP exporter Example
2-
3-
This example shows how to setup OpenTelemetry OTLP exporter for logs, metrics
4-
and traces to exports them to the [OpenTelemetry
5-
Collector](https://github.com/open-telemetry/opentelemetry-collector) via OTLP over gRPC.
6-
The Collector then sends the data to the appropriate backend, in this case,
7-
the logging Exporter, which displays data to console.
1+
# Basic OTLP Exporter Example
2+
3+
This example demonstrates how to set up an OpenTelemetry OTLP exporter for logs,
4+
metrics, and traces to send data to the [OpenTelemetry
5+
Collector](https://github.com/open-telemetry/opentelemetry-collector) via OTLP
6+
over gRPC. The Collector then forwards the data to the configured backend, which
7+
in this case is the logging exporter, displaying data on the console.
8+
Additionally, the example configures a `tracing::fmt` layer to output logs
9+
emitted via `tracing` to `stdout`. For demonstration, this layer uses a filter
10+
to display `DEBUG` level logs from various OpenTelemetry components. In real
11+
applications, these filters should be adjusted appropriately.
12+
13+
The example employs a `BatchExporter` for logs and traces, which is the
14+
recommended approach when using OTLP exporters. While it can be modified to use
15+
a `SimpleExporter`, this requires the main method to be a `tokio::main` function
16+
since the `tonic` client requires a Tokio runtime. If you prefer not to use
17+
`tokio::main`, then the `init_logs`, `init_traces`, and `init_metrics` functions
18+
must be executed within a Tokio runtime. Below is an example:
19+
20+
```rust
21+
fn main() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
22+
let rt = tokio::runtime::Runtime::new()?;
23+
let tracer_provider = rt.block_on(async {
24+
init_traces()
25+
})?;
26+
global::set_tracer_provider(tracer_provider.clone());
27+
28+
let meter_provider = rt.block_on(async {
29+
init_metrics()
30+
})?;
31+
global::set_meter_provider(meter_provider.clone());
32+
33+
let logger_provider = rt.block_on(async {
34+
init_logs()
35+
})?;
36+
37+
// Ensure the runtime (`rt`) remains active until the program ends
38+
// Additional code goes here...
39+
}
40+
```
841

942
## Usage
1043

opentelemetry-otlp/examples/basic-otlp/src/main.rs

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ static RESOURCE: Lazy<Resource> = Lazy::new(|| {
2121
)])
2222
});
2323

24-
fn init_tracer_provider() -> Result<sdktrace::TracerProvider, TraceError> {
24+
fn init_traces() -> Result<sdktrace::TracerProvider, TraceError> {
2525
let exporter = SpanExporter::builder()
2626
.with_tonic()
2727
.with_endpoint("http://localhost:4317")
@@ -57,50 +57,48 @@ fn init_logs() -> Result<opentelemetry_sdk::logs::LoggerProvider, LogError> {
5757

5858
#[tokio::main]
5959
async fn main() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
60-
// By binding the result to an unused variable, the lifetime of the variable
61-
// matches the containing block, reporting traces and metrics during the whole
62-
// execution.
63-
64-
let result = init_tracer_provider();
65-
assert!(
66-
result.is_ok(),
67-
"Init tracer failed with error: {:?}",
68-
result.err()
69-
);
70-
let tracer_provider = result.unwrap();
60+
let tracer_provider = init_traces()?;
7161
global::set_tracer_provider(tracer_provider.clone());
7262

73-
let result = init_metrics();
74-
assert!(
75-
result.is_ok(),
76-
"Init metrics failed with error: {:?}",
77-
result.err()
78-
);
79-
let meter_provider = result.unwrap();
63+
let meter_provider = init_metrics()?;
8064
global::set_meter_provider(meter_provider.clone());
8165

82-
// Initialize logs and save the logger_provider.
83-
let logger_provider = init_logs().unwrap();
66+
let logger_provider = init_logs()?;
8467

8568
// Create a new OpenTelemetryTracingBridge using the above LoggerProvider.
86-
let layer = OpenTelemetryTracingBridge::new(&logger_provider);
69+
let otel_layer = OpenTelemetryTracingBridge::new(&logger_provider);
8770

88-
// Add a tracing filter to filter events from crates used by opentelemetry-otlp.
89-
// The filter levels are set as follows:
71+
// For the OpenTelemetry layer, add a tracing filter to filter events from
72+
// OpenTelemetry and its dependent crates (opentelemetry-otlp uses crates
73+
// like reqwest/tonic etc.) from being sent back to OTel itself, thus
74+
// preventing infinite telemetry generation. The filter levels are set as
75+
// follows:
9076
// - Allow `info` level and above by default.
91-
// - Restrict `hyper`, `tonic`, and `reqwest` to `error` level logs only.
92-
// This ensures events generated from these crates within the OTLP Exporter are not looped back,
93-
// thus preventing infinite event generation.
94-
// Note: This will also drop events from these crates used outside the OTLP Exporter.
95-
// For more details, see: https://github.com/open-telemetry/opentelemetry-rust/issues/761
96-
let filter = EnvFilter::new("info")
97-
.add_directive("hyper=error".parse().unwrap())
98-
.add_directive("tonic=error".parse().unwrap())
99-
.add_directive("reqwest=error".parse().unwrap());
100-
77+
// - Restrict `opentelemetry`, `hyper`, `tonic`, and `reqwest` completely.
78+
// Note: This will also drop events from crates like `tonic` etc. even when
79+
// they are used outside the OTLP Exporter. For more details, see:
80+
// https://github.com/open-telemetry/opentelemetry-rust/issues/761
81+
let filter_otel = EnvFilter::new("info")
82+
.add_directive("hyper=off".parse().unwrap())
83+
.add_directive("opentelemetry=off".parse().unwrap())
84+
.add_directive("tonic=off".parse().unwrap())
85+
.add_directive("h2=off".parse().unwrap())
86+
.add_directive("reqwest=off".parse().unwrap());
87+
let otel_layer = otel_layer.with_filter(filter_otel);
88+
89+
// Create a new tracing::Fmt layer to print the logs to stdout. It has a
90+
// default filter of `info` level and above, and `debug` and above for logs
91+
// from OpenTelemtry crates. The filter levels can be customized as needed.
92+
let filter_fmt = EnvFilter::new("info").add_directive("opentelemetry=debug".parse().unwrap());
93+
let fmt_layer = tracing_subscriber::fmt::layer()
94+
.with_thread_names(true)
95+
.with_filter(filter_fmt);
96+
97+
// Initialize the tracing subscriber with the OpenTelemetry layer and the
98+
// Fmt layer.
10199
tracing_subscriber::registry()
102-
.with(filter)
103-
.with(layer)
100+
.with(otel_layer)
101+
.with(fmt_layer)
104102
.init();
105103

106104
let common_scope_attributes = vec![KeyValue::new("scope-key", "scope-value")];

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use super::OtlpHttpClient;
99

1010
#[async_trait]
1111
impl LogExporter for OtlpHttpClient {
12-
async fn export(&mut self, batch: LogBatch<'_>) -> LogResult<()> {
12+
async fn export(&self, batch: LogBatch<'_>) -> LogResult<()> {
1313
let client = self
1414
.client
1515
.lock()

0 commit comments

Comments
 (0)