@@ -222,6 +222,8 @@ module TraceContext = struct
222
222
223
223
let empty = {traceparent= None ; baggage= None }
224
224
225
+ let depth_key = " span.depth"
226
+
225
227
let with_traceparent traceparent ctx = {ctx with traceparent}
226
228
227
229
let with_baggage baggage ctx = {ctx with baggage}
@@ -230,6 +232,20 @@ module TraceContext = struct
230
232
231
233
let baggage_of ctx = ctx.baggage
232
234
235
+ let baggage_depth_of ctx =
236
+ Option. bind (baggage_of ctx) (List. assoc_opt depth_key)
237
+ |> Option. value ~default: " 1"
238
+ |> int_of_string
239
+
240
+ let update_with_baggage k v ctx =
241
+ let new_baggage =
242
+ baggage_of ctx
243
+ |> Option. value ~default: []
244
+ |> List. remove_assoc k
245
+ |> List. cons (k, v)
246
+ in
247
+ with_baggage (Some new_baggage) ctx
248
+
233
249
let parse input =
234
250
let open Astring.String in
235
251
let trim_pair (key , value ) = (trim key, trim value) in
@@ -322,22 +338,36 @@ module Span = struct
322
338
323
339
let start ?(attributes = Attributes. empty)
324
340
?(trace_context : TraceContext.t option ) ~name ~parent ~span_kind () =
325
- let trace_id, extra_context =
341
+ let trace_id, extra_context, depth =
326
342
match parent with
327
343
| None ->
328
- (Trace_id. make () , TraceContext. empty)
344
+ (Trace_id. make () , TraceContext. empty, 1 )
329
345
| Some span_parent ->
330
- (span_parent.context.trace_id, span_parent.context.trace_context)
346
+ ( span_parent.context.trace_id
347
+ , span_parent.context.trace_context
348
+ , TraceContext. baggage_depth_of span_parent.context.trace_context + 1
349
+ )
331
350
in
332
351
let span_id = Span_id. make () in
352
+ let extra_context_with_depth =
353
+ TraceContext. (
354
+ with_added_baggage depth_key (string_of_int depth) extra_context
355
+ )
356
+ in
333
357
let context : SpanContext.t =
334
- {trace_id; span_id; trace_context= extra_context }
358
+ {trace_id; span_id; trace_context= extra_context_with_depth }
335
359
in
336
360
let context =
337
- (* If trace_context is provided to the call, override any inherited trace context. *)
338
- trace_context
339
- |> Option. fold ~none: context
340
- ~some: (Fun. flip SpanContext. with_trace_context context)
361
+ (* If trace_context is provided to the call, override any inherited trace
362
+ context except span.depth which should still be maintained. *)
363
+ match trace_context with
364
+ | Some tc ->
365
+ let tc_with_depth =
366
+ TraceContext. (with_added_baggage depth_key (string_of_int depth) tc)
367
+ in
368
+ SpanContext. with_trace_context tc_with_depth context
369
+ | None ->
370
+ context
341
371
in
342
372
(* Using gettimeofday over Mtime as it is better for sharing timestamps between the systems *)
343
373
let begin_time = Unix. gettimeofday () in
@@ -473,6 +503,11 @@ module Spans = struct
473
503
474
504
let set_max_traces x = Atomic. set max_traces x
475
505
506
+ (* Default is much larger than the largest current traces, so effectively off *)
507
+ let max_depth = Atomic. make 100
508
+
509
+ let set_max_depth x = Atomic. set max_depth x
510
+
476
511
let finished_spans = Atomic. make ([] , 0 )
477
512
478
513
let span_hashtbl_is_empty () = TraceMap. is_empty (Atomic. get spans)
@@ -713,12 +748,18 @@ module Tracer = struct
713
748
let get_tracer ~name :_ = TracerProvider. get_current ()
714
749
715
750
let span_of_span_context context name : Span.t =
751
+ let tc = SpanContext. context_of_span_context context in
752
+ let new_depth = TraceContext. baggage_depth_of tc in
753
+ let new_tc =
754
+ TraceContext. (with_added_baggage depth_key (string_of_int new_depth) tc)
755
+ in
756
+ let context = SpanContext. with_trace_context new_tc context in
716
757
{
717
758
context
718
759
; status= {status_code= Status. Unset ; _description= None }
719
760
; name
720
761
; parent= None
721
- ; span_kind= SpanKind. Client (* This will be the span of the client call*)
762
+ ; span_kind= SpanKind. Client (* This will be the span of the client call *)
722
763
; begin_time= Unix. gettimeofday ()
723
764
; end_time= None
724
765
; links= []
@@ -730,10 +771,23 @@ module Tracer = struct
730
771
?(span_kind = SpanKind. Internal ) ~name ~parent () :
731
772
(Span. t option , exn ) result =
732
773
let open TracerProvider in
733
- (* Do not start span if the TracerProvider is disabled*)
774
+ let parent_depth =
775
+ Option. fold ~none: 1
776
+ ~some: (fun parent ->
777
+ parent.Span. context
778
+ |> SpanContext. context_of_span_context
779
+ |> TraceContext. baggage_depth_of
780
+ )
781
+ parent
782
+ in
783
+ (* Do not start span if the TracerProvider is disabled *)
734
784
if not t.enabled then
785
+ ok_none (* Do not start span if the max depth has been reached *)
786
+ else if parent_depth > = Atomic. get Spans. max_depth then (
787
+ let parent_trace_id = Option. fold ~none: " None" ~some: (fun p -> p.Span. context |> SpanContext. span_id_of_span_context |> Span_id. to_string) parent in
788
+ debug " Max_span_depth limit reached, not creating span %s (parent %s)" name parent_trace_id ;
735
789
ok_none
736
- else
790
+ ) else
737
791
let attributes = Attributes. merge_into t.attributes attributes in
738
792
let span =
739
793
Span. start ~attributes ?trace_context ~name ~parent ~span_kind ()
@@ -750,16 +804,24 @@ module Tracer = struct
750
804
|> Spans. remove_from_spans
751
805
|> Option. map (fun existing_span ->
752
806
let old_context = Span. get_context existing_span in
807
+ let parent_trace_context = Span. get_trace_context parent in
808
+ let new_depth =
809
+ TraceContext. baggage_depth_of parent_trace_context + 1
810
+ in
753
811
let new_context : SpanContext.t =
754
- let trace_context = span.Span. context.trace_context in
812
+ let trace_context =
813
+ TraceContext. (
814
+ with_added_baggage depth_key (string_of_int new_depth)
815
+ span.Span. context.trace_context
816
+ )
817
+ in
755
818
SpanContext. context
756
819
(SpanContext. trace_id_of_span_context parent.context)
757
820
old_context.span_id
758
821
|> SpanContext. with_trace_context trace_context
759
822
in
760
823
let updated_span = {existing_span with parent= Some parent} in
761
824
let updated_span = {updated_span with context= new_context} in
762
-
763
825
let () = Spans. add_to_spans ~span: updated_span in
764
826
updated_span
765
827
)
@@ -926,7 +988,15 @@ module Propagator = struct
926
988
let trace_context' =
927
989
TraceContext. with_traceparent (Some traceparent) trace_context
928
990
in
929
- let carrier' = P. inject_into trace_context' carrier in
991
+ let new_depth =
992
+ TraceContext. baggage_depth_of trace_context' + 1 |> string_of_int
993
+ in
994
+ let trace_context'' =
995
+ TraceContext. (
996
+ with_added_baggage depth_key new_depth trace_context'
997
+ )
998
+ in
999
+ let carrier' = P. inject_into trace_context'' carrier in
930
1000
f carrier'
931
1001
| _ ->
932
1002
f carrier
0 commit comments