Skip to content
Draft
Changes from all 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
164 changes: 108 additions & 56 deletions opentelemetry-user-events-logs/benches/logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@
The benchmark results:
criterion = "0.5.1"

Hardware: Apple M4 Pro
Total Number of Cores: 10
(Inside multipass vm running Ubuntu 22.04)
// When no listener
| Test | Average time|
|-----------------------------|-------------|
| User_Event_4_Attributes | 8 ns |
| User_Event_6_Attributes | 8 ns |
Hardware: <Hardware specifications>
Total Number of Cores: <number>
(Environment details)

// When no listener (automatically set by benchmark)
| Test | Average time |
|-----------------------------------|--------------|
| User_Events/4_Attributes_Disabled | X ns |
| User_Events/6_Attributes_Disabled | X ns |

// When listener is enabled
// Run below to enable
// echo 1 | sudo tee /sys/kernel/debug/tracing/events/user_events/myprovider_L2K1/enable
// Run below to disable
// echo 0 | sudo tee /sys/kernel/debug/tracing/events/user_events/myprovider_L2K1/enable
| Test | Average time|
|-----------------------------|-------------|
| User_Event_4_Attributes | 530 ns |
| User_Event_6_Attributes | 586 ns |
// When listener is enabled (automatically set by benchmark)
| Test | Average time |
|-----------------------------------|--------------|
| User_Events/4_Attributes_Enabled | X ns |
| User_Events/6_Attributes_Enabled | X ns |

Note: The benchmark automatically enables and disables the user-events listener
to compare performance between the two states.
*/

// running the following from the current directory
Expand All @@ -30,10 +30,46 @@ use opentelemetry_appender_tracing::layer as tracing_layer;
use opentelemetry_sdk::logs::SdkLoggerProvider;
use opentelemetry_sdk::Resource;
use opentelemetry_user_events_logs::Processor;
use std::fs;
use std::io::Write;
use std::process::Command;
use tracing::error;
use tracing_subscriber::prelude::*;
use tracing_subscriber::Registry;

/// Attempts to enable or disable the user_events listener
/// Returns true if the operation was successful, false otherwise
fn set_user_events_listener(enabled: bool) -> bool {
let enable_path = "/sys/kernel/debug/tracing/events/user_events/myprovider_L2K1/enable";
let value = if enabled { "1" } else { "0" };

// First try direct write (if we have permissions)
if let Ok(mut file) = fs::OpenOptions::new().write(true).open(enable_path) {
if file.write_all(value.as_bytes()).is_ok() {
return true;
}
}

// Fallback to using sudo with echo command
let output = Command::new("sudo")
.args(["tee", enable_path])
.stdin(std::process::Stdio::piped())
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.spawn()
.and_then(|mut child| {
if let Some(stdin) = child.stdin.as_mut() {
stdin.write_all(value.as_bytes()).ok();
}
child.wait()
});

match output {
Ok(status) => status.success(),
Err(_) => false,
}
}

fn setup_provider() -> SdkLoggerProvider {
let user_event_processor = Processor::builder("myprovider").build().unwrap();
SdkLoggerProvider::builder()
Expand All @@ -46,58 +82,74 @@ fn setup_provider() -> SdkLoggerProvider {
.build()
}

fn benchmark_4_attributes(c: &mut Criterion) {
let provider = setup_provider();
let ot_layer = tracing_layer::OpenTelemetryTracingBridge::new(&provider);
let subscriber = Registry::default().with(ot_layer);

tracing::subscriber::with_default(subscriber, || {
c.bench_function("User_Event_4_Attributes", |b| {
b.iter(|| {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
message = "Unable to process checkout."
);
});
});
});
/// Helper function to emit a log event with the specified number of attributes
fn emit_log_event(attribute_count: u8) {
match attribute_count {
4 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
message = "Unable to process checkout."
);
}
6 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
field5 = "field5",
field6 = "field6",
message = "Unable to process checkout."
);
}
_ => panic!("Unsupported attribute count: {}", attribute_count),
}
}

fn benchmark_6_attributes(c: &mut Criterion) {
fn benchmark_user_events(c: &mut Criterion) {
let mut group = c.benchmark_group("User_Events");

let provider = setup_provider();
let ot_layer = tracing_layer::OpenTelemetryTracingBridge::new(&provider);
let subscriber = Registry::default().with(ot_layer);

tracing::subscriber::with_default(subscriber, || {
c.bench_function("User_Event_6_Attributes", |b| {
b.iter(|| {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
field5 = "field5",
field6 = "field6",
message = "Unable to process checkout."
);
// Test configurations: (attribute_count, listener_enabled)
let test_configs = [
(4, false),
(4, true),
(6, false),
(6, true),
];

for (attribute_count, listener_enabled) in test_configs {
let test_name = format!(
"{}_Attributes_{}",
attribute_count,
if listener_enabled { "Enabled" } else { "Disabled" }
);

set_user_events_listener(listener_enabled);
group.bench_function(&test_name, |b| {
b.iter(|| emit_log_event(attribute_count));
});
});
});
}
}

fn criterion_benchmark(c: &mut Criterion) {
benchmark_4_attributes(c);
benchmark_6_attributes(c);
// Cleanup: disable listener
set_user_events_listener(false);
});

group.finish();
}

criterion_group! {
name = benches;
config = Criterion::default();
targets = criterion_benchmark
targets = benchmark_user_events
}
criterion_main!(benches);
Loading