Skip to content

Commit c86d59b

Browse files
committed
XXX Better code documentation
1 parent 4092c21 commit c86d59b

File tree

3 files changed

+43
-36
lines changed

3 files changed

+43
-36
lines changed

dropshot/examples/multiple-servers.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ use tokio::sync::Mutex;
100100

101101
#[tokio::main]
102102
async fn main() -> Result<(), String> {
103+
// XXX Is there interest in adding the optional integration into some of the existing examples?
104+
#[cfg(feature = "otel-tracing")]
105+
let _otel_guard = equinix_otel_tools::init(env!("CARGO_CRATE_NAME"));
106+
103107
// Initial set of servers to start. Once they're running, we may add or
104108
// remove servers based on client requests.
105109
let initial_servers = [("A", "127.0.0.1:12345"), ("B", "127.0.0.1:12346")];

dropshot/examples/otel.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,8 @@ use opentelemetry_http::{Bytes, HeaderInjector};
4646
async fn main() -> Result<(), String> {
4747
let _otel_guard = equinix_otel_tools::init("otel-demo");
4848

49-
let config_dropshot: ConfigDropshot = ConfigDropshot {
50-
bind_address: std::net::SocketAddr::new(
51-
std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)),
52-
4000,
53-
),
49+
let config_dropshot = ConfigDropshot {
50+
bind_address: "127.0.0.1:4000".parse().unwrap(),
5451
..Default::default()
5552
};
5653

@@ -248,6 +245,7 @@ async fn example_api_error(
248245
method = GET,
249246
path = "/panic",
250247
}]
248+
#[cfg_attr(feature = "tokio-tracing", tracing::instrument(skip_all, err))]
251249
async fn example_api_panic(
252250
_rqctx: RequestContext<ExampleContext>,
253251
) -> Result<HttpResponseOk<CounterValue>, HttpError> {
@@ -264,7 +262,7 @@ async fn example_api_panic(
264262
method = PUT,
265263
path = "/counter",
266264
}]
267-
#[cfg_attr(feature = "tokio-tracing", tracing::instrument)]
265+
#[cfg_attr(feature = "tokio-tracing", tracing::instrument(skip_all, err))]
268266
async fn example_api_put_counter(
269267
rqctx: RequestContext<ExampleContext>,
270268
update: TypedBody<CounterValue>,

dropshot/src/otel.rs

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,35 @@
11
// Copyright 2024 Oxide Computer Company
22
//! Opentelemetry tracing support
33
//!
4+
// XXX Not sure if we want to just mimic reqwest-tracing
5+
// or not...
46
//! Fields that we want to produce to provide comparable
5-
//! functionality to reqwest-tracing[1]:
7+
//! functionality to [reqwest-tracing]:
68
//!
7-
//! - http.request.method
8-
//! - url.scheme
9-
//! - server.address
10-
//! - server.port
11-
//! - otel.kind
12-
//! - otel.name
13-
//! - otel.status_code
14-
//! - user_agent.original
15-
//! - http.response.status_code
16-
//! - error.message
17-
//! - error.cause_chain
9+
//! - [ ] error.cause_chain
10+
//! - [ ] error.message
11+
//! - [x] http.request.method
12+
//! - [x] http.response.status_code
13+
//! - [x] otel.kind (showing up as span.kind?)
14+
//! - [x] otel.name
15+
//! - [ ] otel.status_code (needs investigation)
16+
//! - [x] server.address
17+
//! - [x] server.port
18+
//! - [ ] url.scheme
19+
//! - [x] user_agent.original
1820
//!
19-
//! [1] <https://docs.rs/reqwest-tracing/0.5.4/reqwest_tracing/macro.reqwest_otel_span.html>
21+
//! Where possible we use the [opentelemetry-semantic-conventions] crate for naming.
22+
//!
23+
//! [reqwest-tracing]: https://docs.rs/reqwest-tracing/0.5.4/reqwest_tracing/macro.reqwest_otel_span.html
24+
//! [opentelemetry-semantic-conventions]:
25+
//! <https://docs.rs/opentelemetry-semantic-conventions/latest/opentelemetry_semantic_conventions/trace/index.html>
2026
2127
use opentelemetry::{
2228
global, trace::Span, trace::Tracer, trace::TracerProvider,
2329
};
2430
use opentelemetry_http::HeaderExtractor;
2531
use opentelemetry_semantic_conventions::trace;
2632

27-
// - url.scheme
28-
// - server.address
29-
// - server.port
30-
// - user_agent.original
3133
#[derive(Debug, Clone, serde::Serialize)]
3234
pub(crate) struct RequestInfo {
3335
pub id: String,
@@ -39,16 +41,14 @@ pub(crate) struct RequestInfo {
3941
pub user_agent: String,
4042
}
4143

42-
// - http.response.status_code
43-
// - error.message
44-
// - error.cause_chain
45-
// - otel.status_code
4644
pub(crate) struct ResponseInfo<'a> {
4745
pub status_code: u16,
4846
pub message: String,
4947
pub error: Option<&'a crate::handler::HandlerError>,
5048
}
5149

50+
/// Generate an opentelementry Context based on the headers
51+
/// in the incoming hyper request.
5252
fn extract_context_from_request(
5353
request: &hyper::Request<hyper::body::Incoming>,
5454
) -> opentelemetry::Context {
@@ -57,6 +57,7 @@ fn extract_context_from_request(
5757
})
5858
}
5959

60+
/// Create an opentelemetry Span to represent the handling of the incoming request.
6061
pub fn create_request_span(
6162
request: &hyper::Request<hyper::body::Incoming>,
6263
) -> opentelemetry::global::BoxedSpan {
@@ -74,8 +75,14 @@ pub fn create_request_span(
7475
.start_with_context(&tracer, &parent_cx)
7576
}
7677

78+
/// This trait contains all functionality needed for dropshot to annotate
79+
/// opentelemetry spans with information about a request and the corresponding response.
7780
pub trait TraceDropshot {
81+
/// Attach attributes to the span based on the provided
82+
/// RequestInfo
7883
fn trace_request(&mut self, request: RequestInfo);
84+
/// Attach the information from the ResponseInfo to the span
85+
/// including marking the span as an error if an error occurred.
7986
fn trace_response(&mut self, response: ResponseInfo);
8087
}
8188

@@ -84,30 +91,28 @@ impl TraceDropshot for opentelemetry::global::BoxedSpan {
8491
self.set_attributes(vec![
8592
// Rename to dropshot.id ????
8693
opentelemetry::KeyValue::new("http.id".to_string(), request.id),
94+
opentelemetry::KeyValue::new(trace::URL_PATH, request.path),
8795
opentelemetry::KeyValue::new(
88-
"http.method".to_string(),
96+
trace::HTTP_REQUEST_METHOD,
8997
request.method,
9098
),
91-
opentelemetry::KeyValue::new("http.path".to_string(), request.path),
9299
opentelemetry::KeyValue::new(
93-
"server.address".to_string(),
100+
trace::SERVER_ADDRESS,
94101
request.local_addr.ip().to_string(),
95102
),
96103
opentelemetry::KeyValue::new(
97-
"server.port".to_string(),
104+
trace::SERVER_PORT,
98105
request.local_addr.port().to_string(),
99106
),
100107
opentelemetry::KeyValue::new(
101-
"user_agent.original".to_string(),
108+
trace::USER_AGENT_ORIGINAL,
102109
request.user_agent,
103110
),
104111
]);
105112
}
106113

107-
// - [x] http.response.status_code
108-
// - [x] error.message
109-
// - [ ] error.cause_chain
110-
// - [ ] otel.status_code
114+
/// TODO: Do we want to differentiate between 4xx vs 5xx errors
115+
/// and not mark 4xx spans as error spans?
111116
fn trace_response(&mut self, response: ResponseInfo) {
112117
self.set_attributes(vec![
113118
opentelemetry::KeyValue::new(

0 commit comments

Comments
 (0)