Skip to content

Commit 9c81493

Browse files
committed
Update otel
1 parent 75722d5 commit 9c81493

File tree

6 files changed

+105
-131
lines changed

6 files changed

+105
-131
lines changed

.cursor/rules/rust.mdc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ globs: **.rs
99
---
1010

1111
This Rust project uses the async-std runtime, the anyhow error handling crate, the Poem HTTP framework, and rustls-tls for secure TLS. Assume these dependencies are available and imported when generating code.
12+
13+
This project is a monorepo, the rust code can be found in the `engine/` folder.

engine/src/main.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,13 @@ use tracing_subscriber::prelude::*;
2828
#[async_std::main]
2929
async fn main() {
3030
dotenvy::dotenv().ok();
31-
// tracing_log::LogTracer::init().expect("Failed to initialize logger");
32-
33-
// let exporter = opentelemetry_otlp::SpanExporter::builder()
34-
// .with_http()
35-
// .with_endpoint("http://localhost:4317")
36-
// .build()
37-
// // .install_batch(opentelemetry_sdk::runtime::AsyncStd)
38-
// .expect("Couldn't create OTLP tracer");
3931

4032
let otlp_endpoint = env::var("OTLP_ENDPOINT").ok();
4133

4234
if let Some(endpoint) = otlp_endpoint {
4335
info!("Starting Edgerouter with OTLP tracing");
36+
37+
// Set up propagator for trace context
4438
opentelemetry::global::set_text_map_propagator(TraceContextPropagator::new());
4539

4640
let exporter = opentelemetry_otlp::SpanExporter::builder()
@@ -56,6 +50,7 @@ async fn main() {
5650
.with_attribute(KeyValue::new("host.name", hostname))
5751
.build();
5852

53+
// Use a simple tracer provider configuration
5954
let trace_provider = opentelemetry_sdk::trace::SdkTracerProvider::builder()
6055
.with_resource(resource)
6156
.with_batch_exporter(exporter)
@@ -65,17 +60,20 @@ async fn main() {
6560

6661
let tracer = trace_provider.tracer("edgeserver");
6762

63+
// Simple telemetry layer
6864
let telemetry_layer = tracing_opentelemetry::layer()
69-
.with_tracer(tracer.clone())
70-
.with_error_fields_to_exceptions(true)
71-
.with_tracked_inactivity(true);
65+
.with_tracer(tracer);
7266

73-
let fmt_layer = tracing_subscriber::fmt::layer().with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE);
67+
// Create a formatting layer with span closure events
68+
let fmt_layer = tracing_subscriber::fmt::layer()
69+
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE);
7470

71+
// Set up filter for relevant components
7572
let filter = tracing_subscriber::EnvFilter::from_default_env()
7673
.add_directive("poem=info".parse().unwrap())
7774
.add_directive("edgeserver=debug".parse().unwrap());
7875

76+
// Register layers with the subscriber
7977
tracing_subscriber::registry()
8078
.with(filter)
8179
.with(fmt_layer)

engine/src/middlewares/auth.rs

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use poem_openapi::{
77
ApiExtractor, ApiExtractorType, ExtractParamOptions,
88
};
99
use tracing::{info, info_span, Instrument};
10-
use tracing_opentelemetry::OpenTelemetrySpanExt;
1110

1211
use crate::{
1312
models::{keys::Key, session::Session, team::Team},
@@ -38,15 +37,10 @@ impl<'a> ApiExtractor<'a> for UserAuth {
3837
body: &mut RequestBody,
3938
_param_opts: ExtractParamOptions<Self::ParamType>,
4039
) -> Result<Self> {
41-
// Get current OpenTelemetry context to propagate
42-
let parent_cx = Context::current();
43-
44-
// Create auth span with proper parent context
45-
let auth_span = info_span!("auth");
46-
auth_span.set_parent(parent_cx);
47-
48-
// Run the authentication logic within the auth span
49-
let auth_result = async move {
40+
let span = info_span!("auth");
41+
42+
// Use instrument to track the auth span
43+
async {
5044
let state = <Data<&State> as FromRequest>::from_request(req, body).await?;
5145
let state = state.0;
5246

@@ -120,10 +114,8 @@ impl<'a> ApiExtractor<'a> for UserAuth {
120114

121115
Err(HttpError::Unauthorized.into())
122116
}
123-
.instrument(auth_span)
124-
.await;
125-
126-
auth_result
117+
.instrument(span)
118+
.await
127119
}
128120

129121
fn register(registry: &mut Registry) {
@@ -177,15 +169,10 @@ impl UserAuth {
177169
&self,
178170
team_id: impl AsRef<str> + Debug,
179171
) -> Result<(), HttpError> {
180-
// Get current OpenTelemetry context to propagate
181-
let parent_cx = Context::current();
182-
183-
// Create span with proper parent context
184-
let member_span = info_span!("required_member_of", team_id = ?team_id);
185-
member_span.set_parent(parent_cx);
186-
187-
// Each request should have its own context path
188-
async move {
172+
let span = info_span!("required_member_of", team_id = ?team_id);
173+
174+
// Use instrument to track the span
175+
async {
189176
match self {
190177
UserAuth::User(session, state) => {
191178
if !Team::is_member(&state, &team_id, &session.user_id)
@@ -203,22 +190,18 @@ impl UserAuth {
203190
UserAuth::None(_) => Err(HttpError::Unauthorized),
204191
}
205192
}
206-
.instrument(member_span)
193+
.instrument(span)
207194
.await
208195
}
209196

210197
pub async fn verify_access_to(
211198
&self,
212199
resource: &impl AccessibleResource,
213200
) -> Result<(), HttpError> {
214-
// Get current OpenTelemetry context to propagate
215-
216-
// Create span with proper parent context
217-
let access_span = info_span!("verify_access_to", resource = ?resource);
218-
access_span.set_parent(Context::current());
219-
220-
// Each request should have its own context path
221-
async move {
201+
let span = info_span!("verify_access_to", resource = ?resource);
202+
203+
// Use instrument to track the span
204+
async {
222205
match self {
223206
UserAuth::User(session, state) => match resource
224207
.has_access(state, "user", &session.user_id)
@@ -241,7 +224,7 @@ impl UserAuth {
241224
UserAuth::None(_) => Err(HttpError::Unauthorized),
242225
}
243226
}
244-
.instrument(access_span)
227+
.instrument(span)
245228
.await
246229
}
247230
}

engine/src/middlewares/tracing.rs

Lines changed: 72 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::sync::Arc;
22

33
use opentelemetry::{
44
global,
5-
trace::{FutureExt, Span, SpanKind, Tracer, TraceContextExt},
5+
trace::{Span, SpanKind, Tracer, TraceContextExt},
66
Context, Key, KeyValue,
77
};
88
use opentelemetry_http::HeaderExtractor;
@@ -68,11 +68,6 @@ where
6868
.map(|addr| addr.to_string())
6969
.unwrap_or_else(|| req.remote_addr().to_string());
7070

71-
// Extract parent context from request headers if present
72-
let parent_cx = global::get_text_map_propagator(|propagator| {
73-
propagator.extract(&HeaderExtractor(req.headers()))
74-
});
75-
7671
// Prepare span attributes
7772
let mut attributes = Vec::new();
7873
attributes.push(KeyValue::new(
@@ -101,99 +96,95 @@ where
10196
// Get method for span name
10297
let method = req.method().to_string();
10398

104-
// Create an OpenTelemetry span
99+
// Create a completely new span for this request
105100
let mut span = self
106101
.tracer
107102
.span_builder(format!("{} {}", method, req.uri()))
108103
.with_kind(SpanKind::Server)
109104
.with_attributes(attributes)
110-
.start_with_context(&*self.tracer, &parent_cx);
111-
105+
.start_with_context(&*self.tracer, &Context::new()); // Use a new blank context
106+
112107
// Record request start event
113108
span.add_event("request.started".to_string(), vec![]);
114109

115110
// Get trace ID for response header
116111
let trace_id = span.span_context().trace_id().to_string();
117112

118-
// Use FutureExt to maintain context across async boundaries
119-
async move {
120-
// Process the request with the inner endpoint
121-
let res = self.inner.call(req).await;
122-
123-
// Get current context with span
124-
let cx = Context::current();
125-
let span = cx.span();
126-
127-
// Process the response
128-
match res {
129-
Ok(resp) => {
130-
let mut resp = resp.into_response();
131-
132-
// Update span with path pattern if available
133-
if let Some(path_pattern) = resp.data::<PathPattern>() {
134-
const HTTP_PATH_PATTERN: Key = Key::from_static_str("http.path_pattern");
135-
span.update_name(format!("{} {}", method, path_pattern.0));
136-
span.set_attribute(KeyValue::new(
137-
HTTP_PATH_PATTERN,
138-
path_pattern.0.to_string(),
139-
));
140-
}
141-
142-
// Record successful completion
143-
span.add_event("request.completed".to_string(), vec![]);
144-
145-
// Set response status
113+
// Process the request with the inner endpoint
114+
let res = self.inner.call(req).await;
115+
116+
// Process the response
117+
match res {
118+
Ok(resp) => {
119+
let mut resp = resp.into_response();
120+
121+
// Update span with path pattern if available
122+
if let Some(path_pattern) = resp.data::<PathPattern>() {
123+
const HTTP_PATH_PATTERN: Key = Key::from_static_str("http.path_pattern");
124+
span.update_name(format!("{} {}", method, path_pattern.0));
146125
span.set_attribute(KeyValue::new(
147-
attribute::HTTP_RESPONSE_STATUS_CODE,
148-
resp.status().as_u16() as i64,
126+
HTTP_PATH_PATTERN,
127+
path_pattern.0.to_string(),
149128
));
150-
151-
// Track content length if available
152-
if let Some(content_length) = resp.headers().typed_get::<headers::ContentLength>() {
153-
span.set_attribute(KeyValue::new(
154-
// attribute::HTTP_RESPONSE_BODY_SIZE,
155-
"http.response_body_size",
156-
content_length.0 as i64,
157-
));
158-
}
159-
160-
// Add trace ID to response headers
161-
resp.headers_mut().insert(
162-
"X-Trace-Id",
163-
HeaderValue::from_str(&trace_id)
164-
.unwrap_or_else(|_| HeaderValue::from_static("unknown")),
165-
);
166-
167-
Ok(resp)
168129
}
169-
Err(err) => {
170-
// Update span with path pattern if error has it
171-
if let Some(path_pattern) = err.data::<PathPattern>() {
172-
const HTTP_PATH_PATTERN: Key = Key::from_static_str("http.path_pattern");
173-
span.update_name(format!("{} {}", method, path_pattern.0));
174-
span.set_attribute(KeyValue::new(
175-
HTTP_PATH_PATTERN,
176-
path_pattern.0.to_string(),
177-
));
178-
}
179-
180-
// Set error status code
130+
131+
// Record successful completion
132+
span.add_event("request.completed".to_string(), vec![]);
133+
134+
// Set response status
135+
span.set_attribute(KeyValue::new(
136+
attribute::HTTP_RESPONSE_STATUS_CODE,
137+
resp.status().as_u16() as i64,
138+
));
139+
140+
// Track content length if available
141+
if let Some(content_length) = resp.headers().typed_get::<headers::ContentLength>() {
142+
span.set_attribute(KeyValue::new(
143+
"http.response_body_size",
144+
content_length.0 as i64,
145+
));
146+
}
147+
148+
// Add trace ID to response headers
149+
resp.headers_mut().insert(
150+
"X-Trace-Id",
151+
HeaderValue::from_str(&trace_id)
152+
.unwrap_or_else(|_| HeaderValue::from_static("unknown")),
153+
);
154+
155+
// End the span
156+
span.end();
157+
158+
Ok(resp)
159+
}
160+
Err(err) => {
161+
// Update span with path pattern if error has it
162+
if let Some(path_pattern) = err.data::<PathPattern>() {
163+
const HTTP_PATH_PATTERN: Key = Key::from_static_str("http.path_pattern");
164+
span.update_name(format!("{} {}", method, path_pattern.0));
181165
span.set_attribute(KeyValue::new(
182-
attribute::HTTP_RESPONSE_STATUS_CODE,
183-
err.status().as_u16() as i64,
166+
HTTP_PATH_PATTERN,
167+
path_pattern.0.to_string(),
184168
));
185-
186-
// Record error event
187-
span.add_event(
188-
"request.error".to_string(),
189-
vec![KeyValue::new(attribute::EXCEPTION_MESSAGE, err.to_string())],
190-
);
191-
192-
Err(err)
193169
}
170+
171+
// Set error status code
172+
span.set_attribute(KeyValue::new(
173+
attribute::HTTP_RESPONSE_STATUS_CODE,
174+
err.status().as_u16() as i64,
175+
));
176+
177+
// Record error event
178+
span.add_event(
179+
"request.error".to_string(),
180+
vec![KeyValue::new(attribute::EXCEPTION_MESSAGE, err.to_string())],
181+
);
182+
183+
// End the span
184+
span.end();
185+
186+
Err(err)
194187
}
195188
}
196-
.with_context(Context::current_with_span(span)) // Key to proper context propagation
197-
.await
198189
}
199190
}

engine/src/server/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,4 +302,4 @@ fn polyfill_mime_type(mime: &str, file_name: &str) -> String {
302302
} else {
303303
mime.to_string()
304304
}
305-
}
305+
}

web/src/api/schema.gen.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,7 @@ export type components = {
16911691
* Deployment
16921692
* @example {
16931693
* "context": "{}",
1694-
* "created_at": "2025-05-18T11:53:27.918210298+00:00",
1694+
* "created_at": "2025-05-18T19:52:11.327096482+00:00",
16951695
* "deployment_id": "d_1234567890",
16961696
* "ipfs_cid": "Qm1234567890...",
16971697
* "site_id": "s_1234567890"
@@ -1764,13 +1764,13 @@ export type components = {
17641764
/**
17651765
* Key
17661766
* @example {
1767-
* "created_at": "2025-05-18T11:53:27.918285958+00:00",
1767+
* "created_at": "2025-05-18T19:52:11.327172962+00:00",
17681768
* "created_by": "u_1234567890",
1769-
* "expires_at": "2025-06-17T11:53:27.918286128+00:00",
1769+
* "expires_at": "2025-06-17T19:52:11.327173112+00:00",
17701770
* "key_id": "k_site_12345678901234567890",
17711771
* "key_resource": "s_1234567890",
17721772
* "key_type": "site",
1773-
* "last_used": "2025-05-18T11:53:27.918286058+00:00",
1773+
* "last_used": "2025-05-18T19:52:11.327173042+00:00",
17741774
* "permissions": "TBD",
17751775
* "vanity": "4567890"
17761776
* }

0 commit comments

Comments
 (0)