ocaml-trace/src/core/trace_core.ml
2026-01-17 20:53:12 -05:00

195 lines
5.8 KiB
OCaml

include Types
module A = Atomic_
module Collector = Collector
module Meta_map = Meta_map
module Level = Level
module Core_ext = Core_ext
type collector = Collector.t
(* ## globals ## *)
(** Global collector. *)
let collector : collector A.t = A.make Collector.C_none
(* default level for spans without a level *)
let default_level_ = A.make Level.Trace
let current_level_ = A.make Level.Trace
(* ## implementation ## *)
let data_empty_build_ () = []
let[@inline] enabled () = Collector.is_some (A.get collector)
let[@inline] get_default_level () = A.get default_level_
let[@inline] set_default_level l = A.set default_level_ l
let[@inline] set_current_level l = A.set current_level_ l
let[@inline] get_current_level () = A.get current_level_
let[@inline] check_level ?(level = A.get default_level_) () : bool =
Level.leq level (A.get current_level_)
let parent_of_span_opt_opt = function
| None -> P_unknown
| Some None -> P_none
| Some (Some p) -> P_some p
let enter_span_st st (cbs : _ Collector.Callbacks.t) ?__FUNCTION__ ~__FILE__
~__LINE__ ?parent ?(params = []) ?(data = data_empty_build_) name : span =
let parent = parent_of_span_opt_opt parent in
let data = data () in
cbs.enter_span st ~__FUNCTION__ ~__FILE__ ~__LINE__ ~parent ~params ~data name
let with_span_collector_ st (cbs : _ Collector.Callbacks.t) ?__FUNCTION__
~__FILE__ ~__LINE__ ?parent ?params ?data name f =
let sp : span =
enter_span_st st cbs ?__FUNCTION__ ~__FILE__ ~__LINE__ ?parent ?params ?data
name
in
match f sp with
| res ->
cbs.exit_span st sp;
res
| exception exn ->
let bt = Printexc.get_raw_backtrace () in
cbs.exit_span st sp;
Printexc.raise_with_backtrace exn bt
let[@inline] with_span ?level ?__FUNCTION__ ~__FILE__ ~__LINE__ ?parent ?params
?data name f =
match A.get collector with
| C_some (st, cbs) when check_level ?level () ->
with_span_collector_ st cbs ?__FUNCTION__ ~__FILE__ ~__LINE__ ?parent
?params ?data name f
| _ ->
(* fast path: no collector, no span *)
f Collector.dummy_span
let[@inline] enter_span ?level ?__FUNCTION__ ~__FILE__ ~__LINE__ ?flavor ?parent
?(params = []) ?data name : span =
match A.get collector with
| C_some (st, cbs) when check_level ?level () ->
let params =
match flavor with
| None -> params
| Some f -> Core_ext.Extension_span_flavor f :: params
in
(enter_span_st [@inlined never]) st cbs ?__FUNCTION__ ~__FILE__ ~__LINE__
?parent ~params ?data name
| _ -> Collector.dummy_span
let[@inline] exit_span sp : unit =
match A.get collector with
| C_none -> ()
| C_some (st, cbs) -> cbs.exit_span st sp
let[@inline] add_data_to_span sp data : unit =
if sp != Collector.dummy_span && data <> [] then (
match A.get collector with
| C_none -> ()
| C_some (st, cbs) -> cbs.add_data_to_span st sp data
)
let message_collector_ st (cbs : _ Collector.Callbacks.t) ?span ?(params = [])
?(data = data_empty_build_) msg : unit =
let data = data () in
cbs.message st ~span ~params ~data msg
let[@inline] message ?level ?span ?params ?data msg : unit =
match A.get collector with
| C_some (st, cbs) when check_level ?level () ->
(message_collector_ [@inlined never]) st cbs ?span ?params ?data msg
| _ -> ()
let messagef ?level ?span ?params ?data k =
match A.get collector with
| C_some (st, cbs) when check_level ?level () ->
k (fun fmt ->
Format.kasprintf
(fun str -> message_collector_ st cbs ?span ?params ?data str)
fmt)
| _ -> ()
let counter_int ?level ?(params = []) ?(data = data_empty_build_) name n : unit
=
match A.get collector with
| C_some (st, cbs) when check_level ?level () ->
let data = data () in
cbs.counter_int st ~params ~data name n
| _ -> ()
let counter_float ?level ?(params = []) ?(data = data_empty_build_) name f :
unit =
match A.get collector with
| C_some (st, cbs) when check_level ?level () ->
let data = data () in
cbs.counter_float st ~params ~data name f
| _ -> ()
let setup_collector c : unit =
while
let cur = A.get collector in
match cur with
| C_some _ -> invalid_arg "trace: collector already present"
| C_none -> not (A.compare_and_set collector cur c)
do
()
done;
(* initialize collector *)
match c with
| C_none -> ()
| C_some (st, cb) -> cb.init st
let shutdown () =
match A.exchange collector C_none with
| C_none -> ()
| C_some (st, cbs) -> cbs.shutdown st
let with_setup_collector c f =
setup_collector c;
Fun.protect ~finally:shutdown f
type extension_event = Types.extension_event = ..
let[@inline] extension_event ev : unit =
match A.get collector with
| C_none -> ()
| C_some (st, cbs) -> cbs.extension st ev
let set_thread_name name : unit =
extension_event @@ Core_ext.Extension_set_thread_name name
let set_process_name name : unit =
extension_event @@ Core_ext.Extension_set_process_name name
module Internal_ = struct
module Atomic_ = Atomic_
end
(* ### deprecated *)
[@@@ocaml.alert "-deprecated"]
let enter_manual_span ~parent ?flavor ?level ?__FUNCTION__ ~__FILE__ ~__LINE__
?data name : explicit_span =
let params =
match flavor with
| None -> []
| Some f -> [ Core_ext.Extension_span_flavor f ]
in
enter_span ~parent ~params ?level ?__FUNCTION__ ~__FILE__ ~__LINE__ ?data name
let enter_manual_toplevel_span ?flavor ?level ?__FUNCTION__ ~__FILE__ ~__LINE__
?data name : explicit_span =
enter_manual_span ~parent:None ?flavor ?level ?__FUNCTION__ ~__FILE__
~__LINE__ ?data name
let enter_manual_sub_span ~parent ?flavor ?level ?__FUNCTION__ ~__FILE__
~__LINE__ ?data name : explicit_span =
enter_manual_span ~parent:(Some parent) ?flavor ?level ?__FUNCTION__ ~__FILE__
~__LINE__ ?data name
let exit_manual_span = exit_span
let add_data_to_manual_span = add_data_to_span
[@@@ocaml.alert "+deprecated"]