feat: add an extensible sum type for extending the library

libraries and collectors can now define their own "events" that
collectors will handle (or not), without having to contribute them to
ocaml-trace at all.
This commit is contained in:
Simon Cruanes 2024-10-17 21:08:36 -04:00
parent 9a7b4710a3
commit 4dfa319003
No known key found for this signature in database
GPG key ID: EBFFF6F283F3A2B4
9 changed files with 53 additions and 0 deletions

View file

@ -94,6 +94,12 @@ module type S = sig
val counter_float : data:(string * user_data) list -> string -> float -> unit val counter_float : data:(string * user_data) list -> string -> float -> unit
(** Float counter. *) (** Float counter. *)
val extension_event : extension_event -> unit
(** Handle an extension event.
A collector {b MUST} simple ignore events it doesn't know,
and return [()] silently.
@since NEXT_RELEASE *)
val shutdown : unit -> unit val shutdown : unit -> unit
(** Shutdown collector, possibly waiting for it to finish sending data. *) (** Shutdown collector, possibly waiting for it to finish sending data. *)
end end

View file

@ -168,6 +168,13 @@ let shutdown () =
| None -> () | None -> ()
| Some (module C) -> C.shutdown () | Some (module C) -> C.shutdown ()
type extension_event = Types.extension_event = ..
let[@inline] extension_event ev =
match A.get collector with
| None -> ()
| Some (module C) -> C.extension_event ev
module Internal_ = struct module Internal_ = struct
module Atomic_ = Atomic_ module Atomic_ = Atomic_
end end

View file

@ -214,3 +214,16 @@ val set_current_level : Level.t -> unit
val shutdown : unit -> unit val shutdown : unit -> unit
(** [shutdown ()] shutdowns the current collector, if one was installed, (** [shutdown ()] shutdowns the current collector, if one was installed,
and waits for it to terminate before returning. *) and waits for it to terminate before returning. *)
(** {2 Extensions} *)
type extension_event = Types.extension_event = ..
(** Extension event
@since NEXT_RELEASE *)
val extension_event : extension_event -> unit
(** Trigger an extension event, whose meaning depends on
the library that defines it. Some collectors will
simply ignore it. This does nothing if no collector
is setup.
@since NEXT_RELEASE *)

View file

@ -23,3 +23,8 @@ type explicit_span = {
of the span, to the end of the span. *) of the span, to the end of the span. *)
} }
(** Explicit span, with collector-specific metadata *) (** Explicit span, with collector-specific metadata *)
type extension_event = ..
(** An extension event, used to add features that are backend specific
or simply not envisioned by [trace].
@since NEXT_RELEASE *)

View file

@ -363,6 +363,8 @@ struct
encode out ~name ~ty:ty_thread ~kid:tls.tid encode out ~name ~ty:ty_thread ~kid:tls.tid
~args:[ "process", `Kid pid ] ~args:[ "process", `Kid pid ]
()) ())
let extension_event _ = ()
end end
let create ~out () : collector = let create ~out () : collector =

View file

@ -104,6 +104,11 @@ module type S = sig
span -> span ->
unit unit
(** Exit a manual span *) (** Exit a manual span *)
val on_extension_event :
st -> time_ns:float -> tid:int -> extension_event -> unit
(** Extension event
@since NEXT_RELEASE *)
end end
type 'st t = (module S with type st = 'st) type 'st t = (module S with type st = 'st)
@ -137,6 +142,8 @@ module Dummy = struct
let on_exit_manual_span _ ~time_ns:_ ~tid:_ ~name:_ ~data:_ ~flavor:_ let on_exit_manual_span _ ~time_ns:_ ~tid:_ ~name:_ ~data:_ ~flavor:_
~trace_id:_ _ = ~trace_id:_ _ =
() ()
let on_extension_event _ ~time_ns:_ ~tid:_ _ = ()
end end
(** Dummy callbacks, ignores all events. *) (** Dummy callbacks, ignores all events. *)

View file

@ -96,6 +96,12 @@ open struct
span; span;
CB2.on_exit_manual_span s2 ~time_ns ~tid ~name ~data ~flavor ~trace_id CB2.on_exit_manual_span s2 ~time_ns ~tid ~name ~data ~flavor ~trace_id
span span
let on_extension_event
( Sub { st = s1; callbacks = (module CB1) },
Sub { st = s2; callbacks = (module CB2) } ) ~time_ns ~tid ev : unit =
CB1.on_extension_event s1 ~time_ns ~tid ev;
CB2.on_extension_event s2 ~time_ns ~tid ev
end end
end end

View file

@ -177,6 +177,11 @@ let collector (Sub { st; callbacks = (module CB) } : Subscriber.t) : collector =
let time_ns = now_ns () in let time_ns = now_ns () in
CB.on_shutdown st ~time_ns CB.on_shutdown st ~time_ns
let extension_event ev =
let tid = tid_ () in
let time_ns = now_ns () in
CB.on_extension_event st ~time_ns ~tid ev
let () = let () =
(* init code *) (* init code *)
let time_ns = now_ns () in let time_ns = now_ns () in

View file

@ -354,6 +354,8 @@ let subscriber_ ~finally ~out ~(mode : [ `Single | `Jsonl ]) () : Sub.t =
let time_us = time_ns *. 1e-3 in let time_us = time_ns *. 1e-3 in
B_queue.push self.events B_queue.push self.events
@@ E_exit_manual_span { tid; id = trace_id; name; time_us; data; flavor } @@ E_exit_manual_span { tid; id = trace_id; name; time_us; data; flavor }
let on_extension_event _ ~time_ns:_ ~tid:_ _ev = ()
end in end in
let events = B_queue.create () in let events = B_queue.create () in
let t_write = let t_write =