Skip to content
This repository was archived by the owner on Sep 10, 2024. It is now read-only.

Commit dde9077

Browse files
committed
Use OTEL semantic conventions constants for most attributes
1 parent 7e30daf commit dde9077

File tree

11 files changed

+72
-57
lines changed

11 files changed

+72
-57
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/cli/src/server.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use opentelemetry::{Key, KeyValue};
4242
use opentelemetry_http::HeaderExtractor;
4343
use opentelemetry_semantic_conventions::trace::{
4444
HTTP_REQUEST_METHOD, HTTP_RESPONSE_STATUS_CODE, HTTP_ROUTE, NETWORK_PROTOCOL_NAME,
45-
NETWORK_PROTOCOL_VERSION, URL_SCHEME,
45+
NETWORK_PROTOCOL_VERSION, URL_PATH, URL_QUERY, URL_SCHEME, USER_AGENT_ORIGINAL,
4646
};
4747
use rustls::ServerConfig;
4848
use sentry_tower::{NewSentryLayer, SentryHttpLayer};
@@ -120,30 +120,31 @@ fn make_http_span<B>(req: &Request<B>) -> Span {
120120
"otel.kind" = "server",
121121
"otel.name" = span_name,
122122
"otel.status_code" = tracing::field::Empty,
123-
"network.protocol.name" = "http",
124-
"network.protocol.version" = otel_net_protocol_version(req),
125-
"http.method" = method,
126-
"http.route" = tracing::field::Empty,
127-
"http.response.status_code" = tracing::field::Empty,
128-
"url.path" = req.uri().path(),
129-
"url.query" = tracing::field::Empty,
130-
"url.scheme" = otel_url_scheme(req),
131-
"user_agent.original" = tracing::field::Empty,
123+
{ NETWORK_PROTOCOL_NAME } = "http",
124+
{ NETWORK_PROTOCOL_VERSION } = otel_net_protocol_version(req),
125+
{ HTTP_REQUEST_METHOD } = method,
126+
{ HTTP_ROUTE } = tracing::field::Empty,
127+
{ HTTP_RESPONSE_STATUS_CODE } = tracing::field::Empty,
128+
{ URL_PATH } = req.uri().path(),
129+
{ URL_QUERY } = tracing::field::Empty,
130+
{ URL_SCHEME } = otel_url_scheme(req),
131+
{ USER_AGENT_ORIGINAL } = tracing::field::Empty,
132132
);
133133

134134
if let Some(route) = route.as_ref() {
135-
span.record("http.route", route);
135+
span.record(HTTP_ROUTE, route);
136136
}
137137

138138
if let Some(query) = req.uri().query() {
139-
span.record("url.query", query);
139+
span.record(URL_QUERY, query);
140140
}
141141

142-
if let Some(user_agent) = req.headers().get(USER_AGENT) {
143-
span.record(
144-
"user_agent.original",
145-
user_agent.to_str().unwrap_or("INVALID"),
146-
);
142+
if let Some(user_agent) = req
143+
.headers()
144+
.get(USER_AGENT)
145+
.and_then(|ua| ua.to_str().ok())
146+
{
147+
span.record(USER_AGENT_ORIGINAL, user_agent);
147148
}
148149

149150
// Extract the parent span context from the request headers

crates/handlers/src/graphql/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use mas_storage::{
3939
BoxClock, BoxRepository, BoxRng, Clock, Repository, RepositoryError, SystemClock,
4040
};
4141
use mas_storage_pg::PgRepository;
42+
use opentelemetry_semantic_conventions::trace::{GRAPHQL_DOCUMENT, GRAPHQL_OPERATION_NAME};
4243
use rand::{thread_rng, SeedableRng};
4344
use rand_chacha::ChaChaRng;
4445
use sqlx::PgPool;
@@ -112,13 +113,13 @@ fn span_for_graphql_request(request: &async_graphql::Request) -> tracing::Span {
112113
"GraphQL operation",
113114
"otel.name" = tracing::field::Empty,
114115
"otel.kind" = "server",
115-
"graphql.document" = request.query,
116-
"graphql.operation.name" = tracing::field::Empty,
116+
{ GRAPHQL_DOCUMENT } = request.query,
117+
{ GRAPHQL_OPERATION_NAME } = tracing::field::Empty,
117118
);
118119

119120
if let Some(name) = &request.operation_name {
120121
span.record("otel.name", name);
121-
span.record("graphql.operation.name", name);
122+
span.record(GRAPHQL_OPERATION_NAME, name);
122123
}
123124

124125
span

crates/http/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ http-body.workspace = true
2020
hyper.workspace = true
2121
hyper-rustls = { workspace = true, optional = true }
2222
opentelemetry.workspace = true
23+
opentelemetry-semantic-conventions.workspace = true
2324
rustls = { workspace = true, optional = true }
2425
rustls-platform-verifier = { workspace = true, optional = true }
2526
serde.workspace = true

crates/http/src/client.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use mas_tower::{
2222
DurationRecorderLayer, DurationRecorderService, FnWrapper, InFlightCounterLayer,
2323
InFlightCounterService, TraceLayer, TraceService,
2424
};
25+
use opentelemetry_semantic_conventions::trace::SERVER_ADDRESS;
2526
use tower::Layer;
2627
use tracing::Span;
2728

@@ -54,9 +55,10 @@ where
5455
let trace_layer = TraceLayer::from_fn(
5556
(|request: &Name| {
5657
tracing::info_span!(
57-
"dns.resolve",
58+
"dns.lookup",
5859
"otel.kind" = "client",
59-
"net.host.name" = %request,
60+
{ SERVER_ADDRESS } = %request,
61+
6062
)
6163
}) as fn(&Name) -> Span,
6264
);

crates/http/src/layers/client.rs

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ use mas_tower::{
2323
TraceLayer, TraceService,
2424
};
2525
use opentelemetry::KeyValue;
26+
use opentelemetry_semantic_conventions::trace::{
27+
CLIENT_ADDRESS, CLIENT_PORT, HTTP_REQUEST_BODY_SIZE, HTTP_REQUEST_METHOD,
28+
HTTP_RESPONSE_BODY_SIZE, HTTP_RESPONSE_STATUS_CODE, NETWORK_PROTOCOL_NAME, NETWORK_TRANSPORT,
29+
NETWORK_TYPE, SERVER_ADDRESS, SERVER_PORT, URL_FULL, USER_AGENT_ORIGINAL,
30+
};
2631
use tower::{
2732
limit::{ConcurrencyLimit, GlobalConcurrencyLimitLayer},
2833
Layer,
@@ -69,27 +74,25 @@ impl<B> MakeSpan<Request<B>> for MakeSpanForRequest {
6974
.typed_get::<UserAgent>()
7075
.map(tracing::field::display);
7176
let content_length = headers.typed_get().map(|ContentLength(len)| len);
72-
let net_sock_peer_name = request.uri().host();
7377
let category = self.category.unwrap_or("UNSET");
7478

7579
tracing::info_span!(
7680
"http.client.request",
7781
"otel.kind" = "client",
7882
"otel.status_code" = tracing::field::Empty,
79-
"http.method" = %request.method(),
80-
"http.url" = %request.uri(),
81-
"http.status_code" = tracing::field::Empty,
82-
"http.host" = host,
83-
"http.request_content_length" = content_length,
84-
"http.response_content_length" = tracing::field::Empty,
85-
"net.transport" = "ip_tcp",
86-
"net.sock.family" = tracing::field::Empty,
87-
"net.sock.peer.name" = net_sock_peer_name,
88-
"net.sock.peer.addr" = tracing::field::Empty,
89-
"net.sock.peer.port" = tracing::field::Empty,
90-
"net.sock.host.addr" = tracing::field::Empty,
91-
"net.sock.host.port" = tracing::field::Empty,
92-
"user_agent.original" = user_agent,
83+
{ HTTP_REQUEST_METHOD } = %request.method(),
84+
{ URL_FULL } = %request.uri(),
85+
{ HTTP_RESPONSE_STATUS_CODE } = tracing::field::Empty,
86+
{ SERVER_ADDRESS } = host,
87+
{ HTTP_REQUEST_BODY_SIZE } = content_length,
88+
{ HTTP_RESPONSE_BODY_SIZE } = tracing::field::Empty,
89+
{ NETWORK_TRANSPORT } = "tcp",
90+
{ NETWORK_TYPE } = tracing::field::Empty,
91+
{ SERVER_ADDRESS } = tracing::field::Empty,
92+
{ SERVER_PORT } = tracing::field::Empty,
93+
{ CLIENT_ADDRESS } = tracing::field::Empty,
94+
{ CLIENT_PORT } = tracing::field::Empty,
95+
{ USER_AGENT_ORIGINAL } = user_agent,
9396
"rust.error" = tracing::field::Empty,
9497
"mas.category" = category,
9598
)
@@ -102,22 +105,22 @@ pub struct EnrichSpanOnResponse;
102105
impl<B> EnrichSpan<Response<B>> for EnrichSpanOnResponse {
103106
fn enrich_span(&self, span: &Span, response: &Response<B>) {
104107
span.record("otel.status_code", "OK");
105-
span.record("http.status_code", response.status().as_u16());
108+
span.record(HTTP_RESPONSE_STATUS_CODE, response.status().as_u16());
106109

107110
if let Some(ContentLength(content_length)) = response.headers().typed_get() {
108-
span.record("http.response_content_length", content_length);
111+
span.record(HTTP_RESPONSE_BODY_SIZE, content_length);
109112
}
110113

111114
if let Some(http_info) = response.extensions().get::<HttpInfo>() {
112115
let local = http_info.local_addr();
113116
let remote = http_info.remote_addr();
114117

115-
let family = if local.is_ipv4() { "inet" } else { "inet6" };
116-
span.record("net.sock.family", family);
117-
span.record("net.sock.peer.addr", remote.ip().to_string());
118-
span.record("net.sock.peer.port", remote.port());
119-
span.record("net.sock.host.addr", local.ip().to_string());
120-
span.record("net.sock.host.port", local.port());
118+
let family = if local.is_ipv4() { "ipv4" } else { "ipv6" };
119+
span.record(NETWORK_TYPE, family);
120+
span.record(CLIENT_ADDRESS, remote.ip().to_string());
121+
span.record(CLIENT_PORT, remote.port());
122+
span.record(SERVER_ADDRESS, local.ip().to_string());
123+
span.record(SERVER_PORT, local.port());
121124
} else {
122125
tracing::warn!("No HttpInfo injected in response extensions");
123126
}
@@ -149,8 +152,8 @@ where
149152
type Iter<'a> = std::array::IntoIter<KeyValue, 3>;
150153
fn attributes<'a>(&'a self, t: &'a Request<B>) -> Self::Iter<'a> {
151154
[
152-
KeyValue::new("http.request.method", t.method().as_str().to_owned()),
153-
KeyValue::new("network.protocol.name", "http"),
155+
KeyValue::new(HTTP_REQUEST_METHOD, t.method().as_str().to_owned()),
156+
KeyValue::new(NETWORK_PROTOCOL_NAME, "http"),
154157
KeyValue::new("mas.category", self.category.unwrap_or("UNSET")),
155158
]
156159
.into_iter()
@@ -167,7 +170,7 @@ where
167170
type Iter<'a> = std::iter::Once<KeyValue>;
168171
fn attributes<'a>(&'a self, t: &'a Response<B>) -> Self::Iter<'a> {
169172
std::iter::once(KeyValue::new(
170-
"http.response.status_code",
173+
HTTP_RESPONSE_STATUS_CODE,
171174
i64::from(t.status().as_u16()),
172175
))
173176
}

crates/storage-pg/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ serde_json.workspace = true
2222
thiserror.workspace = true
2323
tracing.workspace = true
2424
futures-util = "0.3.30"
25+
opentelemetry-semantic-conventions.workspace = true
2526

2627
rand.workspace = true
2728
rand_chacha = "0.3.1"

crates/storage-pg/src/oauth2/client.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use oauth2_types::{
3131
requests::GrantType,
3232
scope::{Scope, ScopeToken},
3333
};
34+
use opentelemetry_semantic_conventions::trace::DB_STATEMENT;
3435
use rand::RngCore;
3536
use sqlx::PgConnection;
3637
use tracing::{info_span, Instrument};
@@ -786,7 +787,7 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
786787
{
787788
let span = info_span!(
788789
"db.oauth2_client.delete_by_id.authorization_grants",
789-
db.statement = tracing::field::Empty,
790+
{ DB_STATEMENT } = tracing::field::Empty,
790791
);
791792

792793
sqlx::query!(
@@ -806,7 +807,7 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
806807
{
807808
let span = info_span!(
808809
"db.oauth2_client.delete_by_id.consents",
809-
db.statement = tracing::field::Empty,
810+
{ DB_STATEMENT } = tracing::field::Empty,
810811
);
811812

812813
sqlx::query!(
@@ -826,7 +827,7 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
826827
{
827828
let span = info_span!(
828829
"db.oauth2_client.delete_by_id.access_tokens",
829-
db.statement = tracing::field::Empty,
830+
{ DB_STATEMENT } = tracing::field::Empty,
830831
);
831832

832833
sqlx::query!(
@@ -849,7 +850,7 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
849850
{
850851
let span = info_span!(
851852
"db.oauth2_client.delete_by_id.refresh_tokens",
852-
db.statement = tracing::field::Empty,
853+
{ DB_STATEMENT } = tracing::field::Empty,
853854
);
854855

855856
sqlx::query!(
@@ -872,7 +873,7 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
872873
{
873874
let span = info_span!(
874875
"db.oauth2_client.delete_by_id.sessions",
875-
db.statement = tracing::field::Empty,
876+
{ DB_STATEMENT } = tracing::field::Empty,
876877
);
877878

878879
sqlx::query!(

crates/storage-pg/src/tracing.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use opentelemetry_semantic_conventions::trace::DB_STATEMENT;
1516
use tracing::Span;
1617

1718
/// An extension trait for [`sqlx::Execute`] that records the SQL statement as
@@ -34,7 +35,7 @@ where
3435
DB: sqlx::Database,
3536
{
3637
fn record(self, span: &Span) -> Self {
37-
span.record("db.statement", self.sql());
38+
span.record(DB_STATEMENT, self.sql());
3839
self
3940
}
4041
}

crates/storage-pg/src/upstream_oauth2/provider.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use mas_storage::{
2121
},
2222
Clock, Page, Pagination,
2323
};
24+
use opentelemetry_semantic_conventions::trace::DB_STATEMENT;
2425
use rand::RngCore;
2526
use sea_query::{enum_def, Expr, PostgresQueryBuilder, Query};
2627
use sea_query_binder::SqlxBinder;
@@ -333,7 +334,7 @@ impl<'c> UpstreamOAuthProviderRepository for PgUpstreamOAuthProviderRepository<'
333334
let span = info_span!(
334335
"db.oauth2_client.delete_by_id.authorization_sessions",
335336
upstream_oauth_provider.id = %id,
336-
db.statement = tracing::field::Empty,
337+
{ DB_STATEMENT } = tracing::field::Empty,
337338
);
338339
sqlx::query!(
339340
r#"
@@ -354,7 +355,7 @@ impl<'c> UpstreamOAuthProviderRepository for PgUpstreamOAuthProviderRepository<'
354355
let span = info_span!(
355356
"db.oauth2_client.delete_by_id.links",
356357
upstream_oauth_provider.id = %id,
357-
db.statement = tracing::field::Empty,
358+
{ DB_STATEMENT } = tracing::field::Empty,
358359
);
359360
sqlx::query!(
360361
r#"

0 commit comments

Comments
 (0)