ocaml-opentelemetry/src/lib/gc_metrics.ml
2026-02-27 14:56:21 -05:00

46 lines
1.7 KiB
OCaml

open struct
let bytes_per_word = Sys.word_size / 8
let[@inline] word_to_bytes n = n * bytes_per_word
let[@inline] word_to_bytes_f n = n *. float bytes_per_word
let default_interval_s = 20
end
let get_metrics () : Metrics.t list =
let gc = Gc.quick_stat () in
let now = Clock.now_main () in
let open Metrics in
let open Conventions.Metrics in
[
gauge ~name:Process.Runtime.Ocaml.GC.major_heap ~unit_:"B"
[ int ~now (word_to_bytes gc.Gc.heap_words) ];
sum ~name:Process.Runtime.Ocaml.GC.minor_allocated
~aggregation_temporality:Metrics.Aggregation_temporality_cumulative
~is_monotonic:true ~unit_:"B"
[ float ~now (word_to_bytes_f gc.Gc.minor_words) ];
sum ~name:Process.Runtime.Ocaml.GC.minor_collections
~aggregation_temporality:Metrics.Aggregation_temporality_cumulative
~is_monotonic:true
[ int ~now gc.Gc.minor_collections ];
sum ~name:Process.Runtime.Ocaml.GC.major_collections
~aggregation_temporality:Metrics.Aggregation_temporality_cumulative
~is_monotonic:true
[ int ~now gc.Gc.major_collections ];
sum ~name:Process.Runtime.Ocaml.GC.compactions
~aggregation_temporality:Metrics.Aggregation_temporality_cumulative
~is_monotonic:true
[ int ~now gc.Gc.compactions ];
]
let setup ?(min_interval_s = default_interval_s)
?(meter = Meter_provider.default_meter) () =
let min_interval_s = max 5 min_interval_s in
let min_interval = Mtime.Span.(min_interval_s * s) in
let limiter = Interval_limiter.create ~min_interval () in
Sdk.add_on_tick_callback (fun () ->
if Interval_limiter.make_attempt limiter then
List.iter (Meter.emit1 meter) (get_metrics ()))
let basic_setup () = setup ()