package opentelemetry
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Core library for instrumentation and serialization for https://opentelemetry.io
Install
dune-project
Dependency
Authors
Maintainers
Sources
opentelemetry-0.90.tbz
sha256=c3989bb678f57e5276209d3c60afb29cdca33122288de55e591fbbe2e50a662c
sha512=ba8339256c9b2d8c99c8304991a3047f280a01e492add4cf82bf1d43dfa51e790366c09c6901c0501b8b8e1f810c6e128e33dd33542d785013407f642ade4eea
doc/src/opentelemetry.core/instrument.ml.html
Source file instrument.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 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221type 'a t = { kind: string; name: string; emit: clock:Clock.t -> unit -> Metrics.t list; update: 'a -> unit; } let all : (clock:Clock.t -> unit -> Metrics.t list) Alist.t = Alist.make () let register (instr : 'a t) : unit = Alist.add all instr.emit module Internal = struct let iter_all f = Alist.get all |> List.iter f end let float_add (a : float Atomic.t) (delta : float) : unit = while let cur = Atomic.get a in not (Atomic.compare_and_set a cur (cur +. delta)) do () done module type CUSTOM_IMPL = sig type data type state val kind : string val init : unit -> state val update : state -> data -> unit val to_metrics : state -> name:string -> ?description:string -> ?unit_:string -> clock:Clock.t -> unit -> Metrics.t list end module Make (I : CUSTOM_IMPL) = struct let create ~name ?description ?unit_ () : I.data t = let state = I.init () in let emit ~clock () = I.to_metrics state ~name ?description ?unit_ ~clock () in let instrument = { kind = I.kind; name; emit; update = I.update state } [@warning "-45"] in register instrument; instrument end module Int_counter = struct include Make (struct type data = int type state = int Atomic.t let kind = "counter" let init () = Atomic.make 0 let update state delta = ignore (Atomic.fetch_and_add state delta : int) let to_metrics state ~name ?description ?unit_ ~clock () = let now = Clock.now clock in [ Metrics.sum ~name ?description ?unit_ ~is_monotonic:true [ Metrics.int ~now (Atomic.get state) ]; ] end) let add (instrument : int t) delta = instrument.update delta end module Float_counter = struct include Make (struct type data = float type state = float Atomic.t let kind = "counter" let init () = Atomic.make 0. let update state delta = float_add state delta let to_metrics state ~name ?description ?unit_ ~clock () = let now = Clock.now clock in [ Metrics.sum ~name ?description ?unit_ ~is_monotonic:true [ Metrics.float ~now (Atomic.get state) ]; ] end) let add (instrument : float t) delta = instrument.update delta end module Int_gauge = struct include Make (struct type data = int type state = int Atomic.t let kind = "gauge" let init () = Atomic.make 0 let update state v = Atomic.set state v let to_metrics state ~name ?description ?unit_ ~clock () = let now = Clock.now clock in [ Metrics.gauge ~name ?description ?unit_ [ Metrics.int ~now (Atomic.get state) ]; ] end) let record (instrument : int t) v = instrument.update v end module Float_gauge = struct include Make (struct type data = float type state = float Atomic.t let kind = "gauge" let init () = Atomic.make 0. let update state v = Atomic.set state v let to_metrics state ~name ?description ?unit_ ~clock () = let now = Clock.now clock in [ Metrics.gauge ~name ?description ?unit_ [ Metrics.float ~now (Atomic.get state) ]; ] end) let record (instrument : float t) v = instrument.update v end module Histogram = struct let default_bounds = [ 0.005; 0.01; 0.025; 0.05; 0.075; 0.1; 0.25; 0.5; 0.75; 1.; 2.5; 5.; 7.5; 10.; ] (* Find the index of the first bucket whose upper bound >= v. Returns Array.length bounds if v exceeds all bounds (overflow bucket). *) let find_bucket (bounds : float array) (v : float) : int = let n = Array.length bounds in let lo = ref 0 and hi = ref (n - 1) in while !lo < !hi do let mid = (!lo + !hi) / 2 in if bounds.(mid) < v then lo := mid + 1 else hi := mid done; if !lo < n && v <= bounds.(!lo) then !lo else n let create ~name ?description ?unit_ ?(bounds = default_bounds) () : float t = let bounds_arr = Array.of_list bounds in let n_buckets = Array.length bounds_arr + 1 in let bucket_counts = Array.init n_buckets (fun _ -> Atomic.make 0) in let sum = Atomic.make 0. in let count = Atomic.make 0 in let update v = let bucket = find_bucket bounds_arr v in ignore (Atomic.fetch_and_add bucket_counts.(bucket) 1 : int); float_add sum v; ignore (Atomic.fetch_and_add count 1 : int) in let emit ~clock () = let now = Clock.now clock in let count_v = Int64.of_int (Atomic.get count) in let sum_v = Atomic.get sum in let bc = Array.to_list (Array.map (fun a -> Int64.of_int (Atomic.get a)) bucket_counts) in [ Metrics.histogram ~name ?description ?unit_ [ Metrics.histogram_data_point ~now ~count:count_v ~sum:sum_v ~bucket_counts:bc ~explicit_bounds:bounds (); ]; ] in let instrument = { kind = "histogram"; name; emit; update } [@warning "-45"] in register instrument; instrument let record (instrument : float t) v = instrument.update v end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>