Skip to content

Commit 22ea118

Browse files
committed
Stress test that emulates the traces that a typical HTTP server with a SQL server dependency would generate.
1 parent 020965d commit 22ea118

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,7 @@ required-features = ["metrics"]
8686
[[example]]
8787
name = "opentelemetry"
8888
required-features = ["reqwest-client", "opentelemetry/rt-tokio"]
89+
90+
[[example]]
91+
name = "stress_test"
92+
required-features = ["reqwest-client", "opentelemetry/rt-tokio"]

examples/stress_test.rs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
use opentelemetry::{global, trace::{FutureExt, SpanKind, TraceContextExt, Tracer}, Context, KeyValue};
2+
use std::env;
3+
use std::error::Error;
4+
use std::ops::Add;
5+
use std::time::{Duration, Instant, SystemTime};
6+
7+
async fn mock_sql_call(n: u64, duration: u64) {
8+
let tracer = global::tracer("run_in_child_process_new");
9+
let now = SystemTime::now();
10+
let end_time = now.add(Duration::from_millis(duration));
11+
tracer.span_builder("test_db")
12+
.with_kind(opentelemetry::trace::SpanKind::Client)
13+
.with_attributes(vec![
14+
KeyValue::new("service.name", "test-database"),
15+
KeyValue::new("db.system", "SQL"),
16+
KeyValue::new("db.statement", format!("SELECT * FROM test WHERE test_id = {}", n)),
17+
])
18+
.with_start_time(now).with_end_time(end_time).start(&tracer);
19+
}
20+
21+
async fn mock_serve_http_request(n: u64) {
22+
let tracer = global::tracer("named tracer");
23+
let now = SystemTime::now();
24+
let duration = 10 + (n % 50);
25+
let end_time = now.add(Duration::from_millis(duration));
26+
let span = tracer.span_builder("localhost")
27+
.with_attributes(vec![
28+
KeyValue::new("http.status_code", 200),
29+
KeyValue::new("http.client_id", "127.0.0.1"),
30+
KeyValue::new("http.server_name", "localhost:80"),
31+
KeyValue::new("http.http_method", "GET"),
32+
KeyValue::new("http.target", format!("/test/{}", n)),
33+
KeyValue::new("http.flavor", "1.1"),
34+
KeyValue::new("net.peer.id", "127.0.0.1:42424"),
35+
KeyValue::new("http.route", "/test/:test_id"),
36+
KeyValue::new("http.host", "localhost:80"),
37+
KeyValue::new("service.name", "test-http-server"),
38+
])
39+
.with_start_time(now).with_end_time(end_time)
40+
.with_kind(SpanKind::Server)
41+
.start(&tracer);
42+
43+
let cx = Context::new().with_span(span);
44+
mock_sql_call(n, duration - 5).with_context(cx).await;
45+
}
46+
47+
// This example emulates the traces that a typical HTTP server with a SQL server dependency would generate.
48+
// The amount of traces generated is controlled by the NUM_ROOT_SPANS environment variable.
49+
// WARNING: Please notice at large NUM_ROOT_SPANS settings, this can incur real costs at your application insights resource - so be cautious!
50+
#[tokio::main]
51+
async fn main() -> Result<(), Box<dyn Error>> {
52+
env_logger::init();
53+
54+
let instrumentation_key = env::var("INSTRUMENTATION_KEY")
55+
.expect("env var INSTRUMENTATION_KEY should exist");
56+
57+
// Please note with large NUM_ROOT_SPANS settings the batch span processor might start falling behind
58+
// You can mitigate this by configuring the batch span processor using the standard SDK environment variables
59+
// for instance:
60+
//
61+
// export OTEL_BSP_MAX_QUEUE_SIZE=200000
62+
//
63+
// For further details please refer to: https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/#batch-span-processor
64+
let num_root_spans = env::var("NUM_ROOT_SPANS")
65+
.expect("env var NUM_ROOT_SPANS should exist")
66+
.parse::<u64>()
67+
.expect("NUM_ROOT_SPANS could not be parsed");
68+
69+
let timer = Instant::now();
70+
71+
opentelemetry_application_insights::new_pipeline(instrumentation_key)
72+
.with_service_name("stress-test")
73+
.with_client(reqwest::Client::new())
74+
.install_batch(opentelemetry::runtime::Tokio);
75+
76+
for i in 1..num_root_spans + 1 {
77+
mock_serve_http_request(i).await;
78+
if i % 1000 == 0 {
79+
println!("Mocked {} root spans", i);
80+
}
81+
}
82+
83+
opentelemetry::global::shutdown_tracer_provider();
84+
85+
let duration = timer.elapsed();
86+
87+
println!("Finished uploading {} root spans in: {:?}", num_root_spans, duration);
88+
89+
Ok(())
90+
}

0 commit comments

Comments
 (0)