@@ -25,6 +25,14 @@ use opentelemetry::{
25
25
Context ,
26
26
trace:: { SpanKind , TraceContextExt } ,
27
27
} ;
28
+ use opentelemetry_semantic_conventions:: {
29
+ attribute:: { OTEL_STATUS_CODE , OTEL_STATUS_DESCRIPTION } ,
30
+ trace:: {
31
+ CLIENT_ADDRESS , CLIENT_PORT , HTTP_REQUEST_HEADER , HTTP_REQUEST_METHOD ,
32
+ HTTP_RESPONSE_STATUS_CODE , HTTP_ROUTE , SERVER_ADDRESS , SERVER_PORT , URL_PATH , URL_QUERY ,
33
+ URL_SCHEME , USER_AGENT_ORIGINAL ,
34
+ } ,
35
+ } ;
28
36
use pin_project:: pin_project;
29
37
use snafu:: { ResultExt , Snafu } ;
30
38
use tower:: { Layer , Service } ;
@@ -41,6 +49,14 @@ const X_FORWARDED_HOST_HEADER_KEY: &str = "X-Forwarded-Host";
41
49
const DEFAULT_HTTPS_PORT : u16 = 443 ;
42
50
const DEFAULT_HTTP_PORT : u16 = 80 ;
43
51
52
+ // NOTE (@Techassi): These constants are defined here because they are private in
53
+ // the tracing-opentelemetry crate.
54
+ const OTEL_NAME : & str = "otel.name" ;
55
+ const OTEL_KIND : & str = "otel.kind" ;
56
+
57
+ const OTEL_TRACE_ID_FROM : & str = "opentelemetry.trace_id.from" ;
58
+ const OTEL_TRACE_ID_TO : & str = "opentelemetry.trace_id.to" ;
59
+
44
60
/// A Tower [`Layer`][1] which decorates [`TraceService`].
45
61
///
46
62
/// ### Example with Axum
@@ -414,21 +430,23 @@ impl SpanExt for Span {
414
430
415
431
let span = tracing:: trace_span!(
416
432
"HTTP request" ,
417
- "otel.name" = span_name,
418
- "otel.kind" = ?SpanKind :: Server ,
419
- "otel.status_code" = Empty ,
420
- "otel.status_message" = Empty ,
421
- "http.request.method" = http_method,
422
- "http.response.status_code" = Empty ,
423
- "http.route" = Empty ,
424
- "url.path" = url. path( ) ,
425
- "url.query" = url. query( ) ,
426
- "url.scheme" = url. scheme_str( ) . unwrap_or_default( ) ,
427
- "user_agent.original" = Empty ,
428
- "server.address" = Empty ,
429
- "server.port" = Empty ,
430
- "client.address" = Empty ,
431
- "client.port" = Empty ,
433
+ { OTEL_NAME } = span_name,
434
+ { OTEL_KIND } = ?SpanKind :: Server ,
435
+ { OTEL_STATUS_CODE } = Empty ,
436
+ // The current tracing-opentelemetry version still uses the old semantic convention
437
+ // See https://github.com/tokio-rs/tracing-opentelemetry/pull/209
438
+ { OTEL_STATUS_DESCRIPTION } = Empty ,
439
+ { HTTP_REQUEST_METHOD } = http_method,
440
+ { HTTP_RESPONSE_STATUS_CODE } = Empty ,
441
+ { HTTP_ROUTE } = Empty ,
442
+ { URL_PATH } = url. path( ) ,
443
+ { URL_QUERY } = url. query( ) ,
444
+ { URL_SCHEME } = url. scheme_str( ) . unwrap_or_default( ) ,
445
+ { USER_AGENT_ORIGINAL } = Empty ,
446
+ { SERVER_ADDRESS } = Empty ,
447
+ { SERVER_PORT } = Empty ,
448
+ { CLIENT_ADDRESS } = Empty ,
449
+ { CLIENT_PORT } = Empty ,
432
450
// TODO (@Techassi): Add network.protocol.version
433
451
) ;
434
452
@@ -462,8 +480,8 @@ impl SpanExt for Span {
462
480
463
481
if new_span_context != current_span_context {
464
482
tracing:: trace!(
465
- opentelemetry . trace_id . from = ?current_span_context. trace_id( ) ,
466
- opentelemetry . trace_id . to = ?new_span_context. trace_id( ) ,
483
+ { OTEL_TRACE_ID_FROM } = ?current_span_context. trace_id( ) ,
484
+ { OTEL_TRACE_ID_TO } = ?new_span_context. trace_id( ) ,
467
485
"set parent span context based on context extracted from request headers"
468
486
) ;
469
487
@@ -473,7 +491,7 @@ impl SpanExt for Span {
473
491
}
474
492
475
493
if let Some ( user_agent) = req. user_agent ( ) {
476
- span. record ( "user_agent.original" , user_agent) ;
494
+ span. record ( USER_AGENT_ORIGINAL , user_agent) ;
477
495
}
478
496
479
497
// Setting server.address and server.port
@@ -483,21 +501,21 @@ impl SpanExt for Span {
483
501
// NOTE (@Techassi): We cast to i64, because otherwise the field
484
502
// will NOT be recorded as a number but as a string. This is likely
485
503
// an issue in the tracing-opentelemetry crate.
486
- span. record ( "server.address" , host)
487
- . record ( "server.port" , port as i64 ) ;
504
+ span. record ( SERVER_ADDRESS , host)
505
+ . record ( SERVER_PORT , port as i64 ) ;
488
506
}
489
507
490
508
// Setting fields according to the HTTP server semantic conventions
491
509
// See https://opentelemetry.io/docs/specs/semconv/http/http-spans/#http-server-semantic-conventions
492
510
493
511
if let Some ( client_socket_address) = req. client_socket_address ( ) {
494
- span. record ( "client.address" , client_socket_address. ip ( ) . to_string ( ) ) ;
512
+ span. record ( CLIENT_ADDRESS , client_socket_address. ip ( ) . to_string ( ) ) ;
495
513
496
514
if opt_in {
497
515
// NOTE (@Techassi): We cast to i64, because otherwise the field
498
516
// will NOT be recorded as a number but as a string. This is
499
517
// likely an issue in the tracing-opentelemetry crate.
500
- span. record ( "client.port" , client_socket_address. port ( ) as i64 ) ;
518
+ span. record ( CLIENT_PORT , client_socket_address. port ( ) as i64 ) ;
501
519
}
502
520
}
503
521
@@ -511,7 +529,7 @@ impl SpanExt for Span {
511
529
// See: https://github.com/tokio-rs/tracing/issues/1343
512
530
513
531
if let Some ( http_route) = req. matched_path ( ) {
514
- span. record ( "http.route" , http_route. as_str ( ) ) ;
532
+ span. record ( HTTP_ROUTE , http_route. as_str ( ) ) ;
515
533
}
516
534
517
535
span
@@ -525,7 +543,7 @@ impl SpanExt for Span {
525
543
// header_name.as_str() always returns lowercase strings and thus we
526
544
// don't need to call to_lowercase on it.
527
545
let header_name = header_name. as_str ( ) ;
528
- let field_name = format ! ( "http.request.header .{header_name}" ) ;
546
+ let field_name = format ! ( "{HTTP_REQUEST_HEADER} .{header_name}" ) ;
529
547
530
548
self . record (
531
549
field_name. as_str ( ) ,
@@ -540,15 +558,15 @@ impl SpanExt for Span {
540
558
// NOTE (@Techassi): We cast to i64, because otherwise the field will
541
559
// NOT be recorded as a number but as a string. This is likely an issue
542
560
// in the tracing-opentelemetry crate.
543
- self . record ( "http.response.status_code" , status_code. as_u16 ( ) as i64 ) ;
561
+ self . record ( HTTP_RESPONSE_STATUS_CODE , status_code. as_u16 ( ) as i64 ) ;
544
562
545
563
// Only set the span status to "Error" when we encountered an server
546
564
// error. See:
547
565
//
548
566
// - https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
549
567
// - https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/trace/api.md#set-status
550
568
if status_code. is_server_error ( ) {
551
- self . record ( "otel.status_code" , "Error" ) ;
569
+ self . record ( OTEL_STATUS_CODE , "Error" ) ;
552
570
// NOTE (@Techassi): Can we add a status_description here as well?
553
571
}
554
572
@@ -561,8 +579,9 @@ impl SpanExt for Span {
561
579
E : std:: error:: Error ,
562
580
{
563
581
// NOTE (@Techassi): This field might get renamed: https://github.com/tokio-rs/tracing-opentelemetry/issues/115
564
- self . record ( "otel.status_code" , "Error" )
565
- . record ( "otel.status_message" , error. to_string ( ) ) ;
582
+ // NOTE (@Techassi): It got renamed, a fixed version of tracing-opentelemetry is not available yet
583
+ self . record ( OTEL_STATUS_CODE , "Error" )
584
+ . record ( OTEL_STATUS_DESCRIPTION , error. to_string ( ) ) ;
566
585
}
567
586
}
568
587
0 commit comments