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

Export logs only if the level/logger/target is enabled. #1147

Merged
merged 19 commits into from
Jul 29, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
5 changes: 5 additions & 0 deletions opentelemetry-api/src/global/logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ impl Logger for BoxedLogger {
fn emit(&self, record: crate::logs::LogRecord) {
self.0.emit(record)
}

#[cfg(feature = "logs_level_enabled")]
fn event_enabled(&self, level: crate::logs::Severity) -> bool {
self.0.event_enabled(level)
}
}

#[derive(Clone)]
Expand Down
7 changes: 7 additions & 0 deletions opentelemetry-api/src/logs/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ use std::borrow::Cow;

use crate::{logs::LogRecord, KeyValue};

#[cfg(feature = "logs_level_enabled")]
use super::Severity;

/// The interface for emitting [`LogRecord`]s.

pub trait Logger {
/// Emit a [`LogRecord`]. If this `Logger` was created with
/// `include_trace_context` set to `true`, the logger will set the record's
Expand All @@ -12,6 +16,9 @@ pub trait Logger {
/// [`Context`]: crate::Context
/// [`TraceContext`]: crate::logs::TraceContext
fn emit(&self, record: LogRecord);

#[cfg(feature = "logs_level_enabled")]
fn event_enabled(&self, level: Severity) -> bool;
}

/// Interfaces that can create [`Logger`] instances.
Expand Down
4 changes: 4 additions & 0 deletions opentelemetry-api/src/logs/noop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,8 @@ pub struct NoopLogger(());

impl Logger for NoopLogger {
fn emit(&self, _record: LogRecord) {}
#[cfg(feature = "logs_level_enabled")]
fn event_enabled(&self, _level: super::Severity) -> bool {
true
}
}
2 changes: 1 addition & 1 deletion opentelemetry-appender-tracing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ tracing-subscriber = { version = "0.3.0", default-features = false, features = [
once_cell = "1.13.0"

[dev-dependencies]
opentelemetry-stdout = { path = "../opentelemetry-stdout", features = ["logs"] }
opentelemetry-stdout = { path = "../opentelemetry-stdout", features = ["logs"] }
7 changes: 6 additions & 1 deletion opentelemetry-sdk/src/export/logs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use crate::Resource;
use async_trait::async_trait;
use opentelemetry_api::{
logs::{LogError, LogRecord, LogResult},
logs::{LogError, LogRecord, LogResult, Severity},
InstrumentationLibrary,
};
use std::{borrow::Cow, fmt::Debug};
Expand All @@ -14,6 +14,11 @@ pub trait LogExporter: Send + Debug {
async fn export(&mut self, batch: Vec<LogData>) -> LogResult<()>;
/// Shuts down the expoter.
fn shutdown(&mut self) {}
#[cfg(feature = "logs_level_enabled")]
/// Chek if logs are enabled.
fn event_enabled(&self, _name: &str, _level: Severity) -> bool {
true
}
}

/// `LogData` associates a [`LogRecord`] with a [`Resource`] and
Expand Down
19 changes: 19 additions & 0 deletions opentelemetry-sdk/src/logs/log_emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ use opentelemetry_api::{
trace::TraceContextExt,
Context, InstrumentationLibrary,
};

#[cfg(feature = "logs_level_enabled")]
use opentelemetry_api::logs::Severity;

use std::{
borrow::Cow,
sync::{Arc, Weak},
Expand Down Expand Up @@ -228,4 +232,19 @@ impl opentelemetry_api::logs::Logger for Logger {
processor.emit(data);
}
}

#[cfg(feature = "logs_level_enabled")]
fn event_enabled(&self, level: Severity) -> bool {
let provider = match self.provider() {
Some(provider) => provider,
None => return false,
};

let mut enabled = false;
for processor in provider.log_processors() {
enabled =
enabled || processor.event_enabled(self.instrumentation_lib.name.as_ref(), level)
}
enabled
}
}
16 changes: 15 additions & 1 deletion opentelemetry-sdk/src/logs/log_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use futures_util::{
future::{self, Either},
{pin_mut, stream, StreamExt as _},
};
#[cfg(feature = "logs_level_enabled")]
use opentelemetry_api::logs::Severity;
use opentelemetry_api::{
global,
logs::{LogError, LogResult},
Expand All @@ -27,6 +29,9 @@ pub trait LogProcessor: Send + Sync + Debug {
fn force_flush(&self) -> LogResult<()>;
/// Shuts down the processor.
fn shutdown(&mut self) -> LogResult<()>;
#[cfg(feature = "logs_level_enabled")]
/// Check if logging is enabled
fn event_enabled(&self, name: &str, level: Severity) -> bool;
}

/// A [`LogProcessor`] that exports synchronously when logs are emitted.
Expand Down Expand Up @@ -93,9 +98,13 @@ impl LogProcessor for SimpleLogProcessor {
)))
}
}

Ok(())
}

#[cfg(feature = "logs_level_enabled")]
fn event_enabled(&self, _name: &str, _level: Severity) -> bool {
true
}
}

/// A [`LogProcessor`] that asynchronously buffers log records and reports
Expand All @@ -121,6 +130,11 @@ impl<R: RuntimeChannel<BatchMessage>> LogProcessor for BatchLogProcessor<R> {
}
}

#[cfg(feature = "logs_level_enabled")]
fn event_enabled(&self, _name: &str, _level: Severity) -> bool {
true
}

fn force_flush(&self) -> LogResult<()> {
let (res_sender, res_receiver) = oneshot::channel();
self.message_sender
Expand Down
5 changes: 3 additions & 2 deletions opentelemetry-user-events-logs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ name = "opentelemetry-user-events-logs"
description = "OpenTelemetry-Rust exporter to userevents"
version = "0.1.0"
edition = "2021"
homepage = "https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-user-events-logs"
repository = "https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-user-events-logs"
homepage = "https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-userevents-exporter"
repository = "https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-userevents-exporter"
readme = "README.md"
rust-version = "1.68.0"
keywords = ["opentelemetry", "log", "trace", "user_events"]
Expand All @@ -24,4 +24,5 @@ opentelemetry-appender-tracing = { path = "../opentelemetry-appender-tracing" }
tracing = { version = "0.1.37", default-features = false, features = ["std"] }
tracing-core = "0.1.31"
tracing-subscriber = { version = "0.3.0", default-features = false, features = ["registry", "std"] }
microbench = "0.5.0"

143 changes: 88 additions & 55 deletions opentelemetry-user-events-logs/src/logs/exporter.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use async_trait::async_trait;
use eventheader::{FieldFormat, Level, Opcode};
use eventheader_dynamic::EventBuilder;
use opentelemetry_sdk::export;
use std::borrow::Cow;
use std::collections::HashMap;
use std::fmt::Debug;
use std::sync::Arc;

Expand All @@ -17,18 +19,38 @@ thread_local! { static EBW: RefCell<EventBuilder> = RefCell::new(EventBuilder::n
#[derive(Debug)]
pub struct ExporterConfig {
/// keyword associated with user_events name
pub keyword: u64,
pub keywords_map: HashMap<String, u64>,
pub default_keyword: u64,
}

impl Default for ExporterConfig {
fn default() -> Self {
ExporterConfig { keyword: 1 }
ExporterConfig {
keywords_map: HashMap::new(),
default_keyword: 1,
}
}
}

impl ExporterConfig {
pub(crate) fn get_log_event_keyword(&self) -> u64 {
self.keyword
pub(crate) fn get_log_keyword(&self, name: &str) -> Option<u64> {
match self.keywords_map.get(name) {
Some(value) => Some(*value),
_ => None,
}
}

pub(crate) fn get_log_keywork_or_default(&self, name: &str) -> Option<u64> {
lalitb marked this conversation as resolved.
Show resolved Hide resolved
let mut keyword = None;
if self.keywords_map.len() == 0 {
keyword = Some(self.default_keyword);
} else {
keyword = match self.get_log_keyword(name) {
Some(x) => Some(x),
_ => None,
}
}
keyword
}
}

Expand All @@ -51,59 +73,36 @@ impl UserEventsExporter {
options = *options.group_name(provider_name);
let mut eventheader_provider: eventheader_dynamic::Provider =
eventheader_dynamic::Provider::new(provider_name, &options);
eventheader_provider.register_set(
eventheader::Level::Informational,
exporter_config.get_log_event_keyword(),
);
eventheader_provider.register_set(
eventheader::Level::Verbose,
exporter_config.get_log_event_keyword(),
);
eventheader_provider.register_set(
eventheader::Level::Warning,
exporter_config.get_log_event_keyword(),
);
eventheader_provider.register_set(
eventheader::Level::Error,
exporter_config.get_log_event_keyword(),
);
eventheader_provider.register_set(
eventheader::Level::CriticalError,
exporter_config.get_log_event_keyword(),
);

eventheader_provider.create_unregistered(
true,
eventheader::Level::Informational,
exporter_config.get_log_event_keyword(),
);
eventheader_provider.create_unregistered(
true,
eventheader::Level::Verbose,
exporter_config.get_log_event_keyword(),
);
eventheader_provider.create_unregistered(
true,
eventheader::Level::Warning,
exporter_config.get_log_event_keyword(),
);
eventheader_provider.create_unregistered(
true,
eventheader::Level::Error,
exporter_config.get_log_event_keyword(),
);
eventheader_provider.create_unregistered(
true,
eventheader::Level::CriticalError,
exporter_config.get_log_event_keyword(),
);

if exporter_config.keywords_map.len() == 0 {
println!(
lalitb marked this conversation as resolved.
Show resolved Hide resolved
"Register default keyworkd {}",
lalitb marked this conversation as resolved.
Show resolved Hide resolved
exporter_config.default_keyword
);
Self::register_events(&mut eventheader_provider, exporter_config.default_keyword)
}
for keyword in exporter_config.keywords_map.values().into_iter() {
Self::register_events(&mut eventheader_provider, *keyword)
}
UserEventsExporter {
provider: Arc::new(eventheader_provider),
exporter_config,
}
}

fn register_events(eventheader_provider: &mut eventheader_dynamic::Provider, keyword: u64) {
eventheader_provider.register_set(eventheader::Level::Informational, keyword);
eventheader_provider.register_set(eventheader::Level::Verbose, keyword);
eventheader_provider.register_set(eventheader::Level::Warning, keyword);
eventheader_provider.register_set(eventheader::Level::Error, keyword);
eventheader_provider.register_set(eventheader::Level::CriticalError, keyword);

eventheader_provider.create_unregistered(true, eventheader::Level::Informational, keyword);
eventheader_provider.create_unregistered(true, eventheader::Level::Verbose, keyword);
eventheader_provider.create_unregistered(true, eventheader::Level::Warning, keyword);
eventheader_provider.create_unregistered(true, eventheader::Level::Error, keyword);
eventheader_provider.create_unregistered(true, eventheader::Level::CriticalError, keyword);
lalitb marked this conversation as resolved.
Show resolved Hide resolved
}

fn add_attributes_to_event(
&self,
eb: &mut EventBuilder,
Expand Down Expand Up @@ -180,10 +179,19 @@ impl UserEventsExporter {
if log_data.record.severity_number.is_some() {
level = self.get_serverity_level(log_data.record.severity_number.unwrap());
}
let log_es = if let Some(es) = self.provider.find_set(
level.as_int().into(),
self.exporter_config.get_log_event_keyword(),
) {

let keyword = self
.exporter_config
.get_log_keywork_or_default(log_data.instrumentation.name.as_ref());

if keyword == None {
return Ok(());
}

let log_es = if let Some(es) = self
.provider
.find_set(level.as_int().into(), keyword.unwrap())
{
es
} else {
return Ok(());
Expand Down Expand Up @@ -342,4 +350,29 @@ impl opentelemetry_sdk::export::logs::LogExporter for UserEventsExporter {
}
Ok(())
}

fn event_enabled(&self, name: &str, level: Severity) -> bool {
//print!("LALIT:event-enabled check for {} and {:?}", name, level);

let (found, keyword) = if self.exporter_config.keywords_map.len() == 0 {
(true, self.exporter_config.default_keyword)
} else {
match self.exporter_config.get_log_keyword(name) {
Some(x) => (true, x),
_ => (false, 0),
}
};
if !found {
return false;
}

let es = self
.provider
.find_set(self.get_serverity_level(level), keyword);
lalitb marked this conversation as resolved.
Show resolved Hide resolved
match es {
Some(x) => x.enabled(),
_ => false,
};
false
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fmt::Debug;

use opentelemetry_api::logs::LogResult;
use opentelemetry_sdk::export::logs::LogData;
use opentelemetry_sdk::export::logs::{LogData, LogExporter};

use crate::logs::exporter::ExporterConfig;
use crate::logs::exporter::*;
Expand Down Expand Up @@ -45,4 +45,9 @@ impl opentelemetry_sdk::logs::LogProcessor for ReentrantLogProcessor {
fn shutdown(&mut self) -> LogResult<()> {
Ok(())
}

#[cfg(feature = "logs_level_enabled")]
fn event_enabled(&self, name: &str, level: opentelemetry_api::logs::Severity) -> bool {
self.event_exporter.event_enabled(name, level)
}
}
1 change: 1 addition & 0 deletions opentelemetry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ default = ["trace"]
trace = ["opentelemetry_api/trace", "opentelemetry_sdk/trace", "opentelemetry-stdout/trace"]
metrics = ["opentelemetry_api/metrics", "opentelemetry_sdk/metrics", "opentelemetry-stdout/metrics"]
logs = ["opentelemetry_sdk/logs"]
logs_level_enabled = ["logs"]
testing = ["opentelemetry_api/testing", "opentelemetry_sdk/testing"]
rt-tokio = ["opentelemetry_sdk/rt-tokio"]
rt-tokio-current-thread = ["opentelemetry_sdk/rt-tokio-current-thread"]
Expand Down