-module(pharos@probe).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/pharos/probe.gleam").
-export([new/5, id/1, event_name/1, interval_ms/1, source/1, decode/2, threshold_id/1]).
-export_type([source/0, probe/0, comparison/0, probe_threshold/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Custom monitoring probes - the pluggable lane of pharos.\n"
"\n"
" The built-in `Statistic` / `Measurement` / `Threshold` enums cover BEAM\n"
" and host signals. A `Probe` opens the same \n"
" `poll` -> `decode` -> `threshold` -> `alert` \n"
" pipeline to *any* signal a caller can express, without modifying\n"
" pharos: it bundles how to poll (a `Source`), the telemetry event it\n"
" emits, and how to decode that event into named numeric readings\n"
" (`MetricSample`). `ProbeThreshold`s compare a single sample field against\n"
" a limit and feed the same soak/cool alert machinery the BEAM lane uses.\n"
"\n"
" This is what lets a consumer such as `logothetes` monitor MicroVMs:\n"
" register a probe whose `Source` points at an emitter that reads\n"
" `/proc/<pid>` and `telemetry:execute`s the readings, plus thresholds over\n"
" the decoded fields.\n"
).
-type source() :: {custom_mfa,
gleam@erlang@atom:atom_(),
gleam@erlang@atom:atom_(),
list(gleam@dynamic:dynamic_())}.
-opaque probe() :: {probe,
binary(),
list(gleam@erlang@atom:atom_()),
integer(),
source(),
fun((pharos@measurement:telemetry_event()) -> {ok,
gleam@dict:dict(binary(), float())} |
{error, binary()})}.
-type comparison() :: {above, float()} | {below, float()}.
-type probe_threshold() :: {probe_threshold,
binary(),
binary(),
comparison(),
pharos@alert:alert_level()}.
-file("src/pharos/probe.gleam", 56).
?DOC(
" Define a probe.\n"
"\n"
" - `id` - stable identifier, referenced by `ProbeThreshold.probe_id`.\n"
" - `event_name` - the telemetry event the `source` emits (e.g.\n"
" `[atom.create(\"logothetes\"), atom.create(\"vm\"), atom.create(\"metrics\")]`).\n"
" - `interval_ms` - how often to poll.\n"
" - `source` - how the reading is produced.\n"
" - `decode` - lift the raw telemetry event into a `MetricSample`.\n"
).
-spec new(
binary(),
list(gleam@erlang@atom:atom_()),
integer(),
source(),
fun((pharos@measurement:telemetry_event()) -> {ok,
gleam@dict:dict(binary(), float())} |
{error, binary()})
) -> probe().
new(Id, Event_name, Interval_ms, Source, Decode) ->
{probe, Id, Event_name, Interval_ms, Source, Decode}.
-file("src/pharos/probe.gleam", 73).
?DOC(" The probe's stable identifier.\n").
-spec id(probe()) -> binary().
id(Probe) ->
erlang:element(2, Probe).
-file("src/pharos/probe.gleam", 78).
?DOC(" The telemetry event name the probe emits.\n").
-spec event_name(probe()) -> list(gleam@erlang@atom:atom_()).
event_name(Probe) ->
erlang:element(3, Probe).
-file("src/pharos/probe.gleam", 83).
?DOC(" The probe's polling interval in milliseconds.\n").
-spec interval_ms(probe()) -> integer().
interval_ms(Probe) ->
erlang:element(4, Probe).
-file("src/pharos/probe.gleam", 88).
?DOC(" How the probe is polled.\n").
-spec source(probe()) -> source().
source(Probe) ->
erlang:element(5, Probe).
-file("src/pharos/probe.gleam", 94).
?DOC(
" Decode a raw telemetry event into a `MetricSample` using the probe's\n"
" decoder.\n"
).
-spec decode(probe(), pharos@measurement:telemetry_event()) -> {ok,
gleam@dict:dict(binary(), float())} |
{error, binary()}.
decode(Probe, Event) ->
(erlang:element(6, Probe))(Event).
-file("src/pharos/probe.gleam", 124).
?DOC(
" Stable string id derived from a probe threshold. Used to register the\n"
" per-threshold alert manager under a deterministic name (mirrors\n"
" `config.threshold_id` for the BEAM lane).\n"
).
-spec threshold_id(probe_threshold()) -> binary().
threshold_id(Threshold) ->
Comparison = case erlang:element(4, Threshold) of
{above, _} ->
<<"above"/utf8>>;
{below, _} ->
<<"below"/utf8>>
end,
<<<<<<<<(erlang:element(2, Threshold))/binary, "_"/utf8>>/binary,
(erlang:element(3, Threshold))/binary>>/binary,
"_"/utf8>>/binary,
Comparison/binary>>.