package trace
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
A lightweight stub for tracing/observability, agnostic in how data is collected
Install
dune-project
Dependency
Authors
Maintainers
Sources
trace-0.11.tbz
sha256=a29329fcfb191a98bfed26c05c300ed9e1e915b73cc59f51e9d9cdc4d1f158bc
sha512=ff77a4ef19375f4ad3b1ddff7336657a4a5695924b679ac2c36a77b14b95c63d126539efd1590f83b415a1288bb843a5fb4308e53a807dcc22456cb40a8e0026
doc/src/trace.debug/track_spans.ml.html
Source file track_spans.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 150module A = Trace_core.Internal_.Atomic_ open Trace_core let ( let@ ) = ( @@ ) type span += Span_tracked of (* id *) int * span type unclosed_spans = { num: int; by_name: (string * int) list; } type out = [ `Out of out_channel | `Call of unclosed_spans -> unit ] open struct module Tbl = Hashtbl.Make (struct type t = int let equal = Stdlib.( = ) let hash = Hashtbl.hash end) type 'state st = { mutex: Mutex.t; tbl_open_spans: string Tbl.t; gen_id: int A.t; state: 'state; cbs: 'state Collector.Callbacks.t; (** underlying callbacks *) out: out; } let create_st ~state ~cbs ~out () : _ st = { mutex = Mutex.create (); tbl_open_spans = Tbl.create 32; gen_id = A.make 0; state; cbs; out; } let with_mutex mut f = Mutex.lock mut; Fun.protect f ~finally:(fun () -> Mutex.unlock mut) let enter_span (self : _ st) ~__FUNCTION__ ~__FILE__ ~__LINE__ ~level ~params ~data ~parent name : span = let span = self.cbs.enter_span self.state ~__FUNCTION__ ~__FILE__ ~__LINE__ ~level ~params ~data ~parent name in let id = A.fetch_and_add self.gen_id 1 in (let@ () = with_mutex self.mutex in Tbl.add self.tbl_open_spans id name); Span_tracked (id, span) let exit_span (self : _ st) span = match span with | Span_tracked (id, span) -> (let@ () = with_mutex self.mutex in Tbl.remove self.tbl_open_spans id); self.cbs.exit_span self.state span | _ -> self.cbs.exit_span self.state span let add_data_to_span (self : _ st) span data = match span with | Span_tracked (_, span) -> self.cbs.add_data_to_span self.state span data | _ -> self.cbs.add_data_to_span self.state span data let emit (self : _ st) (us : unclosed_spans) = assert (us.by_name <> []); match self.out with | `Call f -> f us | `Out out -> Printf.fprintf out "trace: warning: %d spans were not closed\n" us.num; List.iter (fun (name, n) -> Printf.fprintf out " span %S was not closed (%d occurrences)\n" name n) us.by_name; flush out let print_non_closed_spans_warning (self : _ st) = let module Str_map = Map.Make (String) in let@ () = with_mutex self.mutex in let num = Tbl.length self.tbl_open_spans in if num > 0 then ( let names_with_count = Tbl.fold (fun _id name m -> Str_map.add name (1 + try Str_map.find name m with Not_found -> 0) m) self.tbl_open_spans Str_map.empty in let unclosed_spans = { num; by_name = Str_map.fold (fun name id l -> (name, id) :: l) names_with_count [] |> List.sort Stdlib.compare; } in emit self unclosed_spans ) let message self ~level ~params ~data ~span msg = let span = match span with | Some (Span_tracked (_, sp)) -> Some sp | _ -> span in self.cbs.message self.state ~level ~params ~data ~span msg let metric self ~level ~params ~data name v = self.cbs.metric self.state ~level ~params ~data name v let enabled _ _ = true let init (self : _ st) = self.cbs.init self.state let shutdown (self : _ st) : unit = print_non_closed_spans_warning self; self.cbs.shutdown self.state let extension self ~level ev = self.cbs.extension self.state ~level ev let track_callbacks : _ st Collector.Callbacks.t = { enter_span; exit_span; add_data_to_span; enabled; message; metric; init; shutdown; extension; } end let track ?(on_lingering_spans = `Out stderr) (c : Collector.t) : Collector.t = match c with | C_none -> C_none | C_some (st, cbs) -> let st = create_st ~state:st ~cbs ~out:on_lingering_spans () in C_some (st, track_callbacks)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>