Skip to content

Commit 1e64d7e

Browse files
committed
Fix OpenTelemetry naming in logs and spans
1 parent 1af44a7 commit 1e64d7e

File tree

5 files changed

+36
-25
lines changed

5 files changed

+36
-25
lines changed

examples/telemetry/README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,25 +67,25 @@ Each HTTP request produces a tree of **spans** (timed operations):
6767
└─ [sqlpage] SQL website/todos.sql ← SQL file execution
6868
├─ db.pool.acquire ← time waiting for a DB connection
6969
└─ db.query ← the actual SQL query
70-
db.statement = "SELECT title, ..."
71-
db.system = "PostgreSQL"
70+
db.query.text = "SELECT title, ..."
71+
db.system.name = "postgresql"
7272
```
7373

7474
Key attributes on each span:
7575

7676
| Span | Key attributes |
7777
|---------------------|--------------------------------------------------------------|
78-
| HTTP request | `http.method`, `http.target`, `http.status_code`, `http.user_agent` |
79-
| SQL file execution | `sqlpage.file` — which `.sql` file was executed |
80-
| `db.pool.acquire` | `db.pool.size` — current pool size when acquiring |
81-
| `db.query` | `db.statement` — the full SQL text; `db.system` — database type |
78+
| HTTP request | `http.request.method`, `http.route`, `http.response.status_code`, `user_agent.original` |
79+
| SQL file execution | `code.file.path` — which `.sql` file was executed |
80+
| `db.pool.acquire` | `db.client.connection.pool.name`; `sqlpage.db.pool.size` — current pool size when acquiring |
81+
| `db.query` | `db.query.text` — the full SQL text; `db.system.name` — database type |
8282

8383
### What you will see in the logs
8484

8585
SQLPage writes one structured log line per event, for example:
8686

8787
```text
88-
ts=2026-03-08T20:56:15.000Z level=info target=sqlpage::webserver::http msg="request completed" method=GET path=/ trace_id=4f2d...
88+
ts=2026-03-08T20:56:15.000Z level=info target=sqlpage::webserver::http msg="request completed" http.request.method=GET url.path=/ trace_id=4f2d...
8989
```
9090

9191
The OpenTelemetry Collector receives these SQLPage container logs through Docker's syslog

examples/telemetry/nginx/nginx.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ http {
2020
}
2121

2222
log_format otel_request 'ts=$time_iso8601 level=$log_level target=$log_target '
23-
'client_ip=$remote_addr method=$request_method path="$uri" '
23+
'client.address=$remote_addr method=$request_method path="$uri" '
2424
'status=$status request_time=$request_time '
2525
'connection=$connection '
2626
'upstream_addr="$upstream_addr" upstream_status="$upstream_status" '

src/telemetry.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ fn set_global_subscriber(subscriber: impl tracing::Subscriber + Send + Sync) ->
370370
///
371371
/// Outputs one line per event in logfmt format with carefully chosen fields:
372372
/// ```text
373-
/// ts=2026-03-08T20:56:15Z level=error target=sqlpage::webserver::error msg="..." method=GET path=/foo client_ip=1.2.3.4 trace_id=abc123
373+
/// ts=2026-03-08T20:56:15Z level=error target=sqlpage::webserver::error msg="..." http.request.method=GET url.path=/foo client.address=1.2.3.4 trace_id=abc123
374374
/// ```
375375
///
376376
/// With terminal colors when stderr is a TTY.
@@ -415,11 +415,14 @@ mod logfmt {
415415
/// Fields we pick from spans, in display order.
416416
/// (`span_field_name`, `logfmt_key`)
417417
const SPAN_FIELDS: &[(&str, &str)] = &[
418-
(otel::HTTP_REQUEST_METHOD, "method"),
419-
(otel::URL_PATH, "path"),
420-
(otel::HTTP_RESPONSE_STATUS_CODE, "status"),
421-
("sqlpage.file", "file"),
422-
(otel::CLIENT_ADDRESS, "client_ip"),
418+
(otel::HTTP_REQUEST_METHOD, otel::HTTP_REQUEST_METHOD),
419+
(otel::URL_PATH, otel::URL_PATH),
420+
(
421+
otel::HTTP_RESPONSE_STATUS_CODE,
422+
otel::HTTP_RESPONSE_STATUS_CODE,
423+
),
424+
(otel::CODE_FILE_PATH, otel::CODE_FILE_PATH),
425+
(otel::CLIENT_ADDRESS, otel::CLIENT_ADDRESS),
423426
];
424427

425428
/// All-zeros trace ID means no real trace context.
@@ -780,7 +783,10 @@ mod logfmt {
780783

781784
write_span_field_maps(&mut buf, [&span_fields], true);
782785

783-
assert_eq!(buf, " method=GET http.route=/users/:id otel.kind=server");
786+
assert_eq!(
787+
buf,
788+
" http.request.method=GET http.route=/users/:id otel.kind=server"
789+
);
784790
}
785791

786792
#[test]
@@ -794,7 +800,7 @@ mod logfmt {
794800

795801
write_span_field_maps(&mut buf, [&span_fields], false);
796802

797-
assert_eq!(buf, " method=GET");
803+
assert_eq!(buf, " http.request.method=GET");
798804
}
799805

800806
#[test]

src/webserver/database/execute_queries.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl<'a> DbQueryMetricsContext<'a> {
9898
self.span
9999
.record(otel::EXCEPTION_MESSAGE, tracing::field::display(error));
100100
self.span
101-
.record("exception.details", tracing::field::debug(error));
101+
.record("sqlpage.exception.details", tracing::field::debug(error));
102102
let attributes = [
103103
opentelemetry::KeyValue::new(otel::DB_SYSTEM_NAME, self.db_system_name),
104104
opentelemetry::KeyValue::new(otel::DB_OPERATION_NAME, self.operation_name.clone()),
@@ -127,7 +127,7 @@ fn create_db_query_span(
127127
{ otel::CODE_LINE_NUMBER } = source_line_number(line),
128128
{ otel::OTEL_STATUS_CODE } = tracing::field::Empty,
129129
{ otel::EXCEPTION_MESSAGE } = tracing::field::Empty,
130-
"exception.details" = tracing::field::Empty,
130+
"sqlpage.exception.details" = tracing::field::Empty,
131131
{ otel::DB_RESPONSE_RETURNED_ROWS } = tracing::field::Empty,
132132
);
133133
(span, operation_name)
@@ -456,7 +456,12 @@ async fn take_connection<'a>(
456456
return Ok(c);
457457
}
458458
let pool_size = db.connection.size();
459-
let acquire_span = tracing::info_span!("db.pool.acquire", db.pool.size = pool_size,);
459+
let acquire_span = tracing::info_span!(
460+
"db.pool.acquire",
461+
{ otel::DB_SYSTEM_NAME } = db.info.database_type.otel_name(),
462+
{ otel::DB_CLIENT_CONNECTION_POOL_NAME } = "sqlpage",
463+
sqlpage.db.pool.size = pool_size,
464+
);
460465
match db.connection.acquire().instrument(acquire_span).await {
461466
Ok(c) => {
462467
log::debug!("Acquired a database connection");
@@ -895,7 +900,7 @@ mod tests {
895900
"db.query",
896901
otel.status_code = tracing::field::Empty,
897902
exception.message = tracing::field::Empty,
898-
exception.details = tracing::field::Empty,
903+
sqlpage.exception.details = tracing::field::Empty,
899904
db.response.returned_rows = tracing::field::Empty,
900905
);
901906
let metrics = crate::telemetry_metrics::TelemetryMetrics::default();
@@ -908,7 +913,7 @@ mod tests {
908913
assert_eq!(fields[otel::OTEL_STATUS_CODE], "OK");
909914
assert_eq!(fields[otel::DB_RESPONSE_RETURNED_ROWS], "3");
910915
assert!(!fields.contains_key(otel::EXCEPTION_MESSAGE));
911-
assert!(!fields.contains_key("exception.details"));
916+
assert!(!fields.contains_key("sqlpage.exception.details"));
912917
}
913918

914919
#[test]
@@ -918,7 +923,7 @@ mod tests {
918923
"db.query",
919924
otel.status_code = tracing::field::Empty,
920925
exception.message = tracing::field::Empty,
921-
exception.details = tracing::field::Empty,
926+
sqlpage.exception.details = tracing::field::Empty,
922927
db.response.returned_rows = tracing::field::Empty,
923928
);
924929
let error = anyhow!("query failed").context("while executing SELECT 1");
@@ -932,6 +937,6 @@ mod tests {
932937
assert_eq!(fields[otel::OTEL_STATUS_CODE], "ERROR");
933938
assert_eq!(fields[otel::DB_RESPONSE_RETURNED_ROWS], "2");
934939
assert!(fields[otel::EXCEPTION_MESSAGE].contains("while executing SELECT 1"));
935-
assert!(fields["exception.details"].contains("query failed"));
940+
assert!(fields["sqlpage.exception.details"].contains("query failed"));
936941
}
937942
}

src/webserver/http.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ async fn render_sql(
241241
let parse_span = tracing::info_span!(
242242
"http.parse_request",
243243
http.request.method = %srv_req.method(),
244-
http.request.header.content_type = content_type,
244+
"http.request.header.content-type" = content_type,
245245
http.request.body.size = content_length,
246246
url.query = url_query,
247247
);
@@ -359,7 +359,7 @@ impl RootSpanBuilder for SqlPageRootSpanBuilder {
359359
{ otel::OTEL_STATUS_CODE } = tracing::field::Empty,
360360
request_id = %request_id,
361361
{ otel::EXCEPTION_MESSAGE } = tracing::field::Empty,
362-
"exception.details" = tracing::field::Empty,
362+
"sqlpage.exception.details" = tracing::field::Empty,
363363
);
364364
std::mem::drop(connection_info);
365365
tracing_actix_web::root_span_macro::private::set_otel_parent(request, &span);

0 commit comments

Comments
 (0)