Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/logs-basic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ opentelemetry_sdk = { path = "../../opentelemetry-sdk", features = ["logs"] }
opentelemetry-stdout = { path = "../../opentelemetry-stdout", features = ["logs"]}
opentelemetry-appender-tracing = { path = "../../opentelemetry-appender-tracing", default-features = false}
tracing = { workspace = true, features = ["std"]}
tracing-subscriber = { workspace = true, features = ["registry", "std"] }
tracing-subscriber = { workspace = true, features = ["env-filter","registry", "std", "fmt"] }
35 changes: 32 additions & 3 deletions examples/logs-basic/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use opentelemetry_appender_tracing::layer;
use opentelemetry_sdk::logs::SdkLoggerProvider;
use opentelemetry_sdk::Resource;
use tracing::error;
use tracing_subscriber::prelude::*;
use tracing_subscriber::{prelude::*, EnvFilter};

fn main() {
let exporter = opentelemetry_stdout::LogExporter::default();
Expand All @@ -14,8 +14,37 @@ fn main() {
)
.with_simple_exporter(exporter)
.build();
let layer = layer::OpenTelemetryTracingBridge::new(&provider);
tracing_subscriber::registry().with(layer).init();

// For the OpenTelemetry layer, add a tracing filter to filter events from
// OpenTelemetry and its dependent crates (opentelemetry-otlp uses crates
// like reqwest/tonic etc.) from being sent back to OTel itself, thus
// preventing infinite telemetry generation. The filter levels are set as
// follows:
// - Allow `info` level and above by default.
// - Restrict `opentelemetry`, `hyper`, `tonic`, and `reqwest` completely.
// Note: This will also drop events from crates like `tonic` etc. even when
// they are used outside the OTLP Exporter. For more details, see:
// https://github.com/open-telemetry/opentelemetry-rust/issues/761
let filter_otel = EnvFilter::new("info")
.add_directive("hyper=off".parse().unwrap())
.add_directive("opentelemetry=off".parse().unwrap())
.add_directive("tonic=off".parse().unwrap())
.add_directive("h2=off".parse().unwrap())
.add_directive("reqwest=off".parse().unwrap());
let otel_layer = layer::OpenTelemetryTracingBridge::new(&provider).with_filter(filter_otel);

// Create a new tracing::Fmt layer to print the logs to stdout. It has a
// default filter of `info` level and above, and `debug` and above for logs
// from OpenTelemetry crates. The filter levels can be customized as needed.
let filter_fmt = EnvFilter::new("info").add_directive("opentelemetry=debug".parse().unwrap());
let fmt_layer = tracing_subscriber::fmt::layer()
.with_thread_names(true)
.with_filter(filter_fmt);

tracing_subscriber::registry()
.with(otel_layer)
.with(fmt_layer)
.init();

error!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "[email protected]", message = "This is an example message");
let _ = provider.shutdown();
Expand Down
2 changes: 1 addition & 1 deletion examples/tracing-grpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ opentelemetry_sdk = { path = "../../opentelemetry-sdk", features = ["rt-tokio"]
opentelemetry-stdout = { path = "../../opentelemetry-stdout", features = ["trace"] }
prost = { workspace = true }
tokio = { workspace = true, features = ["full"] }
tonic = { workspace = true }
tonic = { workspace = true, features = ["server"] }

[build-dependencies]
tonic-build = { workspace = true }
6 changes: 4 additions & 2 deletions examples/tracing-jaeger/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use opentelemetry::{
global,
trace::{TraceContextExt, TraceError, Tracer},
trace::{TraceContextExt, Tracer},
KeyValue,
};
use opentelemetry_otlp::ExporterBuildError;
use opentelemetry_sdk::trace::SdkTracerProvider;
use opentelemetry_sdk::Resource;

use std::error::Error;

fn init_tracer_provider() -> Result<opentelemetry_sdk::trace::SdkTracerProvider, TraceError> {
fn init_tracer_provider() -> Result<opentelemetry_sdk::trace::SdkTracerProvider, ExporterBuildError>
{
let exporter = opentelemetry_otlp::SpanExporter::builder()
.with_tonic()
.build()?;
Expand Down
10 changes: 6 additions & 4 deletions opentelemetry-appender-tracing/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

## vNext

Fixes [1682](https://github.com/open-telemetry/opentelemetry-rust/issues/1682).
"spec_unstable_logs_enabled" feature now do not suppress logs for other layers.

## 0.28.1

Released 2025-Feb-12

- Bump `tracing-opentelemetry` to 0.29
- New experimental feature to use trace\_id & span\_id from spans created through the [tracing](https://crates.io/crates/tracing) crate (experimental_use_tracing_span_context) [#2438](https://github.com/open-telemetry/opentelemetry-rust/pull/2438)

- New *experimental* feature to use trace_id & span_id from spans created through the [tracing](https://crates.io/crates/tracing) crate (experimental_use_tracing_span_context) [#2438](https://github.com/open-telemetry/opentelemetry-rust/pull/2438)

## 0.28.0

Expand All @@ -27,6 +28,7 @@ Released 2024-Nov-11
- **Breaking** [2291](https://github.com/open-telemetry/opentelemetry-rust/pull/2291) Rename `logs_level_enabled flag` to `spec_unstable_logs_enabled`. Please enable this updated flag if the feature is needed. This flag will be removed once the feature is stabilized in the specifications.

## v0.26.0

Released 2024-Sep-30

- Update `opentelemetry` dependency version to 0.26
Expand All @@ -45,7 +47,7 @@ Released 2024-Sep-30
Exporters might use the target to override the instrumentation scope, which previously contained "opentelemetry-appender-tracing".

- **Breaking** [1928](https://github.com/open-telemetry/opentelemetry-rust/pull/1928) Insert tracing event name into LogRecord::event_name instead of attributes.
- If using a custom exporter, then they must serialize this field directly from LogRecord::event_name instead of iterating over the attributes. OTLP Exporter is modified to handle this.
- If using a custom exporter, then they must serialize this field directly from LogRecord::event_name instead of iterating over the attributes. OTLP Exporter is modified to handle this.
- Update `opentelemetry` dependency version to 0.24

## v0.4.0
Expand Down
4 changes: 2 additions & 2 deletions opentelemetry-appender-tracing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ tracing-opentelemetry = { version = "0.29", optional = true }
log = { workspace = true }
opentelemetry-stdout = { path = "../opentelemetry-stdout", features = ["logs"] }
opentelemetry_sdk = { path = "../opentelemetry-sdk", features = ["logs", "testing"] }
tracing-subscriber = { workspace = true, features = ["registry", "std", "env-filter"] }
tracing = { workspace = true, features = ["std"]}
tracing-subscriber = { workspace = true, features = ["env-filter","registry", "std", "fmt"] }
tracing-log = "0.2"
criterion = { workspace = true }
tokio = { workspace = true, features = ["full"]}
Expand All @@ -35,7 +36,6 @@ pprof = { version = "0.14", features = ["flamegraph", "criterion"] }
default = []
experimental_metadata_attributes = ["dep:tracing-log"]
spec_unstable_logs_enabled = ["opentelemetry/spec_unstable_logs_enabled"]
# TODO - Enable this in 0.28.1 (once tracing-opentelemetry v0.29 is released)
experimental_use_tracing_span_context = ["tracing-opentelemetry"]


Expand Down
47 changes: 12 additions & 35 deletions opentelemetry-appender-tracing/benches/logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use criterion::{criterion_group, criterion_main, Criterion};
use opentelemetry::InstrumentationScope;
use opentelemetry_appender_tracing::layer as tracing_layer;
use opentelemetry_sdk::error::OTelSdkResult;
use opentelemetry_sdk::logs::{LogBatch, LogExporter};
use opentelemetry_sdk::logs::{LogProcessor, SdkLogRecord, SdkLoggerProvider};
use opentelemetry_sdk::Resource;
#[cfg(not(target_os = "windows"))]
Expand All @@ -27,40 +26,19 @@ use tracing_subscriber::prelude::*;
use tracing_subscriber::Layer;
use tracing_subscriber::Registry;

#[derive(Debug, Clone)]
struct NoopExporter {
enabled: bool,
}

impl LogExporter for NoopExporter {
#[allow(clippy::manual_async_fn)]
fn export(
&self,
_batch: LogBatch<'_>,
) -> impl std::future::Future<Output = OTelSdkResult> + Send {
async { OTelSdkResult::Ok(()) }
}

fn event_enabled(&self, _: opentelemetry::logs::Severity, _: &str, _: &str) -> bool {
self.enabled
}
}

#[derive(Debug)]
struct NoopProcessor<E: LogExporter> {
exporter: E,
struct NoopProcessor {
enabled: bool,
}

impl<E: LogExporter> NoopProcessor<E> {
fn new(exporter: E) -> Self {
Self { exporter }
impl NoopProcessor {
fn new(enabled: bool) -> Self {
Self { enabled }
}
}

impl<E: LogExporter> LogProcessor for NoopProcessor<E> {
fn emit(&self, _: &mut SdkLogRecord, _: &InstrumentationScope) {
// no-op
}
impl LogProcessor for NoopProcessor {
fn emit(&self, _: &mut SdkLogRecord, _: &InstrumentationScope) {}

fn force_flush(&self) -> OTelSdkResult {
Ok(())
Expand All @@ -72,11 +50,11 @@ impl<E: LogExporter> LogProcessor for NoopProcessor<E> {

fn event_enabled(
&self,
level: opentelemetry::logs::Severity,
target: &str,
name: &str,
_level: opentelemetry::logs::Severity,
_target: &str,
_name: &str,
) -> bool {
self.exporter.event_enabled(level, target, name)
self.enabled
}
}

Expand Down Expand Up @@ -126,8 +104,7 @@ fn benchmark_no_subscriber(c: &mut Criterion) {
}

fn benchmark_with_ot_layer(c: &mut Criterion, enabled: bool, bench_name: &str) {
let exporter = NoopExporter { enabled };
let processor = NoopProcessor::new(exporter);
let processor = NoopProcessor::new(enabled);
let provider = SdkLoggerProvider::builder()
.with_resource(
Resource::builder_empty()
Expand Down
35 changes: 32 additions & 3 deletions opentelemetry-appender-tracing/examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use opentelemetry_appender_tracing::layer;
use opentelemetry_sdk::{logs::SdkLoggerProvider, Resource};
use tracing::error;
use tracing_subscriber::prelude::*;
use tracing_subscriber::{prelude::*, EnvFilter};

fn main() {
let exporter = opentelemetry_stdout::LogExporter::default();
Expand All @@ -15,8 +15,37 @@ fn main() {
)
.with_simple_exporter(exporter)
.build();
let layer = layer::OpenTelemetryTracingBridge::new(&provider);
tracing_subscriber::registry().with(layer).init();

// For the OpenTelemetry layer, add a tracing filter to filter events from
// OpenTelemetry and its dependent crates (opentelemetry-otlp uses crates
// like reqwest/tonic etc.) from being sent back to OTel itself, thus
// preventing infinite telemetry generation. The filter levels are set as
// follows:
// - Allow `info` level and above by default.
// - Restrict `opentelemetry`, `hyper`, `tonic`, and `reqwest` completely.
// Note: This will also drop events from crates like `tonic` etc. even when
// they are used outside the OTLP Exporter. For more details, see:
// https://github.com/open-telemetry/opentelemetry-rust/issues/761
let filter_otel = EnvFilter::new("info")
.add_directive("hyper=off".parse().unwrap())
.add_directive("opentelemetry=off".parse().unwrap())
.add_directive("tonic=off".parse().unwrap())
.add_directive("h2=off".parse().unwrap())
.add_directive("reqwest=off".parse().unwrap());
let otel_layer = layer::OpenTelemetryTracingBridge::new(&provider).with_filter(filter_otel);

// Create a new tracing::Fmt layer to print the logs to stdout. It has a
// default filter of `info` level and above, and `debug` and above for logs
// from OpenTelemetry crates. The filter levels can be customized as needed.
let filter_fmt = EnvFilter::new("info").add_directive("opentelemetry=debug".parse().unwrap());
let fmt_layer = tracing_subscriber::fmt::layer()
.with_thread_names(true)
.with_filter(filter_fmt);

tracing_subscriber::registry()
.with(otel_layer)
.with(fmt_layer)
.init();

error!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "[email protected]", message = "This is an example message");
let _ = provider.shutdown();
Expand Down
39 changes: 15 additions & 24 deletions opentelemetry-appender-tracing/src/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ where
event: &tracing::Event<'_>,
_ctx: tracing_subscriber::layer::Context<'_, S>,
) {
let severity = severity_of_level(event.metadata().level());
let target = event.metadata().target();
#[cfg(feature = "spec_unstable_logs_enabled")]
if !self.logger.event_enabled(severity, target) {
// TODO: See if we need internal logs or track the count.
return;
}

#[cfg(feature = "experimental_metadata_attributes")]
let normalized_meta = event.normalized_metadata();

Expand All @@ -170,9 +178,9 @@ where
let mut log_record = self.logger.create_log_record();

// TODO: Fix heap allocation
log_record.set_target(meta.target().to_string());
log_record.set_target(target.to_string());
log_record.set_event_name(meta.name());
log_record.set_severity_number(severity_of_level(meta.level()));
log_record.set_severity_number(severity);
log_record.set_severity_text(meta.level().as_str());
let mut visitor = EventVisitor::new(&mut log_record);
#[cfg(feature = "experimental_metadata_attributes")]
Expand Down Expand Up @@ -203,17 +211,6 @@ where
//emit record
self.logger.emit(log_record);
}

#[cfg(feature = "spec_unstable_logs_enabled")]
fn event_enabled(
&self,
_event: &tracing_core::Event<'_>,
_ctx: tracing_subscriber::layer::Context<'_, S>,
) -> bool {
let severity = severity_of_level(_event.metadata().level());
self.logger
.event_enabled(severity, _event.metadata().target())
}
}

const fn severity_of_level(level: &Level) -> Severity {
Expand Down Expand Up @@ -266,17 +263,11 @@ mod tests {
struct ReentrantLogExporter;

impl LogExporter for ReentrantLogExporter {
#[allow(clippy::manual_async_fn)]
fn export(
&self,
_batch: LogBatch<'_>,
) -> impl std::future::Future<Output = OTelSdkResult> + Send {
async {
// This will cause a deadlock as the export itself creates a log
// while still within the lock of the SimpleLogProcessor.
warn!(name: "my-event-name", target: "reentrant", event_id = 20, user_name = "otel", user_email = "[email protected]");
Ok(())
}
async fn export(&self, _batch: LogBatch<'_>) -> OTelSdkResult {
// This will cause a deadlock as the export itself creates a log
// while still within the lock of the SimpleLogProcessor.
warn!(name: "my-event-name", target: "reentrant", event_id = 20, user_name = "otel", user_email = "[email protected]");
Ok(())
}
}

Expand Down
13 changes: 13 additions & 0 deletions opentelemetry-otlp/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

## vNext

- The `OTEL_EXPORTER_OTLP_TIMEOUT`, `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT`, `OTEL_EXPORTER_OTLP_METRICS_TIMEOUT` and `OTEL_EXPORTER_OTLP_LOGS_TIMEOUT` are changed from seconds to miliseconds.

- *Breaking*

ExporterBuilder's build() method now Result with `ExporterBuildError` being the
Error variant. Previously it returned signal specific errors like `LogError`
from the `opentelemetry_sdk`, which are no longer part of the sdk. No changes
required if you were using unwrap/expect. If you were matching on the returning
Error enum, replace with the enum `ExporterBuildError`. Unlike the previous
`Error` which contained many variants unrelated to building an exporter, the
new one returns specific variants applicable to building an exporter. Some
variants might be applicable only on select features.

## 0.28.0

Released 2025-Feb-10
Expand Down
2 changes: 1 addition & 1 deletion opentelemetry-otlp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[dependencies]
async-trait = { workspace = true }
futures-core = { workspace = true }
opentelemetry = { version = "0.28", default-features = false, path = "../opentelemetry" }
opentelemetry_sdk = { version = "0.28", default-features = false, path = "../opentelemetry-sdk" }
Expand All @@ -51,6 +50,7 @@ opentelemetry_sdk = { features = ["trace", "rt-tokio", "testing"], path = "../op
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
futures-util = { workspace = true }
temp-env = { workspace = true }
tonic = { workspace = true, features = ["server"] }

[features]
# telemetry pillars and functions
Expand Down
Loading