package trace
A stub for tracing/observability, agnostic in how data is collected
Install
Dune Dependency
Authors
Maintainers
Sources
trace-0.8.tbz
sha256=34cfa5662b611c1e246f0fb8131ee605eeb90b359c105e882f51adc7e70878c3
sha512=ea47974a77a0ab26c58fe6d1bc898d4f3e6a5f865e4c1acb4188b9acd7ba8e7527d0ea7f2ae66574ceccc14f11127ee203aedba2be334d17b36c83dabff61261
doc/src/trace.subscriber/trace_subscriber.ml.html
Source file trace_subscriber.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
open Trace_core module Callbacks = Callbacks module Subscriber = Subscriber include Types type t = Subscriber.t module Private_ = struct let get_now_ns_ = ref None let get_tid_ = ref None (** Now, in nanoseconds *) let[@inline] now_ns () : float = match !get_now_ns_ with | Some f -> f () | None -> Time_.get_time_ns () let[@inline] tid_ () : int = match !get_tid_ with | Some f -> f () | None -> Thread_.get_tid () end open struct module A = Trace_core.Internal_.Atomic_ type manual_span_info = { name: string; flavor: flavor option; mutable data: (string * user_data) list; } (** Key used to carry some information between begin and end of manual spans, by way of the meta map *) let key_manual_info : manual_span_info Meta_map.key = Meta_map.Key.create () (** key used to carry a unique "id" for all spans in an async context *) let key_async_trace_id : int Meta_map.key = Meta_map.Key.create () end let[@inline] conv_flavor = function | `Async -> Async | `Sync -> Sync let[@inline] conv_flavor_opt = function | None -> None | Some f -> Some (conv_flavor f) let[@inline] conv_user_data = function | `Int i -> U_int i | `Bool b -> U_bool b | `Float f -> U_float f | `String s -> U_string s | `None -> U_none let rec conv_data = function | [] -> [] | [ (k, v) ] -> [ k, conv_user_data v ] | (k, v) :: tl -> (k, conv_user_data v) :: conv_data tl (** A collector that calls the callbacks of subscriber *) let collector (Sub { st; callbacks = (module CB) } : Subscriber.t) : collector = let open Private_ in let module M = struct let trace_id_gen_ = A.make 0 (** generator for span ids *) let new_span_ : unit -> int = let span_id_gen_ = A.make 0 in fun [@inline] () -> A.fetch_and_add span_id_gen_ 1 let enter_span ~__FUNCTION__ ~__FILE__ ~__LINE__ ~data name : span = let span = Int64.of_int (new_span_ ()) in let tid = tid_ () in let time_ns = now_ns () in let data = conv_data data in CB.on_enter_span st ~__FUNCTION__ ~__FILE__ ~__LINE__ ~time_ns ~tid ~data ~name span; span let exit_span span : unit = let time_ns = now_ns () in let tid = tid_ () in CB.on_exit_span st ~time_ns ~tid span let with_span ~__FUNCTION__ ~__FILE__ ~__LINE__ ~data name f = let span = enter_span ~__FUNCTION__ ~__FILE__ ~__LINE__ ~data name in try let x = f span in exit_span span; x with exn -> let bt = Printexc.get_raw_backtrace () in exit_span span; Printexc.raise_with_backtrace exn bt let add_data_to_span span data = if data <> [] then ( let data = conv_data data in CB.on_add_data st ~data span ) let enter_manual_span ~(parent : explicit_span option) ~flavor ~__FUNCTION__ ~__FILE__ ~__LINE__ ~data name : explicit_span = let span = Int64.of_int (new_span_ ()) in let tid = tid_ () in let time_ns = now_ns () in let data = conv_data data in let flavor = conv_flavor_opt flavor in (* get the common trace id, or make a new one *) let trace_id, parent = match parent with | Some m -> Meta_map.find_exn key_async_trace_id m.meta, Some m.span | None -> A.fetch_and_add trace_id_gen_ 1, None in CB.on_enter_manual_span st ~__FUNCTION__ ~__FILE__ ~__LINE__ ~parent ~data ~time_ns ~tid ~name ~flavor ~trace_id span; let meta = Meta_map.empty |> Meta_map.add key_manual_info { name; flavor; data = [] } |> Meta_map.add key_async_trace_id trace_id in { span; meta } let exit_manual_span (es : explicit_span) : unit = let time_ns = now_ns () in let tid = tid_ () in let trace_id = match Meta_map.find key_async_trace_id es.meta with | None -> assert false | Some id -> id in let minfo = match Meta_map.find key_manual_info es.meta with | None -> assert false | Some m -> m in CB.on_exit_manual_span st ~tid ~time_ns ~data:minfo.data ~name:minfo.name ~flavor:minfo.flavor ~trace_id es.span let add_data_to_manual_span (es : explicit_span) data = if data <> [] then ( let data = conv_data data in match Meta_map.find key_manual_info es.meta with | None -> assert false | Some m -> m.data <- List.rev_append data m.data ) let message ?span ~data msg : unit = let time_ns = now_ns () in let tid = tid_ () in let data = conv_data data in CB.on_message st ~time_ns ~tid ~span ~data msg let counter_float ~data name f : unit = let time_ns = now_ns () in let tid = tid_ () in let data = conv_data data in CB.on_counter st ~tid ~time_ns ~data ~name f let[@inline] counter_int ~data name i = counter_float ~data name (float_of_int i) let name_process name : unit = let tid = tid_ () in let time_ns = now_ns () in CB.on_name_process st ~time_ns ~tid ~name let name_thread name : unit = let tid = tid_ () in let time_ns = now_ns () in CB.on_name_thread st ~time_ns ~tid ~name let shutdown () = let time_ns = now_ns () in CB.on_shutdown st ~time_ns let () = (* init code *) let time_ns = now_ns () in CB.on_init st ~time_ns end in (module M)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>