@@ -13,6 +13,7 @@ use tracing_subscriber::registry::LookupSpan;
13
13
use tracing_subscriber:: Layer ;
14
14
15
15
static SPAN_NAME_FIELD : & str = "otel.name" ;
16
+ static SPAN_KIND_FIELD : & str = "otel.kind" ;
16
17
17
18
/// An [OpenTelemetry] propagation layer for use in a project that uses
18
19
/// [tracing].
@@ -133,6 +134,22 @@ pub(crate) fn build_span_context(
133
134
api:: SpanContext :: new ( trace_id, span_id, trace_flags, false )
134
135
}
135
136
137
+ fn str_to_span_kind ( s : & str ) -> Option < api:: SpanKind > {
138
+ if s. eq_ignore_ascii_case ( "SERVER" ) {
139
+ Some ( api:: SpanKind :: Server )
140
+ } else if s. eq_ignore_ascii_case ( "CLIENT" ) {
141
+ Some ( api:: SpanKind :: Client )
142
+ } else if s. eq_ignore_ascii_case ( "PRODUCER" ) {
143
+ Some ( api:: SpanKind :: Producer )
144
+ } else if s. eq_ignore_ascii_case ( "CONSUMER" ) {
145
+ Some ( api:: SpanKind :: Consumer )
146
+ } else if s. eq_ignore_ascii_case ( "INTERNAL" ) {
147
+ Some ( api:: SpanKind :: Internal )
148
+ } else {
149
+ None
150
+ }
151
+ }
152
+
136
153
struct SpanEventVisitor < ' a > ( & ' a mut api:: Event ) ;
137
154
138
155
impl < ' a > field:: Visit for SpanEventVisitor < ' a > {
@@ -179,6 +196,8 @@ impl<'a> field::Visit for SpanAttributeVisitor<'a> {
179
196
fn record_str ( & mut self , field : & field:: Field , value : & str ) {
180
197
if field. name ( ) == SPAN_NAME_FIELD {
181
198
self . 0 . name = value. to_string ( ) ;
199
+ } else if field. name ( ) == SPAN_KIND_FIELD {
200
+ self . 0 . span_kind = str_to_span_kind ( value) ;
182
201
} else {
183
202
let attribute = api:: KeyValue :: new ( field. name ( ) , value) ;
184
203
if let Some ( attributes) = & mut self . 0 . attributes {
@@ -196,6 +215,8 @@ impl<'a> field::Visit for SpanAttributeVisitor<'a> {
196
215
fn record_debug ( & mut self , field : & field:: Field , value : & dyn fmt:: Debug ) {
197
216
if field. name ( ) == SPAN_NAME_FIELD {
198
217
self . 0 . name = format ! ( "{:?}" , value) ;
218
+ } else if field. name ( ) == SPAN_KIND_FIELD {
219
+ self . 0 . span_kind = str_to_span_kind ( & format ! ( "{:?}" , value) ) ;
199
220
} else {
200
221
let attribute = api:: Key :: new ( field. name ( ) ) . string ( format ! ( "{:?}" , value) ) ;
201
222
if let Some ( attributes) = & mut self . 0 . attributes {
@@ -594,4 +615,17 @@ mod tests {
594
615
let recorded_name = tracer. 0 . lock ( ) . unwrap ( ) . as_ref ( ) . map ( |b| b. name . clone ( ) ) ;
595
616
assert_eq ! ( recorded_name, Some ( dynamic_name) )
596
617
}
618
+
619
+ #[ test]
620
+ fn span_kind ( ) {
621
+ let tracer = TestTracer ( Arc :: new ( Mutex :: new ( None ) ) ) ;
622
+ let subscriber = tracing_subscriber:: registry ( ) . with ( layer ( ) . with_tracer ( tracer. clone ( ) ) ) ;
623
+
624
+ tracing:: subscriber:: with_default ( subscriber, || {
625
+ tracing:: debug_span!( "request" , otel. kind = "Server" ) ;
626
+ } ) ;
627
+
628
+ let recorded_kind = tracer. 0 . lock ( ) . unwrap ( ) . as_ref ( ) . unwrap ( ) . span_kind . clone ( ) ;
629
+ assert_eq ! ( recorded_kind, Some ( api:: SpanKind :: Server ) )
630
+ }
597
631
}
0 commit comments