Skip to content

Commit 94df993

Browse files
Merge branch 'main' into add-shutdown-with-timeout-for-metric-exporter
2 parents 706ab5e + a071d8f commit 94df993

File tree

36 files changed

+1255
-659
lines changed

36 files changed

+1255
-659
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ jobs:
106106
continue-on-error: true # Prevent sudden announcement of a new advisory from failing ci
107107
steps:
108108
- uses: actions/checkout@v4
109-
- uses: EmbarkStudios/cargo-deny-action@v1
109+
- uses: EmbarkStudios/cargo-deny-action@v2
110110
with:
111111
command: check advisories
112112
docs:
@@ -153,3 +153,18 @@ jobs:
153153
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
154154
with:
155155
fail_ci_if_error: true
156+
cargo-machete:
157+
continue-on-error: true
158+
runs-on: ubuntu-latest
159+
steps:
160+
- uses: actions/checkout@v4
161+
with:
162+
submodules: true
163+
- uses: dtolnay/rust-toolchain@master
164+
with:
165+
toolchain: stable
166+
- uses: taiki-e/install-action@v2
167+
with:
168+
tool: cargo-machete
169+
- name: cargo machete
170+
run: cargo machete

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,16 +179,16 @@ you're more than welcome to participate!
179179

180180
### Maintainers
181181

182-
* [Cijo Thomas](https://github.com/cijothomas)
182+
* [Cijo Thomas](https://github.com/cijothomas), Microsoft
183183
* [Harold Dost](https://github.com/hdost)
184-
* [Lalit Kumar Bhasin](https://github.com/lalitb)
185-
* [Utkarsh Umesan Pillai](https://github.com/utpilla)
184+
* [Lalit Kumar Bhasin](https://github.com/lalitb), Microsoft
185+
* [Utkarsh Umesan Pillai](https://github.com/utpilla), Microsoft
186186
* [Zhongyang Wu](https://github.com/TommyCpp)
187187

188188
### Approvers
189189

190-
* [Shaun Cox](https://github.com/shaun-cox)
191-
* [Scott Gerring](https://github.com/scottgerring)
190+
* [Shaun Cox](https://github.com/shaun-cox), Microsoft
191+
* [Scott Gerring](https://github.com/scottgerring), Datadog
192192

193193
### Emeritus
194194

deny.toml

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
1-
exclude=[
2-
"actix-http",
3-
"actix-http-tracing",
4-
"actix-udp",
5-
"actix-udp-example",
6-
"tracing-grpc",
7-
"http"
8-
]
1+
[graph]
2+
exclude=[]
93

104
[licenses]
11-
unlicensed = "deny"
125
allow = [
136
"MIT",
147
"Apache-2.0",
@@ -29,5 +22,5 @@ license-files = [
2922
]
3023

3124
[advisories]
32-
unmaintained = "allow"
25+
unmaintained = "none"
3326
yanked = "allow"

docs/adr/001_error_handling.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,5 @@ Note that at the time of writing, there is no instance we have identified within
171171
We will use [thiserror](https://docs.rs/thiserror/latest/thiserror/) by default to implement Rust's [error trait](https://doc.rust-lang.org/core/error/trait.Error.html).
172172
This keeps our code clean, and as it does not appear in our interface, we can choose to replace any particular usage with a hand-rolled implementation should we need to.
173173

174+
### 6. Don't use `#[non_exhaustive]` by default
175+
If an `Error` response set is closed - if we can confidently say it is very unlikely to gain new variants in the future - we should not annotate it with `#[non_exhaustive]`. By way of example, the variants of the exporter error types described above are exhaustively documented in the OpenTelemetry Specification, and we can confidently say that we do not expect new variants.

examples/tracing-grpc/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,8 @@ tonic = { workspace = true, features = ["server", "codegen", "channel", "prost"]
2323

2424
[build-dependencies]
2525
tonic-build = { workspace = true }
26+
27+
[package.metadata.cargo-machete]
28+
ignored = [
29+
"prost" # needed for `tonic-build`
30+
]

examples/tracing-http-propagator/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,8 @@ tokio = { workspace = true, features = ["full"] }
2323
opentelemetry = { path = "../../opentelemetry" }
2424
opentelemetry_sdk = { path = "../../opentelemetry-sdk" }
2525
opentelemetry-http = { path = "../../opentelemetry-http" }
26-
opentelemetry-stdout = { workspace = true, features = ["trace"] }
26+
opentelemetry-stdout = { workspace = true, features = ["trace", "logs"] }
2727
opentelemetry-semantic-conventions = { path = "../../opentelemetry-semantic-conventions" }
28+
opentelemetry-appender-tracing = { workspace = true }
29+
tracing = { workspace = true, features = ["std"]}
30+
tracing-subscriber = { workspace = true, features = ["env-filter","registry", "std", "fmt"] }

examples/tracing-http-propagator/src/client.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,42 @@ use hyper_util::{client::legacy::Client, rt::TokioExecutor};
33
use opentelemetry::{
44
global,
55
trace::{SpanKind, TraceContextExt, Tracer},
6-
Context, KeyValue,
6+
Context,
77
};
8+
use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
89
use opentelemetry_http::{Bytes, HeaderInjector};
9-
use opentelemetry_sdk::{propagation::TraceContextPropagator, trace::SdkTracerProvider};
10-
use opentelemetry_stdout::SpanExporter;
10+
use opentelemetry_sdk::{
11+
logs::SdkLoggerProvider, propagation::TraceContextPropagator, trace::SdkTracerProvider,
12+
};
13+
use opentelemetry_stdout::{LogExporter, SpanExporter};
14+
use tracing::info;
15+
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
1116

12-
fn init_tracer() {
17+
fn init_tracer() -> SdkTracerProvider {
1318
global::set_text_map_propagator(TraceContextPropagator::new());
1419
// Install stdout exporter pipeline to be able to retrieve the collected spans.
1520
// For the demonstration, use `Sampler::AlwaysOn` sampler to sample all traces.
1621
let provider = SdkTracerProvider::builder()
1722
.with_simple_exporter(SpanExporter::default())
1823
.build();
1924

20-
global::set_tracer_provider(provider);
25+
global::set_tracer_provider(provider.clone());
26+
provider
27+
}
28+
29+
fn init_logs() -> SdkLoggerProvider {
30+
// Setup tracerprovider with stdout exporter
31+
// that prints the spans to stdout.
32+
let logger_provider = SdkLoggerProvider::builder()
33+
.with_simple_exporter(LogExporter::default())
34+
.build();
35+
let otel_layer = OpenTelemetryTracingBridge::new(&logger_provider);
36+
tracing_subscriber::registry()
37+
.with(otel_layer)
38+
.with(tracing_subscriber::filter::LevelFilter::INFO)
39+
.init();
40+
41+
logger_provider
2142
}
2243

2344
async fn send_request(
@@ -37,21 +58,22 @@ async fn send_request(
3758
global::get_text_map_propagator(|propagator| {
3859
propagator.inject_context(&cx, &mut HeaderInjector(req.headers_mut().unwrap()))
3960
});
61+
req.headers_mut()
62+
.unwrap()
63+
.insert("baggage", "is_synthetic=true".parse().unwrap());
4064
let res = client
4165
.request(req.body(Full::new(Bytes::from(body_content.to_string())))?)
4266
.await?;
4367

44-
cx.span().add_event(
45-
"Got response!",
46-
vec![KeyValue::new("status", res.status().to_string())],
47-
);
68+
info!(name: "ResponseReceived", status = res.status().to_string(), message = "Response received");
4869

4970
Ok(())
5071
}
5172

5273
#[tokio::main]
5374
async fn main() -> std::result::Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
54-
init_tracer();
75+
let tracer_provider = init_tracer();
76+
let logger_provider = init_logs();
5577

5678
send_request(
5779
"http://127.0.0.1:3000/health",
@@ -66,5 +88,11 @@ async fn main() -> std::result::Result<(), Box<dyn std::error::Error + Send + Sy
6688
)
6789
.await?;
6890

91+
tracer_provider
92+
.shutdown()
93+
.expect("Shutdown provider failed");
94+
logger_provider
95+
.shutdown()
96+
.expect("Shutdown provider failed");
6997
Ok(())
7098
}

examples/tracing-http-propagator/src/server.rs

Lines changed: 91 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,27 @@ use http_body_util::{combinators::BoxBody, BodyExt, Full};
22
use hyper::{body::Incoming, service::service_fn, Request, Response, StatusCode};
33
use hyper_util::rt::{TokioExecutor, TokioIo};
44
use opentelemetry::{
5+
baggage::BaggageExt,
56
global::{self, BoxedTracer},
7+
logs::LogRecord,
8+
propagation::TextMapCompositePropagator,
69
trace::{FutureExt, Span, SpanKind, TraceContextExt, Tracer},
7-
Context, KeyValue,
10+
Context, InstrumentationScope, KeyValue,
811
};
12+
use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
913
use opentelemetry_http::{Bytes, HeaderExtractor};
10-
use opentelemetry_sdk::{propagation::TraceContextPropagator, trace::SdkTracerProvider};
14+
use opentelemetry_sdk::{
15+
error::OTelSdkResult,
16+
logs::{LogProcessor, SdkLogRecord, SdkLoggerProvider},
17+
propagation::{BaggagePropagator, TraceContextPropagator},
18+
trace::{SdkTracerProvider, SpanProcessor},
19+
};
1120
use opentelemetry_semantic_conventions::trace;
12-
use opentelemetry_stdout::SpanExporter;
21+
use opentelemetry_stdout::{LogExporter, SpanExporter};
1322
use std::{convert::Infallible, net::SocketAddr, sync::OnceLock};
1423
use tokio::net::TcpListener;
24+
use tracing::info;
25+
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
1526

1627
fn get_tracer() -> &'static BoxedTracer {
1728
static TRACER: OnceLock<BoxedTracer> = OnceLock::new();
@@ -30,11 +41,11 @@ async fn handle_health_check(
3041
_req: Request<Incoming>,
3142
) -> Result<Response<BoxBody<Bytes, hyper::Error>>, Infallible> {
3243
let tracer = get_tracer();
33-
let mut span = tracer
44+
let _span = tracer
3445
.span_builder("health_check")
3546
.with_kind(SpanKind::Internal)
3647
.start(tracer);
37-
span.add_event("Health check accessed", vec![]);
48+
info!(name: "health_check", message = "Health check endpoint hit");
3849

3950
let res = Response::new(
4051
Full::new(Bytes::from_static(b"Server is up and running!"))
@@ -50,11 +61,11 @@ async fn handle_echo(
5061
req: Request<Incoming>,
5162
) -> Result<Response<BoxBody<Bytes, hyper::Error>>, Infallible> {
5263
let tracer = get_tracer();
53-
let mut span = tracer
64+
let _span = tracer
5465
.span_builder("echo")
5566
.with_kind(SpanKind::Internal)
5667
.start(tracer);
57-
span.add_event("Echoing back the request", vec![]);
68+
info!(name = "echo", message = "Echo endpoint hit");
5869

5970
let res = Response::new(req.into_body().boxed());
6071

@@ -69,14 +80,14 @@ async fn router(
6980
let response = {
7081
// Create a span parenting the remote client span.
7182
let tracer = get_tracer();
72-
let mut span = tracer
83+
let span = tracer
7384
.span_builder("router")
7485
.with_kind(SpanKind::Server)
7586
.start_with_context(tracer, &parent_cx);
7687

77-
span.add_event("dispatching request", vec![]);
88+
info!(name = "router", message = "Dispatching request");
7889

79-
let cx = Context::default().with_span(span);
90+
let cx = parent_cx.with_span(span);
8091
match (req.method(), req.uri().path()) {
8192
(&hyper::Method::GET, "/health") => handle_health_check(req).with_context(cx).await,
8293
(&hyper::Method::GET, "/echo") => handle_echo(req).with_context(cx).await,
@@ -93,24 +104,90 @@ async fn router(
93104
response
94105
}
95106

107+
/// A custom log processor that enriches LogRecords with baggage attributes.
108+
/// Baggage information is not added automatically without this processor.
109+
#[derive(Debug)]
110+
struct EnrichWithBaggageLogProcessor;
111+
impl LogProcessor for EnrichWithBaggageLogProcessor {
112+
fn emit(&self, data: &mut SdkLogRecord, _instrumentation: &InstrumentationScope) {
113+
Context::map_current(|cx| {
114+
for (kk, vv) in cx.baggage().iter() {
115+
data.add_attribute(kk.clone(), vv.0.clone());
116+
}
117+
});
118+
}
119+
120+
fn force_flush(&self) -> OTelSdkResult {
121+
Ok(())
122+
}
123+
124+
fn shutdown(&self) -> OTelSdkResult {
125+
Ok(())
126+
}
127+
}
128+
129+
/// A custom span processor that enriches spans with baggage attributes. Baggage
130+
/// information is not added automatically without this processor.
131+
#[derive(Debug)]
132+
struct EnrichWithBaggageSpanProcessor;
133+
impl SpanProcessor for EnrichWithBaggageSpanProcessor {
134+
fn force_flush(&self) -> OTelSdkResult {
135+
Ok(())
136+
}
137+
138+
fn shutdown(&self) -> OTelSdkResult {
139+
Ok(())
140+
}
141+
142+
fn on_start(&self, span: &mut opentelemetry_sdk::trace::Span, cx: &Context) {
143+
for (kk, vv) in cx.baggage().iter() {
144+
span.set_attribute(KeyValue::new(kk.clone(), vv.0.clone()));
145+
}
146+
}
147+
148+
fn on_end(&self, _span: opentelemetry_sdk::trace::SpanData) {}
149+
}
150+
96151
fn init_tracer() -> SdkTracerProvider {
97-
global::set_text_map_propagator(TraceContextPropagator::new());
152+
let baggage_propagator = BaggagePropagator::new();
153+
let trace_context_propagator = TraceContextPropagator::new();
154+
let composite_propagator = TextMapCompositePropagator::new(vec![
155+
Box::new(baggage_propagator),
156+
Box::new(trace_context_propagator),
157+
]);
158+
159+
global::set_text_map_propagator(composite_propagator);
98160

99161
// Setup tracerprovider with stdout exporter
100162
// that prints the spans to stdout.
101163
let provider = SdkTracerProvider::builder()
164+
.with_span_processor(EnrichWithBaggageSpanProcessor)
102165
.with_simple_exporter(SpanExporter::default())
103166
.build();
104167

105168
global::set_tracer_provider(provider.clone());
106169
provider
107170
}
108171

172+
fn init_logs() -> SdkLoggerProvider {
173+
// Setup tracerprovider with stdout exporter
174+
// that prints the spans to stdout.
175+
let logger_provider = SdkLoggerProvider::builder()
176+
.with_log_processor(EnrichWithBaggageLogProcessor)
177+
.with_simple_exporter(LogExporter::default())
178+
.build();
179+
let otel_layer = OpenTelemetryTracingBridge::new(&logger_provider);
180+
tracing_subscriber::registry().with(otel_layer).init();
181+
182+
logger_provider
183+
}
184+
109185
#[tokio::main]
110186
async fn main() {
111187
use hyper_util::server::conn::auto::Builder;
112188

113189
let provider = init_tracer();
190+
let logger_provider = init_logs();
114191
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
115192
let listener = TcpListener::bind(addr).await.unwrap();
116193

@@ -124,4 +201,7 @@ async fn main() {
124201
}
125202

126203
provider.shutdown().expect("Shutdown provider failed");
204+
logger_provider
205+
.shutdown()
206+
.expect("Shutdown provider failed");
127207
}

opentelemetry-http/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,10 @@ reqwest = { workspace = true, features = ["blocking"], optional = true }
2828
tokio = { workspace = true, features = ["time"], optional = true }
2929
tracing = {workspace = true, optional = true}
3030

31+
[package.metadata.cargo-machete]
32+
ignored = [
33+
"tracing" # needed for `internal-logs`
34+
]
35+
3136
[lints]
3237
workspace = true

opentelemetry-jaeger-propagator/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,10 @@ opentelemetry = { features = ["testing"], path = "../opentelemetry" }
3232
default = ["internal-logs"]
3333
internal-logs = ["tracing"]
3434

35+
[package.metadata.cargo-machete]
36+
ignored = [
37+
"tracing" # needed for `internal-logs`
38+
]
39+
3540
[lints]
3641
workspace = true

0 commit comments

Comments
 (0)