Module Metrics

Metrics Monitoring.

Metrics provides a basic infrastructure to monitor metrics using time series. Monitoring is performed on sources, indexed by tags. Tags allow users to select at runtime which metric sources are producing data points. Disabled data-sources have a low runtime cost (only a closure allocation) which make Metrics suitable to instrument production systems.

Both sources tags and data-points are built using dictionaries of typed entries called fields.

Metrics is heavily inspired by Logs as it decouples metric reporting from metric monitoring. This is handled by custom reporters.

v0.4.0 - homepage

Fields

type graph

The type for metric graphs.

type field

The type for metric fields.

type key = string

The type for field keys.

type 'a field_f = ?doc:string -> ?unit:string -> ?graph:graph -> ?graphs:graph list -> key -> 'a -> field

The type for field functions.

val string : string field_f

string ?doc k v is the field whose key is k and value is v.

val int : int field_f

int ?doc k i is the field whose key is k and value is i.

val uint : int field_f

uint ?doc k i is the field whose key is k and value is i.

val int32 : int32 field_f

int32 k i is the field whose key is k and value is i.

val uint32 : int32 field_f

uint32 ?doc k i is the field whose key is k and value is i.

val int64 : int64 field_f

int64 ?doc k i is the field whose key is k and value is i.

val uint64 : int64 field_f

uint64 ?doc k i is the field whose key is k and value is i.

val float : float field_f

uint ?doc k f is the field whose key is k and value is i.

val bool : bool field_f

uint ?doc k b is the field whose key is k and value is i.

val duration : int64 -> field

duration t is the field ("duration", t, "ns").

type status = [
| `Ok
| `Error
]

The type for process status.

val status : status -> field

status t is the field ("status", "ok") or ("status", "error").

Custom fields

type 'a ty =
| String : string ty
| Bool : bool ty
| Float : float ty
| Int : int ty
| Int32 : int32 ty
| Int64 : int64 ty
| Uint : int ty
| Uint32 : int32 ty
| Uint64 : int64 ty
| Other : 'a Fmt.t -> 'a ty

The type of supported values in metric fields.

val field : ?doc:string -> ?unit:string -> ?graph:graph -> ?graphs:graph list -> string -> 'a ty -> 'a -> field

field ?doc ?unit k ty v is the field whose key is k, value type is ty and value is v.

Reading Fields

val key : field -> string

key f is f's key.

val doc : field -> string option

doc f is f's documentation.

val unit : field -> string option

unit t are t's units.

val graphs : field -> graph list option

graphs t is the graphs where t appears.

type value =
| V : 'a ty * 'a -> value(*

Type for values.

*)
val value : field -> value

value f is f's value.

val index : fields:string list -> field -> int

index ~fields f is f's index in the list of field keys fields. Raise Not_found if f is not a field of t.

val index_key : fields:string list -> string -> int

Same as index but using field keys instead.

Pretty-printing Fields

val pp_key : field Fmt.t

pp_key is the pretty-printer for field keys.

val pp_value : field Fmt.t

pp_value is the pretty-printer for field values, using sensible default.

Data points

module Data : sig ... end

Data defines what is stored in the time series.

type data = Data.t

The type for data points.

Tags

module Tags : sig ... end

Tags indexes metric sources, and allow to enable/disable data collection at runtime.

type tags = field list

The type for metric tags. Used to distinguish the various entities that are being measured.

val tags_enabled : unit -> key list

tags_enabled () is the list of tags that are enabled.

val all_enabled : unit -> bool

all_enabled () is true if all metric sources are enabled.

val enable_tag : key -> unit

enable_tag t enables all the registered metric sources having the tag t.

val disable_tag : key -> unit

disable_tag t disables all the registered metric sources having the tag t.

val enable_all : unit -> unit

enable_all () enables all registered metric sources.

val disable_all : unit -> unit

disable_all () disables all registered metric sources.

Sources

type ('a, 'b) src

The type for metric sources. A source defines a named unit for a time series. 'a is the type of the function used to create new data points. 'b is the type for tags.

module Src : sig ... end

Metric sources.

Metric Graphs

module Graph : sig ... end
module Key : sig ... end

Monitoring

val is_active : ('a'b) src -> bool

is_active src is true iff src monitoring is enabled.

val add : ('a'b) src -> ('a -> tags) -> ('b -> Data.t) -> unit

add src t f adds a new data point to src for the tags t.

val run : ('a('b, exn) Stdlib.result -> Data.t) src -> ('a -> tags) -> (unit -> 'b) -> 'b

run src t f runs f () and add a new data points.

Depending on src configuration, new data points might have duration information (e.g. how long g () took, in nano-seconds) and status information (e.g. to check if an exception has been raised).

type ('a, 'b) rresult = ('a[ `Exn of exn | `Error of 'b ]) Stdlib.result

The type for extended results.

val rrun : ('a('b'c) rresult -> Data.t) src -> ('a -> tags) -> (unit -> ('b'c) Stdlib.result) -> ('b'c) Stdlib.result

Same as run but also record if the result is Ok or Error.

Reporters

TODO: explain and give an example

type reporter = {
now : unit -> int64;
at_exit : unit -> unit;
report : a. tags:tags -> data:data -> over:(unit -> unit) -> Src.t -> (unit -> 'a) -> 'a;
}

The type for reporters.

val nop_reporter : reporter

nop_reporter is the initial reporter returned by reporter, it does nothing if a metric gets reported.

val reporter : unit -> reporter

reporter () is the current reporter.

val set_reporter : reporter -> unit

set_reporter r sets the current reporter to r.

module SM : Stdlib.Map.S with type key = Src.t
val cache_reporter : unit -> (unit -> (tags * data) SM.t) * reporter

cache_reporter now () is a reporter that stores the last measurement from each source in a map (which can be retrieved by the returned function). This is an initial attempt to overcome the push vs pull interface. Each measurement _event_ is sent at an arbitrary point in time, while reporting over a communication channel may be rate-limited (i.e. report every 10 seconds statistics, rather than whenever they appear).

This is only a good idea for counters, histograms etc. may be useful for other numbers (such as time consumed between receive and send - the measurement should provide the information whether it's a counter or sth else).

OCaml Gc sources

The Gc module of the OCaml system provides counters of the memory management via Gc.quick_stat and Gc.stat function. Both are provided here.

val gc_stat : tags:'a Tags.t -> ('aunit -> data) src

gc_stat ~tags is the source of OCaml's Gc.stat () memory management counters.

val gc_quick_stat : tags:'a Tags.t -> ('aunit -> data) src

gc_quick_stat ~tags is the source of OCaml's Gc.quick_stat () memory management counters.

val report : ('a'b) src -> over:(unit -> unit) -> k:(unit -> 'c) -> ('a -> tags) -> ('b -> (data -> 'c) -> 'd) -> 'd

/

val init : ('a'b) src -> data -> unit
val now : unit -> int64