Skip to content

Commit b495cb3

Browse files
committed
git commit -am "docs: Add tracing tutorial with Jaeger"
1 parent 0631070 commit b495cb3

File tree

6 files changed

+147
-0
lines changed

6 files changed

+147
-0
lines changed

examples/all-signals/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "all-signals"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
opentelemetry = { path = "../../opentelemetry" }
8+
opentelemetry_sdk = { path = "../../opentelemetry-sdk" }
9+
opentelemetry-otlp = { workspace = true, features = ["grpc-tonic"] }
10+
tokio = { workspace = true, features = ["full"] }
11+

examples/all-signals/README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Getting Started with OpenTelemetry Tracing in Rust
2+
3+
This tutorial demonstrates how to instrument a Rust application with
4+
OpenTelemetry tracing and visualize the traces using
5+
[Jaeger](https://www.jaegertracing.io/).
6+
7+
## Running the example
8+
9+
### Prerequisites
10+
11+
- **Docker**: Install from [docker.com](https://docs.docker.com/get-docker/) for
12+
running Jaeger locally
13+
14+
### Step 1: Start Jaeger
15+
16+
Start Jaeger using Docker:
17+
18+
```shell
19+
docker run --rm -d --name jaeger \
20+
-p 16686:16686 \
21+
-p 4317:4317 \
22+
cr.jaegertracing.io/jaegertracing/jaeger:2.8.0
23+
```
24+
25+
This exposes:
26+
27+
- Port `16686`: Jaeger web UI
28+
- Port `4317`: OTLP endpoint for receiving traces
29+
30+
Verify it's running at <http://localhost:16686/>
31+
32+
![Jaeger UI](jaeger-start.png)
33+
34+
### Step 2: Run the application
35+
36+
```shell
37+
cargo run
38+
```
39+
40+
This will:
41+
42+
1. Initialize OpenTelemetry with OTLP exporter pointing to `localhost:4317`
43+
2. Create a parent span (`Main operation`) and child span (`Sub operation`)
44+
3. Send the trace data to Jaeger
45+
46+
### Step 3: View traces in Jaeger
47+
48+
1. Open [http://localhost:16686](http://localhost:16686) and refresh
49+
2. Select `DemoApp` from the **Service** dropdown
50+
3. Click **Find Traces**
51+
52+
![Jaeger trace list](jaeger-traces.png)
53+
54+
Click on a trace to open Trace Details view, which show the span hierarchy and timing:
55+
56+
![Jaeger trace details](jaeger-trace-details.png)
57+
58+
You'll see the `Main operation` span containing the `Sub operation` span, along
59+
with their timing information and any attributes or events.
60+
61+
## Data flow
62+
63+
```mermaid
64+
graph LR
65+
A[Rust App] -->|OTLP| B[Jaeger]
66+
B --> C[Web UI]
67+
```
68+
69+
### Cleanup
70+
71+
```shell
72+
docker stop jaeger
73+
```
74+
75+
## Next steps (TODO)
76+
77+
- Add metrics and logs instrumentation
78+
- Add sampling and context propagation
79+
- Add distributed tracing across multiple services
296 KB
Loading
143 KB
Loading
266 KB
Loading

examples/all-signals/src/main.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use opentelemetry_sdk::trace::SdkTracerProvider;
2+
use opentelemetry::trace::{Tracer, TraceContextExt};
3+
use opentelemetry::KeyValue;
4+
use opentelemetry_otlp::SpanExporter;
5+
use opentelemetry_sdk::Resource;
6+
use std::sync::OnceLock;
7+
use opentelemetry::global;
8+
use std::time::Duration;
9+
10+
fn get_resource() -> Resource {
11+
static RESOURCE: OnceLock<Resource> = OnceLock::new();
12+
RESOURCE
13+
.get_or_init(|| {
14+
Resource::builder()
15+
.with_service_name("DemoApp")
16+
.build()
17+
})
18+
.clone()
19+
}
20+
21+
fn init_traces() -> SdkTracerProvider {
22+
let exporter = SpanExporter::builder()
23+
.with_tonic()
24+
.build()
25+
.expect("Failed to create span exporter");
26+
SdkTracerProvider::builder()
27+
.with_resource(get_resource())
28+
.with_batch_exporter(exporter)
29+
.build()
30+
}
31+
32+
#[tokio::main]
33+
async fn main() {
34+
let tracer_provider = init_traces();
35+
global::set_tracer_provider(tracer_provider.clone());
36+
let tracer = global::tracer("my-application");
37+
38+
tracer.in_span("Main operation", |cx| {
39+
let span = cx.span();
40+
span.set_attribute(KeyValue::new("operation.name", "demo"));
41+
42+
// Simulate some work
43+
std::thread::sleep(Duration::from_millis(200));
44+
45+
tracer.in_span("Sub operation", |cx| {
46+
let span = cx.span();
47+
span.set_attribute(KeyValue::new("operation.type", "processing"));
48+
49+
// Simulate sub-operation work
50+
std::thread::sleep(Duration::from_millis(50));
51+
52+
span.add_event("Processing completed", vec![]);
53+
});
54+
});
55+
56+
tracer_provider.shutdown().expect("Failed to shutdown tracer provider");
57+
}

0 commit comments

Comments
 (0)