Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve internal opentelemetry logging #2128

Merged
merged 38 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
7da284e
initial commit
lalitb Sep 18, 2024
573994d
instrument internal code
lalitb Sep 19, 2024
1bfd464
instrument..
lalitb Sep 19, 2024
90470c3
instrument..
lalitb Sep 19, 2024
5f1b990
update example
lalitb Sep 19, 2024
47abb6d
Merge branch 'main' into log-handler-using-tracing
lalitb Sep 19, 2024
46ce8af
update example
lalitb Sep 19, 2024
bbfc03c
Merge branch 'log-handler-using-tracing' of github.com:lalitb/opentel…
lalitb Sep 19, 2024
e5260d9
changes for filtering
lalitb Sep 19, 2024
a79b636
Merge branch 'main' into log-handler-using-tracing
TommyCpp Sep 21, 2024
197b12a
use structured logging
lalitb Sep 23, 2024
91e56ea
review comments
lalitb Sep 27, 2024
fa7148e
update self diagnostic
lalitb Sep 27, 2024
a78357c
allow internal events in pipeline
lalitb Sep 27, 2024
a3fba36
Merge branch 'main' into log-handler-using-tracing
lalitb Sep 27, 2024
54e0755
fix macros
lalitb Oct 1, 2024
4c8cb42
revert appender-tracing example
lalitb Oct 1, 2024
5c4bab9
Merge branch 'main' into log-handler-using-tracing
lalitb Oct 1, 2024
5e95e00
update instrument
lalitb Oct 2, 2024
da3716d
cont..
lalitb Oct 2, 2024
62b9f83
lint fix
lalitb Oct 2, 2024
591c45a
fix macro to dump operation name as name keyt
lalitb Oct 2, 2024
b6e2327
Merge branch 'main' into log-handler-using-tracing
lalitb Oct 2, 2024
2714508
fix unit test for appender-tracing
lalitb Oct 3, 2024
b0c129c
Merge branch 'log-handler-using-tracing' of github.com:lalitb/opentel…
lalitb Oct 3, 2024
83763b1
fix unit tests, and doc test
lalitb Oct 3, 2024
e325316
add macros under feature flag
lalitb Oct 3, 2024
19822b1
make feature default
lalitb Oct 3, 2024
6b98c16
fix build
lalitb Oct 3, 2024
d248750
fix lint
lalitb Oct 3, 2024
f9e3d2d
lint
lalitb Oct 3, 2024
d4c1eb7
use eprintln for warn and error if internal-logs flag is disabled
lalitb Oct 3, 2024
d5120a2
review comments
lalitb Oct 3, 2024
c103467
remove tracing from opentelemetry crate, and use name as metadata
lalitb Oct 3, 2024
b7470b1
fix
lalitb Oct 3, 2024
30f7a4c
remove tracing from otel dev dep
lalitb Oct 3, 2024
adc3fd2
remove debug
lalitb Oct 3, 2024
3c4d20c
Update opentelemetry-sdk/src/metrics/internal/mod.rs
lalitb Oct 3, 2024
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
4 changes: 2 additions & 2 deletions examples/self-diagnostics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ publish = false

[dependencies]
opentelemetry = { path = "../../opentelemetry" }
opentelemetry_sdk = { path = "../../opentelemetry-sdk", features = ["rt-tokio", "experimental-internal-logs"]}
opentelemetry_sdk = { path = "../../opentelemetry-sdk", features = ["rt-tokio"]}
opentelemetry-stdout = { path = "../../opentelemetry-stdout"}
opentelemetry-appender-tracing = { path = "../../opentelemetry-appender-tracing"}
tokio = { workspace = true, features = ["full"] }
tracing = { workspace = true, features = ["std"]}
tracing-core = { workspace = true }
tracing-subscriber = { version = "0.3.18", features = ["env-filter","registry", "std"]}
opentelemetry-otlp = { path = "../../opentelemetry-otlp", features = ["http-proto", "reqwest-client", "logs", "experimental-internal-logs"] }
opentelemetry-otlp = { path = "../../opentelemetry-otlp", features = ["http-proto", "reqwest-client", "logs"] }
once_cell ={ version = "1.19.0"}
ctrlc = "3.4"
1 change: 1 addition & 0 deletions opentelemetry-appender-tracing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ tracing-subscriber = { workspace = true, features = ["registry", "std"] }
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-log = "0.2"
async-trait = { workspace = true }
criterion = { workspace = true }
Expand Down
30 changes: 19 additions & 11 deletions opentelemetry-appender-tracing/src/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,26 @@ mod tests {
use opentelemetry_sdk::trace;
use opentelemetry_sdk::trace::{Sampler, TracerProvider};
use tracing::error;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt;
use tracing_subscriber::Layer;

pub fn attributes_contains(log_record: &LogRecord, key: &Key, value: &AnyValue) -> bool {
log_record
.attributes_iter()
.any(|(k, v)| k == key && v == value)
}

fn create_tracing_subscriber(
_exporter: InMemoryLogsExporter,
logger_provider: &LoggerProvider,
) -> impl tracing::Subscriber {
let level_filter = tracing_subscriber::filter::LevelFilter::WARN; // Capture WARN and ERROR levels
let layer =
layer::OpenTelemetryTracingBridge::new(logger_provider).with_filter(level_filter); // No filter based on target, only based on log level

tracing_subscriber::registry().with(layer)
}

// cargo test --features=testing
#[test]
fn tracing_appender_standalone() {
Expand All @@ -234,8 +246,7 @@ mod tests {
.with_simple_exporter(exporter.clone())
.build();

let layer = layer::OpenTelemetryTracingBridge::new(&logger_provider);
let subscriber = tracing_subscriber::registry().with(layer);
let subscriber = create_tracing_subscriber(exporter.clone(), &logger_provider);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is exporter required to be passed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to remove as part of updating the method. Will cleanup in subsequent PR.


// avoiding setting tracing subscriber as global as that does not
// play well with unit tests.
Expand Down Expand Up @@ -315,8 +326,7 @@ mod tests {
.with_simple_exporter(exporter.clone())
.build();

let layer = layer::OpenTelemetryTracingBridge::new(&logger_provider);
let subscriber = tracing_subscriber::registry().with(layer);
let subscriber = create_tracing_subscriber(exporter.clone(), &logger_provider);

// avoiding setting tracing subscriber as global as that does not
// play well with unit tests.
Expand Down Expand Up @@ -427,16 +437,15 @@ mod tests {
.with_simple_exporter(exporter.clone())
.build();

let layer = layer::OpenTelemetryTracingBridge::new(&logger_provider);
let subscriber = tracing_subscriber::registry().with(layer);
let subscriber = create_tracing_subscriber(exporter.clone(), &logger_provider);

// avoiding setting tracing subscriber as global as that does not
// play well with unit tests.
let _guard = tracing::subscriber::set_default(subscriber);
drop(tracing_log::LogTracer::init());

// Act
log::error!("log from log crate");
log::error!(target: "my-system", "log from log crate");
logger_provider.force_flush();

// Assert TODO: move to helper methods
Expand Down Expand Up @@ -493,8 +502,7 @@ mod tests {
.with_simple_exporter(exporter.clone())
.build();

let layer = layer::OpenTelemetryTracingBridge::new(&logger_provider);
let subscriber = tracing_subscriber::registry().with(layer);
let subscriber = create_tracing_subscriber(exporter.clone(), &logger_provider);

// avoiding setting tracing subscriber as global as that does not
// play well with unit tests.
Expand All @@ -513,7 +521,7 @@ mod tests {
let span_id = cx.span().span_context().span_id();

// logging is done inside span context.
log::error!("log from log crate");
log::error!(target: "my-system", "log from log crate");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need these changes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we can remove the target, will follow up in subsequent cleanups.

(trace_id, span_id)
});

Expand Down
4 changes: 2 additions & 2 deletions opentelemetry-otlp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ trace = ["opentelemetry/trace", "opentelemetry_sdk/trace", "opentelemetry-proto/
metrics = ["opentelemetry/metrics", "opentelemetry_sdk/metrics", "opentelemetry-proto/metrics"]
logs = ["opentelemetry/logs", "opentelemetry_sdk/logs", "opentelemetry-proto/logs"]
populate-logs-event-name = ["opentelemetry-proto/populate-logs-event-name"]
experimental-internal-logs = ["tracing"]
internal-logs = ["tracing"]

# add ons
serialize = ["serde", "serde_json"]

default = ["grpc-tonic", "trace", "metrics", "logs"]
default = ["grpc-tonic", "trace", "metrics", "logs", "internal-logs"]

# grpc using tonic
grpc-tonic = ["tonic", "prost", "http", "tokio", "opentelemetry-proto/gen-tonic"]
Expand Down
14 changes: 6 additions & 8 deletions opentelemetry-otlp/src/metric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use async_trait::async_trait;
use core::fmt;
use opentelemetry::metrics::Result;
use opentelemetry::otel_debug;

#[cfg(feature = "grpc-tonic")]
use crate::exporter::tonic::TonicExporterBuilder;
Expand Down Expand Up @@ -294,22 +295,19 @@
#[async_trait]
impl PushMetricsExporter for MetricsExporter {
async fn export(&self, metrics: &mut ResourceMetrics) -> Result<()> {
#[cfg(feature = "experimental-internal-logs")]
tracing::debug!(
name = "export_metrics",
target = "opentelemetry-otlp",
otel_debug!(

Check warning on line 298 in opentelemetry-otlp/src/metric.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/metric.rs#L298

Added line #L298 was not covered by tests
name: "export_metrics",
metrics_count = metrics
.scope_metrics
.iter()
.map(|scope| scope.metrics.len())
.sum::<usize>(),
status = "started"
);
#[allow(clippy::let_and_return)] // for scenario where internal logs is disabled
let result = self.client.export(metrics).await;
#[cfg(feature = "experimental-internal-logs")]
tracing::debug!(
name = "export_metrics",
target = "opentelemetry-otlp",
otel_debug!(

Check warning on line 309 in opentelemetry-otlp/src/metric.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/metric.rs#L309

Added line #L309 was not covered by tests
name: "export_metrics",
status = if result.is_ok() {
"completed"
} else {
Expand Down
4 changes: 2 additions & 2 deletions opentelemetry-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ temp-env = { workspace = true }
pprof = { version = "0.13", features = ["flamegraph", "criterion"] }

[features]
default = ["trace", "metrics", "logs"]
default = ["trace", "metrics", "logs", "internal-logs"]
trace = ["opentelemetry/trace", "rand", "async-trait", "percent-encoding"]
jaeger_remote_sampler = ["trace", "opentelemetry-http", "http", "serde", "serde_json", "url"]
logs = ["opentelemetry/logs", "async-trait", "serde_json"]
Expand All @@ -52,7 +52,7 @@ testing = ["opentelemetry/testing", "trace", "metrics", "logs", "rt-async-std",
rt-tokio = ["tokio", "tokio-stream"]
rt-tokio-current-thread = ["tokio", "tokio-stream"]
rt-async-std = ["async-std"]
experimental-internal-logs = ["tracing"]
internal-logs = ["tracing"]

[[bench]]
name = "context"
Expand Down
52 changes: 52 additions & 0 deletions opentelemetry-sdk/src/logs/log_emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
trace::TraceContextExt,
Context, InstrumentationLibrary,
};
use opentelemetry::{otel_debug, otel_info, otel_warn};

#[cfg(feature = "logs_level_enabled")]
use opentelemetry::logs::Severity;
Expand Down Expand Up @@ -49,6 +50,12 @@
attributes: Option<Vec<opentelemetry::KeyValue>>,
) -> Logger {
let name = name.into();
otel_info!(
name: "logger_versioned_creation",
instr_lib_name= &*name,
version = version.as_deref(),
schema_url = schema_url.as_deref(),

Check warning on line 57 in opentelemetry-sdk/src/logs/log_emitter.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-sdk/src/logs/log_emitter.rs#L55-L57

Added lines #L55 - L57 were not covered by tests
);

let component_name = if name.is_empty() {
Cow::Borrowed(DEFAULT_COMPONENT_NAME)
Expand All @@ -72,6 +79,9 @@
}

fn library_logger(&self, library: Arc<InstrumentationLibrary>) -> Self::Logger {
otel_info!(
name: "logger_library_logger_creation"
);
// If the provider is shutdown, new logger will refer a no-op logger provider.
if self.is_shutdown.load(Ordering::Relaxed) {
return Logger::new(library, NOOP_LOGGER_PROVIDER.clone());
Expand All @@ -83,19 +93,33 @@
impl LoggerProvider {
/// Create a new `LoggerProvider` builder.
pub fn builder() -> Builder {
otel_info!(
name: "logger_provider_builder"
);
Builder::default()
}

pub(crate) fn log_processors(&self) -> &[Box<dyn LogProcessor>] {
otel_debug!(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be good enough to get the processor count information just once during LoggerProvider build. Is there any value in repeatedly logging it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to unblock and merge this PR quickly, I think its best to remove all internal logging that are not error/warning, and we can selective bring them one by one in future PRs.

name: "logger_provider_log_processors",
processor_count= self.inner.processors.len()

Check warning on line 105 in opentelemetry-sdk/src/logs/log_emitter.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-sdk/src/logs/log_emitter.rs#L105

Added line #L105 was not covered by tests
);
&self.inner.processors
}

pub(crate) fn resource(&self) -> &Resource {
otel_debug!(
name: "logger_provider_resource",
resource_count= self.inner.resource.len()

Check warning on line 113 in opentelemetry-sdk/src/logs/log_emitter.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-sdk/src/logs/log_emitter.rs#L113

Added line #L113 was not covered by tests
);
&self.inner.resource
}

/// Force flush all remaining logs in log processors and return results.
pub fn force_flush(&self) -> Vec<LogResult<()>> {
otel_info!(
cijothomas marked this conversation as resolved.
Show resolved Hide resolved
name: "logger_provider_force_flush"
);
self.log_processors()
.iter()
.map(|processor| processor.force_flush())
Expand All @@ -104,6 +128,9 @@

/// Shuts down this `LoggerProvider`
pub fn shutdown(&self) -> LogResult<()> {
otel_info!(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be logged only in case of a successful shutdown? Only in this case:

if errs.is_empty() {
    Ok(())
}

name: "logger_provider_shutdown"
);
if self
.is_shutdown
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
Expand All @@ -114,6 +141,10 @@
let mut errs = vec![];
for processor in &self.inner.processors {
if let Err(err) = processor.shutdown() {
otel_warn!(

Check warning on line 144 in opentelemetry-sdk/src/logs/log_emitter.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-sdk/src/logs/log_emitter.rs#L144

Added line #L144 was not covered by tests
name: "logger_provider_shutdown_error",
error = format!("{:?}", err)

Check warning on line 146 in opentelemetry-sdk/src/logs/log_emitter.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-sdk/src/logs/log_emitter.rs#L146

Added line #L146 was not covered by tests
);
errs.push(err);
}
}
Expand All @@ -124,6 +155,9 @@
Err(LogError::Other(format!("{errs:?}").into()))
}
} else {
otel_warn!(
name: "logger_provider_already_shutdown"
);
Err(LogError::Other("logger provider already shut down".into()))
}
}
Expand Down Expand Up @@ -203,6 +237,11 @@
for processor in logger_provider.log_processors() {
processor.set_resource(logger_provider.resource());
}
otel_debug!(
name: "logger_provider_build",
resource_count = logger_provider.resource().len(),
processor_count = logger_provider.log_processors().len()

Check warning on line 243 in opentelemetry-sdk/src/logs/log_emitter.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-sdk/src/logs/log_emitter.rs#L242-L243

Added lines #L242 - L243 were not covered by tests
);
logger_provider
}
}
Expand All @@ -221,6 +260,9 @@
instrumentation_lib: Arc<InstrumentationLibrary>,
provider: LoggerProvider,
) -> Self {
otel_info!(
name: "logger_new"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably add some identification information for the logger such as name, version etc.

);
Logger {
instrumentation_lib,
provider,
Expand All @@ -247,6 +289,10 @@

/// Emit a `LogRecord`.
fn emit(&self, mut record: Self::LogRecord) {
otel_debug!(
name: "log_record_emit_start",
record = format!("{:?}", record)

Check warning on line 294 in opentelemetry-sdk/src/logs/log_emitter.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-sdk/src/logs/log_emitter.rs#L294

Added line #L294 was not covered by tests
);
let provider = self.provider();
let processors = provider.log_processors();
let trace_context = Context::map_current(|cx| {
Expand Down Expand Up @@ -280,6 +326,12 @@
self.instrumentation_library().name.as_ref(),
);
}
otel_debug!(
name: "log_record_event_enabled_check",
enabled_status = enabled,
level = level.name(),

Check warning on line 332 in opentelemetry-sdk/src/logs/log_emitter.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-sdk/src/logs/log_emitter.rs#L332

Added line #L332 was not covered by tests
log_target = target
);
enabled
}
}
Expand Down
Loading
Loading