Current section
Files
Jump to
Current section
Files
src/pharos@threshold_eval.erl
-module(pharos@threshold_eval).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/pharos/threshold_eval.gleam").
-export([evaluate_probe/2, evaluate/2]).
-export_type([verdict/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(
" Evaluate a `Threshold` against a decoded `Measurement`.\n"
"\n"
" Returns a three-way verdict so callers can branch without reaching\n"
" for nested `case` over the cartesian product of measurements and\n"
" thresholds. Helper functions match every measurement variant\n"
" exhaustively, so adding a new measurement kind surfaces as a\n"
" compiler warning here.\n"
).
-type verdict() :: not_applicable | healthy | breached.
-file("src/pharos/threshold_eval.gleam", 151).
-spec verdict(boolean()) -> verdict().
verdict(Is_breached) ->
case Is_breached of
true ->
breached;
false ->
healthy
end.
-file("src/pharos/threshold_eval.gleam", 38).
?DOC(
" Evaluate a probe `threshold` against a decoded probe `sample`, returning\n"
" the same `Verdict` as `evaluate/2`. A `NotApplicable` verdict means the\n"
" threshold's field is absent from this sample, so the caller should neither\n"
" breach nor recover.\n"
).
-spec evaluate_probe(
gleam@dict:dict(binary(), float()),
pharos@probe:probe_threshold()
) -> verdict().
evaluate_probe(Sample, Threshold) ->
case gleam_stdlib:map_get(Sample, erlang:element(3, Threshold)) of
{error, nil} ->
not_applicable;
{ok, Value} ->
case erlang:element(4, Threshold) of
{above, Limit} ->
verdict(Value > Limit);
{below, Limit@1} ->
verdict(Value < Limit@1)
end
end.
-file("src/pharos/threshold_eval.gleam", 87).
-spec check_memory(
pharos@measurement:measurement(),
fun((pharos@measurement:beam_memory_stats()) -> boolean())
) -> verdict().
check_memory(Measurement, Predicate) ->
case Measurement of
{beam_memory, Memory} ->
verdict(Predicate(Memory));
{beam_run_queues, _} ->
not_applicable;
{beam_system_counts, _} ->
not_applicable;
{beam_persistent_term, _} ->
not_applicable;
{process_info, _} ->
not_applicable;
{cluster_nodes, _} ->
not_applicable;
{host_memory, _} ->
not_applicable;
{host_disk, _} ->
not_applicable
end.
-file("src/pharos/threshold_eval.gleam", 103).
-spec check_run_queue(
pharos@measurement:measurement(),
fun((pharos@measurement:run_queue_stats()) -> boolean())
) -> verdict().
check_run_queue(Measurement, Predicate) ->
case Measurement of
{beam_run_queues, Queue} ->
verdict(Predicate(Queue));
{beam_memory, _} ->
not_applicable;
{beam_system_counts, _} ->
not_applicable;
{beam_persistent_term, _} ->
not_applicable;
{process_info, _} ->
not_applicable;
{cluster_nodes, _} ->
not_applicable;
{host_memory, _} ->
not_applicable;
{host_disk, _} ->
not_applicable
end.
-file("src/pharos/threshold_eval.gleam", 119).
-spec check_system_counts(
pharos@measurement:measurement(),
fun((pharos@measurement:system_count_stats()) -> boolean())
) -> verdict().
check_system_counts(Measurement, Predicate) ->
case Measurement of
{beam_system_counts, Counts} ->
verdict(Predicate(Counts));
{beam_memory, _} ->
not_applicable;
{beam_run_queues, _} ->
not_applicable;
{beam_persistent_term, _} ->
not_applicable;
{process_info, _} ->
not_applicable;
{cluster_nodes, _} ->
not_applicable;
{host_memory, _} ->
not_applicable;
{host_disk, _} ->
not_applicable
end.
-file("src/pharos/threshold_eval.gleam", 135).
-spec check_persistent_term(
pharos@measurement:measurement(),
fun((pharos@measurement:persistent_term_stats()) -> boolean())
) -> verdict().
check_persistent_term(Measurement, Predicate) ->
case Measurement of
{beam_persistent_term, Term} ->
verdict(Predicate(Term));
{beam_memory, _} ->
not_applicable;
{beam_run_queues, _} ->
not_applicable;
{beam_system_counts, _} ->
not_applicable;
{process_info, _} ->
not_applicable;
{cluster_nodes, _} ->
not_applicable;
{host_memory, _} ->
not_applicable;
{host_disk, _} ->
not_applicable
end.
-file("src/pharos/threshold_eval.gleam", 53).
?DOC(" Evaluate `threshold` against `measurement` and return a `Verdict`.\n").
-spec evaluate(pharos@measurement:measurement(), pharos@config:threshold()) -> verdict().
evaluate(Measurement, Threshold) ->
case Threshold of
{total_memory, Limit} ->
check_memory(
Measurement,
fun(Memory) -> erlang:element(3, Memory) > Limit end
);
{process_memory, Limit@1} ->
check_memory(
Measurement,
fun(Memory@1) -> erlang:element(4, Memory@1) > Limit@1 end
);
{system_memory, Limit@2} ->
check_memory(
Measurement,
fun(Memory@2) -> erlang:element(6, Memory@2) > Limit@2 end
);
{binary_memory, Limit@3} ->
check_memory(
Measurement,
fun(Memory@3) -> erlang:element(9, Memory@3) > Limit@3 end
);
{ets_memory, Limit@4} ->
check_memory(
Measurement,
fun(Memory@4) -> erlang:element(11, Memory@4) > Limit@4 end
);
{total_run_queue, Limit@5} ->
check_run_queue(
Measurement,
fun(Queue) -> erlang:element(2, Queue) > Limit@5 end
);
{cpu_run_queue, Limit@6} ->
check_run_queue(
Measurement,
fun(Queue@1) -> erlang:element(3, Queue@1) > Limit@6 end
);
{process_count, Limit@7} ->
check_system_counts(
Measurement,
fun(Counts) -> erlang:element(2, Counts) > Limit@7 end
);
{atom_count, Limit@8} ->
check_system_counts(
Measurement,
fun(Counts@1) -> erlang:element(3, Counts@1) > Limit@8 end
);
{port_count, Limit@9} ->
check_system_counts(
Measurement,
fun(Counts@2) -> erlang:element(4, Counts@2) > Limit@9 end
);
{persistent_term_count, Limit@10} ->
check_persistent_term(
Measurement,
fun(Term) -> erlang:element(2, Term) > Limit@10 end
);
{persistent_term_memory, Limit@11} ->
check_persistent_term(
Measurement,
fun(Term@1) -> erlang:element(4, Term@1) > Limit@11 end
)
end.