mirror of
https://github.com/ocaml-tracing/ocaml-trace.git
synced 2026-03-09 20:33:34 -04:00
remove trace_id entirely, use meta-maps in more places
The direct use of span_id+trace_id in OTEL is a bad idea, and it makes little sense in other collectors. In the end, `span` should be thought of as an opaque key only the collector understands, and a meta-map should be carried around for the collector to stash additional info such as a (8B, 16B, ...) trace ID or other information.
This commit is contained in:
parent
ef35cc1d79
commit
8b747053d7
12 changed files with 118 additions and 121 deletions
|
|
@ -7,13 +7,11 @@
|
||||||
open Types
|
open Types
|
||||||
|
|
||||||
let dummy_span : span = Int64.min_int
|
let dummy_span : span = Int64.min_int
|
||||||
let dummy_trace_id : trace_id = "<dummy>"
|
|
||||||
|
|
||||||
let dummy_explicit_span : explicit_span =
|
let dummy_explicit_span : explicit_span =
|
||||||
{ span = dummy_span; trace_id = dummy_trace_id; meta = Meta_map.empty }
|
{ span = dummy_span; meta = Meta_map.empty }
|
||||||
|
|
||||||
let dummy_explicit_span_ctx : explicit_span_ctx =
|
let dummy_explicit_span_ctx : explicit_span_ctx = { meta = Meta_map.empty }
|
||||||
{ span = dummy_span; trace_id = dummy_trace_id }
|
|
||||||
|
|
||||||
(** Signature for a collector.
|
(** Signature for a collector.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ let current_level_ = A.make Level.Trace
|
||||||
(* ## implementation ## *)
|
(* ## implementation ## *)
|
||||||
|
|
||||||
let[@inline] ctx_of_span (sp : explicit_span) : explicit_span_ctx =
|
let[@inline] ctx_of_span (sp : explicit_span) : explicit_span_ctx =
|
||||||
{ span = sp.span; trace_id = sp.trace_id }
|
{ meta = sp.meta }
|
||||||
|
|
||||||
let data_empty_build_ () = []
|
let data_empty_build_ () = []
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
|
(** Common types definitions.
|
||||||
|
|
||||||
|
The type [trace_id] was added in 0.10 and removed in NEXT_RELEASE, as it's
|
||||||
|
simply more flexible to use a meta-map ([Hmap.t] in the better case). *)
|
||||||
|
|
||||||
type span = int64
|
type span = int64
|
||||||
(** A span identifier.
|
(** A span identifier.
|
||||||
|
|
||||||
The meaning of the identifier depends on the collector. *)
|
The meaning of the identifier depends on the collector. *)
|
||||||
|
|
||||||
type trace_id = string
|
|
||||||
(** A bytestring representing a (possibly distributed) trace made of async
|
|
||||||
spans. With opentelemetry this is 16 bytes.
|
|
||||||
@since 0.10 *)
|
|
||||||
|
|
||||||
type user_data =
|
type user_data =
|
||||||
[ `Int of int
|
[ `Int of int
|
||||||
| `String of string
|
| `String of string
|
||||||
|
|
@ -26,17 +26,24 @@ type span_flavor =
|
||||||
@since NEXT_RELEASE *)
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
type explicit_span_ctx = {
|
type explicit_span_ctx = {
|
||||||
span: span; (** The current span *)
|
meta: Meta_map.t;
|
||||||
trace_id: trace_id; (** The trace this belongs to *)
|
(** Metadata for this span and its context. This can be used to store
|
||||||
|
trace IDs, attributes, etc. in a collector-specific way. *)
|
||||||
}
|
}
|
||||||
(** A context, passed around for async traces.
|
[@@unboxed]
|
||||||
@since 0.10 *)
|
(** A context, passed around for async traces. It might not correspond to any
|
||||||
|
span created via [Trace] at all, e.g. it might be built in a HTTP handler
|
||||||
|
from a {{:https://www.w3.org/TR/trace-context/} W3C trace contxt} header.
|
||||||
|
|
||||||
|
@since 0.10
|
||||||
|
|
||||||
|
The fields [span] and [trace_id] were removed in NEXT_RELEASE. Please use
|
||||||
|
the meta map instead. *)
|
||||||
|
|
||||||
type explicit_span = {
|
type explicit_span = {
|
||||||
span: span;
|
span: span;
|
||||||
(** Identifier for this span. Several explicit spans might share the same
|
(** Identifier for this span. Several explicit spans might share the same
|
||||||
identifier since we can differentiate between them via [meta]. *)
|
identifier since we can differentiate between them via [meta]. *)
|
||||||
trace_id: trace_id; (** The trace this belongs to *)
|
|
||||||
mutable meta: Meta_map.t;
|
mutable meta: Meta_map.t;
|
||||||
(** Metadata for this span (and its context). This can be used by
|
(** Metadata for this span (and its context). This can be used by
|
||||||
collectors to carry collector-specific information from the beginning
|
collectors to carry collector-specific information from the beginning
|
||||||
|
|
@ -44,7 +51,10 @@ type explicit_span = {
|
||||||
}
|
}
|
||||||
(** Explicit span, with collector-specific metadata. This is richer than
|
(** Explicit span, with collector-specific metadata. This is richer than
|
||||||
{!explicit_span_ctx} but not intended to be passed around (or sent across
|
{!explicit_span_ctx} but not intended to be passed around (or sent across
|
||||||
the wire), unlike {!explicit_span_ctx}. *)
|
the wire), unlike {!explicit_span_ctx}.
|
||||||
|
|
||||||
|
The field [trace_id] was removed in NEXT_RELEASE, please use the meta map
|
||||||
|
instead. *)
|
||||||
|
|
||||||
type extension_event = ..
|
type extension_event = ..
|
||||||
(** An extension event, used to add features that are backend specific or simply
|
(** An extension event, used to add features that are backend specific or simply
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ type t =
|
||||||
tid: int;
|
tid: int;
|
||||||
name: string;
|
name: string;
|
||||||
time_ns: int64;
|
time_ns: int64;
|
||||||
id: trace_id;
|
|
||||||
flavor: span_flavor option;
|
flavor: span_flavor option;
|
||||||
fun_name: string option;
|
fun_name: string option;
|
||||||
data: (string * user_data) list;
|
data: (string * user_data) list;
|
||||||
|
|
@ -48,7 +47,6 @@ type t =
|
||||||
time_ns: int64;
|
time_ns: int64;
|
||||||
flavor: span_flavor option;
|
flavor: span_flavor option;
|
||||||
data: (string * user_data) list;
|
data: (string * user_data) list;
|
||||||
id: trace_id;
|
|
||||||
}
|
}
|
||||||
| E_counter of {
|
| E_counter of {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,17 @@ open struct
|
||||||
(* just use the same ones for everyone *)
|
(* just use the same ones for everyone *)
|
||||||
|
|
||||||
let span_gen = Sub.Span_generator.create ()
|
let span_gen = Sub.Span_generator.create ()
|
||||||
let trace_id_gen = Sub.Trace_id_8B_generator.create ()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Callbacks : Sub.Callbacks.S with type st = event_consumer = struct
|
module Callbacks : Sub.Callbacks.S with type st = event_consumer = struct
|
||||||
type st = event_consumer
|
type st = event_consumer
|
||||||
|
|
||||||
let new_span (_self : st) = Sub.Span_generator.mk_span span_gen
|
let new_span (_self : st) = Sub.Span_generator.mk_span span_gen
|
||||||
let new_trace_id _self = Sub.Trace_id_8B_generator.mk_trace_id trace_id_gen
|
|
||||||
|
let new_explicit_span _self ~parent:_ =
|
||||||
|
let span = Sub.Span_generator.mk_span span_gen in
|
||||||
|
{ span; meta = Meta_map.empty }
|
||||||
|
|
||||||
let on_init (self : st) ~time_ns = self.on_event (E_init { time_ns })
|
let on_init (self : st) ~time_ns = self.on_event (E_init { time_ns })
|
||||||
let on_shutdown (self : st) ~time_ns = self.on_event (E_shutdown { time_ns })
|
let on_shutdown (self : st) ~time_ns = self.on_event (E_shutdown { time_ns })
|
||||||
|
|
||||||
|
|
@ -45,16 +48,13 @@ module Callbacks : Sub.Callbacks.S with type st = event_consumer = struct
|
||||||
self.on_event @@ E_counter { name; n = f; time_ns; tid }
|
self.on_event @@ E_counter { name; n = f; time_ns; tid }
|
||||||
|
|
||||||
let on_enter_manual_span (self : st) ~__FUNCTION__:fun_name ~__FILE__:_
|
let on_enter_manual_span (self : st) ~__FUNCTION__:fun_name ~__FILE__:_
|
||||||
~__LINE__:_ ~time_ns ~tid ~parent:_ ~data ~name ~flavor ~trace_id _span :
|
~__LINE__:_ ~time_ns ~tid ~parent:_ ~data ~name ~flavor _span : unit =
|
||||||
unit =
|
|
||||||
self.on_event
|
self.on_event
|
||||||
@@ E_enter_manual_span
|
@@ E_enter_manual_span { time_ns; tid; data; name; fun_name; flavor }
|
||||||
{ id = trace_id; time_ns; tid; data; name; fun_name; flavor }
|
|
||||||
|
|
||||||
let on_exit_manual_span (self : st) ~time_ns ~tid ~name ~data ~flavor
|
let on_exit_manual_span (self : st) ~time_ns ~tid ~name ~data ~flavor
|
||||||
~trace_id (_ : span) : unit =
|
(_ : explicit_span) : unit =
|
||||||
self.on_event
|
self.on_event @@ E_exit_manual_span { tid; name; time_ns; data; flavor }
|
||||||
@@ E_exit_manual_span { tid; id = trace_id; name; time_ns; data; flavor }
|
|
||||||
|
|
||||||
let on_extension_event (self : st) ~time_ns ~tid ext : unit =
|
let on_extension_event (self : st) ~time_ns ~tid ext : unit =
|
||||||
self.on_event @@ E_extension_event { tid; time_ns; ext }
|
self.on_event @@ E_extension_event { tid; time_ns; ext }
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ type t = {
|
||||||
buf_chain: Buf_chain.t;
|
buf_chain: Buf_chain.t;
|
||||||
exporter: Exporter.t;
|
exporter: Exporter.t;
|
||||||
span_gen: Sub.Span_generator.t;
|
span_gen: Sub.Span_generator.t;
|
||||||
trace_id_gen: Sub.Trace_id_8B_generator.t;
|
(* use the span generator, it's also 64 bits *)
|
||||||
|
trace_id_gen: Sub.Span_generator.t;
|
||||||
}
|
}
|
||||||
(** Subscriber state *)
|
(** Subscriber state *)
|
||||||
|
|
||||||
|
|
@ -49,6 +50,8 @@ open struct
|
||||||
names;
|
names;
|
||||||
flush stderr
|
flush stderr
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let k_trace_id : int64 Meta_map.key = Meta_map.Key.create ()
|
||||||
end
|
end
|
||||||
|
|
||||||
let close (self : t) : unit =
|
let close (self : t) : unit =
|
||||||
|
|
@ -76,7 +79,8 @@ let create ?(buf_pool = Buf_pool.create ()) ~pid ~exporter () : t =
|
||||||
pid;
|
pid;
|
||||||
spans = Span_tbl.create ();
|
spans = Span_tbl.create ();
|
||||||
span_gen = Sub.Span_generator.create ();
|
span_gen = Sub.Span_generator.create ();
|
||||||
trace_id_gen = Sub.Trace_id_8B_generator.create ();
|
(* NOTE: we use a span generator because it's also making [int64] values *)
|
||||||
|
trace_id_gen = Sub.Span_generator.create ();
|
||||||
}
|
}
|
||||||
|
|
||||||
module Callbacks = struct
|
module Callbacks = struct
|
||||||
|
|
@ -84,8 +88,21 @@ module Callbacks = struct
|
||||||
|
|
||||||
let new_span (self : st) = Sub.Span_generator.mk_span self.span_gen
|
let new_span (self : st) = Sub.Span_generator.mk_span self.span_gen
|
||||||
|
|
||||||
let new_trace_id self =
|
let get_trace_id_ meta : int64 =
|
||||||
Sub.Trace_id_8B_generator.mk_trace_id self.trace_id_gen
|
try Meta_map.find_exn k_trace_id meta
|
||||||
|
with _ ->
|
||||||
|
failwith "fuchsia subscriber: could not find trace_id in meta-map"
|
||||||
|
|
||||||
|
let new_explicit_span (self : st) ~(parent : explicit_span_ctx option) :
|
||||||
|
explicit_span =
|
||||||
|
let span = Sub.Span_generator.mk_span self.span_gen in
|
||||||
|
let trace_id =
|
||||||
|
match parent with
|
||||||
|
| None -> Sub.Span_generator.mk_span self.trace_id_gen
|
||||||
|
| Some p -> get_trace_id_ p.meta
|
||||||
|
in
|
||||||
|
let meta = Meta_map.(empty |> add k_trace_id trace_id) in
|
||||||
|
{ span; meta }
|
||||||
|
|
||||||
let on_init (self : st) ~time_ns:_ =
|
let on_init (self : st) ~time_ns:_ =
|
||||||
Writer.Metadata.Magic_record.encode self.buf_chain;
|
Writer.Metadata.Magic_record.encode self.buf_chain;
|
||||||
|
|
@ -164,7 +181,9 @@ module Callbacks = struct
|
||||||
write_ready_ self
|
write_ready_ self
|
||||||
|
|
||||||
let on_enter_manual_span (self : st) ~__FUNCTION__:_ ~__FILE__:_ ~__LINE__:_
|
let on_enter_manual_span (self : st) ~__FUNCTION__:_ ~__FILE__:_ ~__LINE__:_
|
||||||
~time_ns ~tid ~parent:_ ~data ~name ~flavor:_ ~trace_id _span : unit =
|
~time_ns ~tid ~parent:_ ~data ~name ~flavor:_ (span : explicit_span) :
|
||||||
|
unit =
|
||||||
|
let trace_id = get_trace_id_ span.meta in
|
||||||
Writer.(
|
Writer.(
|
||||||
Event.Async_begin.encode self.buf_chain ~name
|
Event.Async_begin.encode self.buf_chain ~name
|
||||||
~args:(args_of_user_data data)
|
~args:(args_of_user_data data)
|
||||||
|
|
@ -173,7 +192,8 @@ module Callbacks = struct
|
||||||
write_ready_ self
|
write_ready_ self
|
||||||
|
|
||||||
let on_exit_manual_span (self : st) ~time_ns ~tid ~name ~data ~flavor:_
|
let on_exit_manual_span (self : st) ~time_ns ~tid ~name ~data ~flavor:_
|
||||||
~trace_id (_ : span) : unit =
|
(span : explicit_span) : unit =
|
||||||
|
let trace_id = get_trace_id_ span.meta in
|
||||||
Writer.(
|
Writer.(
|
||||||
Event.Async_end.encode self.buf_chain ~name ~args:(args_of_user_data data)
|
Event.Async_end.encode self.buf_chain ~name ~args:(args_of_user_data data)
|
||||||
~t_ref:(Thread_ref.inline ~pid:self.pid ~tid)
|
~t_ref:(Thread_ref.inline ~pid:self.pid ~tid)
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,6 @@
|
||||||
|
|
||||||
open Common_
|
open Common_
|
||||||
module Util = Util
|
module Util = Util
|
||||||
|
|
||||||
open struct
|
|
||||||
let[@inline] int64_of_trace_id_ (id : Trace_core.trace_id) : int64 =
|
|
||||||
if id == Trace_core.Collector.dummy_trace_id then
|
|
||||||
0L
|
|
||||||
else
|
|
||||||
Bytes.get_int64_le (Bytes.unsafe_of_string id) 0
|
|
||||||
end
|
|
||||||
|
|
||||||
open Util
|
open Util
|
||||||
|
|
||||||
type user_data = Trace_core.user_data
|
type user_data = Trace_core.user_data
|
||||||
|
|
@ -491,7 +482,7 @@ module Event = struct
|
||||||
+ Arguments.size_word args + 1 (* async id *)
|
+ Arguments.size_word args + 1 (* async id *)
|
||||||
|
|
||||||
let encode (bufs : Buf_chain.t) ~name ~(t_ref : Thread_ref.t) ~time_ns
|
let encode (bufs : Buf_chain.t) ~name ~(t_ref : Thread_ref.t) ~time_ns
|
||||||
~(async_id : Trace_core.trace_id) ~args () : unit =
|
~(async_id : int64) ~args () : unit =
|
||||||
let name = truncate_string name in
|
let name = truncate_string name in
|
||||||
let size = size_word ~name ~t_ref ~args () in
|
let size = size_word ~name ~t_ref ~args () in
|
||||||
let@ buf = Buf_chain.with_buf bufs ~available_word:size in
|
let@ buf = Buf_chain.with_buf bufs ~available_word:size in
|
||||||
|
|
@ -516,7 +507,7 @@ module Event = struct
|
||||||
|
|
||||||
Buf.add_string buf name;
|
Buf.add_string buf name;
|
||||||
Arguments.encode buf args;
|
Arguments.encode buf args;
|
||||||
Buf.add_i64 buf (int64_of_trace_id_ async_id);
|
Buf.add_i64 buf async_id;
|
||||||
()
|
()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -527,7 +518,7 @@ module Event = struct
|
||||||
+ Arguments.size_word args + 1 (* async id *)
|
+ Arguments.size_word args + 1 (* async id *)
|
||||||
|
|
||||||
let encode (bufs : Buf_chain.t) ~name ~(t_ref : Thread_ref.t) ~time_ns
|
let encode (bufs : Buf_chain.t) ~name ~(t_ref : Thread_ref.t) ~time_ns
|
||||||
~(async_id : Trace_core.trace_id) ~args () : unit =
|
~(async_id : int64) ~args () : unit =
|
||||||
let name = truncate_string name in
|
let name = truncate_string name in
|
||||||
let size = size_word ~name ~t_ref ~args () in
|
let size = size_word ~name ~t_ref ~args () in
|
||||||
let@ buf = Buf_chain.with_buf bufs ~available_word:size in
|
let@ buf = Buf_chain.with_buf bufs ~available_word:size in
|
||||||
|
|
@ -552,7 +543,7 @@ module Event = struct
|
||||||
|
|
||||||
Buf.add_string buf name;
|
Buf.add_string buf name;
|
||||||
Arguments.encode buf args;
|
Arguments.encode buf args;
|
||||||
Buf.add_i64 buf (int64_of_trace_id_ async_id);
|
Buf.add_i64 buf async_id;
|
||||||
()
|
()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,9 @@ module type S = sig
|
||||||
(** How to generate a new span?
|
(** How to generate a new span?
|
||||||
@since NEXT_RELEASE *)
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val new_trace_id : st -> trace_id
|
val new_explicit_span : st -> parent:explicit_span_ctx option -> explicit_span
|
||||||
(** How to generate a new trace ID?
|
(** How to generate a new explicit span, with meta-map potentially containing
|
||||||
|
data such as a trace ID or request ID?
|
||||||
@since NEXT_RELEASE *)
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val on_shutdown : st -> time_ns:int64 -> unit
|
val on_shutdown : st -> time_ns:int64 -> unit
|
||||||
|
|
@ -96,12 +97,11 @@ module type S = sig
|
||||||
__LINE__:int ->
|
__LINE__:int ->
|
||||||
time_ns:int64 ->
|
time_ns:int64 ->
|
||||||
tid:int ->
|
tid:int ->
|
||||||
parent:span option ->
|
parent:explicit_span_ctx option ->
|
||||||
data:(string * Trace_core.user_data) list ->
|
data:(string * Trace_core.user_data) list ->
|
||||||
name:string ->
|
name:string ->
|
||||||
flavor:Trace_core.span_flavor option ->
|
flavor:Trace_core.span_flavor option ->
|
||||||
trace_id:trace_id ->
|
explicit_span ->
|
||||||
span ->
|
|
||||||
unit
|
unit
|
||||||
(** Enter a manual (possibly async) span *)
|
(** Enter a manual (possibly async) span *)
|
||||||
|
|
||||||
|
|
@ -112,8 +112,7 @@ module type S = sig
|
||||||
name:string ->
|
name:string ->
|
||||||
data:(string * Trace_core.user_data) list ->
|
data:(string * Trace_core.user_data) list ->
|
||||||
flavor:Trace_core.span_flavor option ->
|
flavor:Trace_core.span_flavor option ->
|
||||||
trace_id:trace_id ->
|
explicit_span ->
|
||||||
span ->
|
|
||||||
unit
|
unit
|
||||||
(** Exit a manual span *)
|
(** Exit a manual span *)
|
||||||
|
|
||||||
|
|
@ -142,7 +141,7 @@ type 'st t = (module S with type st = 'st)
|
||||||
module Dummy = struct
|
module Dummy = struct
|
||||||
let on_init _ ~time_ns:_ = ()
|
let on_init _ ~time_ns:_ = ()
|
||||||
let new_span _ = Collector.dummy_span
|
let new_span _ = Collector.dummy_span
|
||||||
let new_trace_id _ = Collector.dummy_trace_id
|
let new_explicit_span _ ~parent:_ = Collector.dummy_explicit_span
|
||||||
let on_shutdown _ ~time_ns:_ = ()
|
let on_shutdown _ ~time_ns:_ = ()
|
||||||
let on_name_thread _ ~time_ns:_ ~tid:_ ~name:_ = ()
|
let on_name_thread _ ~time_ns:_ ~tid:_ ~name:_ = ()
|
||||||
let on_name_process _ ~time_ns:_ ~tid:_ ~name:_ = ()
|
let on_name_process _ ~time_ns:_ ~tid:_ ~name:_ = ()
|
||||||
|
|
@ -157,13 +156,10 @@ module Dummy = struct
|
||||||
let on_add_data _ ~data:_ _sp = ()
|
let on_add_data _ ~data:_ _sp = ()
|
||||||
|
|
||||||
let on_enter_manual_span _ ~__FUNCTION__:_ ~__FILE__:_ ~__LINE__:_ ~time_ns:_
|
let on_enter_manual_span _ ~__FUNCTION__:_ ~__FILE__:_ ~__LINE__:_ ~time_ns:_
|
||||||
~tid:_ ~parent:_ ~data:_ ~name:_ ~flavor:_ ~trace_id:_ _sp =
|
~tid:_ ~parent:_ ~data:_ ~name:_ ~flavor:_ _sp =
|
||||||
()
|
|
||||||
|
|
||||||
let on_exit_manual_span _ ~time_ns:_ ~tid:_ ~name:_ ~data:_ ~flavor:_
|
|
||||||
~trace_id:_ _ =
|
|
||||||
()
|
()
|
||||||
|
|
||||||
|
let on_exit_manual_span _ ~time_ns:_ ~tid:_ ~name:_ ~data:_ ~flavor:_ _ = ()
|
||||||
let on_extension_event _ ~time_ns:_ ~tid:_ _ = ()
|
let on_extension_event _ ~time_ns:_ ~tid:_ _ = ()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@ open struct
|
||||||
let (Sub { st = s; callbacks = (module CB) }) = Array.get st 0 in
|
let (Sub { st = s; callbacks = (module CB) }) = Array.get st 0 in
|
||||||
CB.new_span s
|
CB.new_span s
|
||||||
|
|
||||||
let new_trace_id st =
|
let new_explicit_span st =
|
||||||
let (Sub { st = s; callbacks = (module CB) }) = Array.get st 0 in
|
let (Sub { st = s; callbacks = (module CB) }) = Array.get st 0 in
|
||||||
CB.new_trace_id s
|
CB.new_explicit_span s
|
||||||
|
|
||||||
let on_init st ~time_ns =
|
let on_init st ~time_ns =
|
||||||
for i = 0 to Array.length st - 1 do
|
for i = 0 to Array.length st - 1 do
|
||||||
|
|
@ -85,19 +85,17 @@ open struct
|
||||||
done
|
done
|
||||||
|
|
||||||
let on_enter_manual_span st ~__FUNCTION__ ~__FILE__ ~__LINE__ ~time_ns ~tid
|
let on_enter_manual_span st ~__FUNCTION__ ~__FILE__ ~__LINE__ ~time_ns ~tid
|
||||||
~parent ~data ~name ~flavor ~trace_id span =
|
~parent ~data ~name ~flavor span =
|
||||||
for i = 0 to Array.length st - 1 do
|
for i = 0 to Array.length st - 1 do
|
||||||
let (Sub { st = s; callbacks = (module CB) }) = Array.get st i in
|
let (Sub { st = s; callbacks = (module CB) }) = Array.get st i in
|
||||||
CB.on_enter_manual_span s ~__FUNCTION__ ~__FILE__ ~__LINE__ ~time_ns
|
CB.on_enter_manual_span s ~__FUNCTION__ ~__FILE__ ~__LINE__ ~time_ns
|
||||||
~tid ~parent ~data ~name ~flavor ~trace_id span
|
~tid ~parent ~data ~name ~flavor span
|
||||||
done
|
done
|
||||||
|
|
||||||
let on_exit_manual_span st ~time_ns ~tid ~name ~data ~flavor ~trace_id span
|
let on_exit_manual_span st ~time_ns ~tid ~name ~data ~flavor span =
|
||||||
=
|
|
||||||
for i = 0 to Array.length st - 1 do
|
for i = 0 to Array.length st - 1 do
|
||||||
let (Sub { st = s; callbacks = (module CB) }) = Array.get st i in
|
let (Sub { st = s; callbacks = (module CB) }) = Array.get st i in
|
||||||
CB.on_exit_manual_span s ~time_ns ~tid ~name ~data ~flavor ~trace_id
|
CB.on_exit_manual_span s ~time_ns ~tid ~name ~data ~flavor span
|
||||||
span
|
|
||||||
done
|
done
|
||||||
|
|
||||||
let on_extension_event st ~time_ns ~tid ev : unit =
|
let on_extension_event st ~time_ns ~tid ev : unit =
|
||||||
|
|
|
||||||
|
|
@ -71,36 +71,27 @@ let collector (Sub { st; callbacks = (module CB) } : Subscriber.t) : collector =
|
||||||
|
|
||||||
let enter_manual_span ~(parent : explicit_span_ctx option) ~flavor
|
let enter_manual_span ~(parent : explicit_span_ctx option) ~flavor
|
||||||
~__FUNCTION__ ~__FILE__ ~__LINE__ ~data name : explicit_span =
|
~__FUNCTION__ ~__FILE__ ~__LINE__ ~data name : explicit_span =
|
||||||
let span = CB.new_span st in
|
|
||||||
let tid = tid_ () in
|
let tid = tid_ () in
|
||||||
let time_ns = now_ns () in
|
let time_ns = now_ns () in
|
||||||
|
|
||||||
(* get the common trace id, or make a new one *)
|
let espan : explicit_span = CB.new_explicit_span st ~parent in
|
||||||
let trace_id, parent =
|
espan.meta <-
|
||||||
match parent with
|
Meta_map.add key_manual_info { name; flavor; data = [] } espan.meta;
|
||||||
| Some m -> m.trace_id, Some m.span
|
|
||||||
| None -> CB.new_trace_id st, None
|
|
||||||
in
|
|
||||||
|
|
||||||
CB.on_enter_manual_span st ~__FUNCTION__ ~__FILE__ ~__LINE__ ~parent ~data
|
CB.on_enter_manual_span st ~__FUNCTION__ ~__FILE__ ~__LINE__ ~parent ~data
|
||||||
~time_ns ~tid ~name ~flavor ~trace_id span;
|
~time_ns ~tid ~name ~flavor espan;
|
||||||
let meta =
|
espan
|
||||||
Meta_map.empty
|
|
||||||
|> Meta_map.add key_manual_info { name; flavor; data = [] }
|
|
||||||
in
|
|
||||||
{ span; trace_id; meta }
|
|
||||||
|
|
||||||
let exit_manual_span (es : explicit_span) : unit =
|
let exit_manual_span (es : explicit_span) : unit =
|
||||||
let time_ns = now_ns () in
|
let time_ns = now_ns () in
|
||||||
let tid = tid_ () in
|
let tid = tid_ () in
|
||||||
let trace_id = es.trace_id in
|
|
||||||
let minfo =
|
let minfo =
|
||||||
match Meta_map.find key_manual_info es.meta with
|
match Meta_map.find key_manual_info es.meta with
|
||||||
| None -> assert false
|
| None -> assert false
|
||||||
| Some m -> m
|
| Some m -> m
|
||||||
in
|
in
|
||||||
CB.on_exit_manual_span st ~tid ~time_ns ~data:minfo.data ~name:minfo.name
|
CB.on_exit_manual_span st ~tid ~time_ns ~data:minfo.data ~name:minfo.name
|
||||||
~flavor:minfo.flavor ~trace_id es.span
|
~flavor:minfo.flavor es
|
||||||
|
|
||||||
let add_data_to_manual_span (es : explicit_span) data =
|
let add_data_to_manual_span (es : explicit_span) data =
|
||||||
if data <> [] then (
|
if data <> [] then (
|
||||||
|
|
@ -154,15 +145,3 @@ module Span_generator = struct
|
||||||
let create () = A.make 0
|
let create () = A.make 0
|
||||||
let[@inline] mk_span self = A.fetch_and_add self 1 |> Int64.of_int
|
let[@inline] mk_span self = A.fetch_and_add self 1 |> Int64.of_int
|
||||||
end
|
end
|
||||||
|
|
||||||
module Trace_id_8B_generator = struct
|
|
||||||
type t = int A.t
|
|
||||||
|
|
||||||
let create () = A.make 0
|
|
||||||
|
|
||||||
let[@inline] mk_trace_id (self : t) : trace_id =
|
|
||||||
let n = A.fetch_and_add self 1 in
|
|
||||||
let b = Bytes.create 8 in
|
|
||||||
Bytes.set_int64_le b 0 (Int64.of_int n);
|
|
||||||
Bytes.unsafe_to_string b
|
|
||||||
end
|
|
||||||
|
|
|
||||||
|
|
@ -37,15 +37,6 @@ module Span_generator : sig
|
||||||
val mk_span : t -> Trace_core.span
|
val mk_span : t -> Trace_core.span
|
||||||
end
|
end
|
||||||
|
|
||||||
(** A counter-based trace ID generator, producing 8-byte trace IDs.
|
|
||||||
@since NEXT_RELEASE *)
|
|
||||||
module Trace_id_8B_generator : sig
|
|
||||||
type t
|
|
||||||
|
|
||||||
val create : unit -> t
|
|
||||||
val mk_trace_id : t -> Trace_core.trace_id
|
|
||||||
end
|
|
||||||
|
|
||||||
(**/**)
|
(**/**)
|
||||||
|
|
||||||
module Private_ : sig
|
module Private_ : sig
|
||||||
|
|
@ -53,7 +44,7 @@ module Private_ : sig
|
||||||
(** Global mock flag. If enable, all timestamps, tid, etc should be faked. *)
|
(** Global mock flag. If enable, all timestamps, tid, etc should be faked. *)
|
||||||
|
|
||||||
val get_now_ns_ : (unit -> int64) ref
|
val get_now_ns_ : (unit -> int64) ref
|
||||||
(** The callback used to get the current timestamp *)
|
(** The callback used to get the current timestamp, in nanoseconds *)
|
||||||
|
|
||||||
val get_tid_ : (unit -> int) ref
|
val get_tid_ : (unit -> int) ref
|
||||||
(** The callback used to get the current thread's id *)
|
(** The callback used to get the current thread's id *)
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,11 @@ open struct
|
||||||
let[@inline] time_us_of_time_ns (t : int64) : float =
|
let[@inline] time_us_of_time_ns (t : int64) : float =
|
||||||
Int64.div t 1_000L |> Int64.to_float
|
Int64.div t 1_000L |> Int64.to_float
|
||||||
|
|
||||||
let[@inline] int64_of_trace_id_ (id : Trace_core.trace_id) : int64 =
|
(** Used to store async spans' trace ID *)
|
||||||
if id == Trace_core.Collector.dummy_trace_id then
|
let k_trace_id : int64 Meta_map.key = Meta_map.Key.create ()
|
||||||
0L
|
|
||||||
else
|
(* 8B in both cases *)
|
||||||
Bytes.get_int64_le (Bytes.unsafe_of_string id) 0
|
module Trace_id_8B_generator = Sub.Span_generator
|
||||||
end
|
end
|
||||||
|
|
||||||
let on_tracing_error = ref (fun s -> Printf.eprintf "%s\n%!" s)
|
let on_tracing_error = ref (fun s -> Printf.eprintf "%s\n%!" s)
|
||||||
|
|
@ -43,7 +43,7 @@ type t = {
|
||||||
buf_pool: Buf_pool.t;
|
buf_pool: Buf_pool.t;
|
||||||
exporter: Exporter.t;
|
exporter: Exporter.t;
|
||||||
span_gen: Sub.Span_generator.t;
|
span_gen: Sub.Span_generator.t;
|
||||||
trace_id_gen: Sub.Trace_id_8B_generator.t;
|
trace_id_gen: Trace_id_8B_generator.t;
|
||||||
}
|
}
|
||||||
(** Subscriber state *)
|
(** Subscriber state *)
|
||||||
|
|
||||||
|
|
@ -85,7 +85,7 @@ let create ?(buf_pool = Buf_pool.create ()) ~pid ~exporter () : t =
|
||||||
pid;
|
pid;
|
||||||
spans = Span_tbl.create ();
|
spans = Span_tbl.create ();
|
||||||
span_gen = Sub.Span_generator.create ();
|
span_gen = Sub.Span_generator.create ();
|
||||||
trace_id_gen = Sub.Trace_id_8B_generator.create ();
|
trace_id_gen = Trace_id_8B_generator.create ();
|
||||||
}
|
}
|
||||||
|
|
||||||
module Callbacks = struct
|
module Callbacks = struct
|
||||||
|
|
@ -93,8 +93,19 @@ module Callbacks = struct
|
||||||
|
|
||||||
let new_span (self : st) = Sub.Span_generator.mk_span self.span_gen
|
let new_span (self : st) = Sub.Span_generator.mk_span self.span_gen
|
||||||
|
|
||||||
let new_trace_id self =
|
let new_explicit_span self ~(parent : explicit_span_ctx option) :
|
||||||
Sub.Trace_id_8B_generator.mk_trace_id self.trace_id_gen
|
explicit_span =
|
||||||
|
let trace_id =
|
||||||
|
match parent with
|
||||||
|
| None -> Trace_id_8B_generator.mk_span self.trace_id_gen
|
||||||
|
| Some p ->
|
||||||
|
(match Meta_map.find k_trace_id p.meta with
|
||||||
|
| Some t -> t
|
||||||
|
| None -> Trace_id_8B_generator.mk_span self.trace_id_gen)
|
||||||
|
in
|
||||||
|
let span = new_span self in
|
||||||
|
let meta = Meta_map.(empty |> add k_trace_id trace_id) in
|
||||||
|
{ span; meta }
|
||||||
|
|
||||||
let on_init _ ~time_ns:_ = ()
|
let on_init _ ~time_ns:_ = ()
|
||||||
let on_shutdown (self : st) ~time_ns:_ = close self
|
let on_shutdown (self : st) ~time_ns:_ = close self
|
||||||
|
|
@ -162,25 +173,30 @@ module Callbacks = struct
|
||||||
self.exporter.on_json buf
|
self.exporter.on_json buf
|
||||||
|
|
||||||
let on_enter_manual_span (self : st) ~__FUNCTION__:fun_name ~__FILE__:_
|
let on_enter_manual_span (self : st) ~__FUNCTION__:fun_name ~__FILE__:_
|
||||||
~__LINE__:_ ~time_ns ~tid ~parent:_ ~data ~name ~flavor ~trace_id _span :
|
~__LINE__:_ ~time_ns ~tid ~parent:_ ~data ~name ~flavor
|
||||||
unit =
|
(span : explicit_span) : unit =
|
||||||
let time_us = time_us_of_time_ns @@ time_ns in
|
let time_us = time_us_of_time_ns @@ time_ns in
|
||||||
|
|
||||||
|
let trace_id =
|
||||||
|
try Meta_map.find_exn k_trace_id span.meta with _ -> assert false
|
||||||
|
in
|
||||||
|
|
||||||
let data = add_fun_name_ fun_name data in
|
let data = add_fun_name_ fun_name data in
|
||||||
let@ buf = Rpool.with_ self.buf_pool in
|
let@ buf = Rpool.with_ self.buf_pool in
|
||||||
Writer.emit_manual_begin buf ~pid:self.pid ~tid ~name
|
Writer.emit_manual_begin buf ~pid:self.pid ~tid ~name ~id:trace_id
|
||||||
~id:(int64_of_trace_id_ trace_id)
|
|
||||||
~ts:time_us ~args:data ~flavor;
|
~ts:time_us ~args:data ~flavor;
|
||||||
self.exporter.on_json buf
|
self.exporter.on_json buf
|
||||||
|
|
||||||
let on_exit_manual_span (self : st) ~time_ns ~tid ~name ~data ~flavor
|
let on_exit_manual_span (self : st) ~time_ns ~tid ~name ~data ~flavor
|
||||||
~trace_id (_ : span) : unit =
|
(span : explicit_span) : unit =
|
||||||
let time_us = time_us_of_time_ns @@ time_ns in
|
let time_us = time_us_of_time_ns @@ time_ns in
|
||||||
|
let trace_id =
|
||||||
|
try Meta_map.find_exn k_trace_id span.meta with _ -> assert false
|
||||||
|
in
|
||||||
|
|
||||||
let@ buf = Rpool.with_ self.buf_pool in
|
let@ buf = Rpool.with_ self.buf_pool in
|
||||||
Writer.emit_manual_end buf ~pid:self.pid ~tid ~name
|
Writer.emit_manual_end buf ~pid:self.pid ~tid ~name ~id:trace_id ~ts:time_us
|
||||||
~id:(int64_of_trace_id_ trace_id)
|
~flavor ~args:data;
|
||||||
~ts:time_us ~flavor ~args:data;
|
|
||||||
self.exporter.on_json buf
|
self.exporter.on_json buf
|
||||||
|
|
||||||
let on_extension_event _ ~time_ns:_ ~tid:_ _ev = ()
|
let on_extension_event _ ~time_ns:_ ~tid:_ _ev = ()
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue