macula_diagnostics (macula v10.20.3)
View SourceStructured event emission + per-process metric accumulation.
Phase 1 implementation: events go through OTP logger with a structured report; metrics live in the calling process's dictionary. Phase 7 upgrades to Prometheus / OpenTelemetry exporters without changing this module's public surface.
Topic namespacing convention:
_macula.*— protocol-layer events (SDK)_hecate.*— station-layer events (Hecate-specific)
Summary
Functions
Emit a structured event at the default info level.
Emit a structured event at a specific level.
Allow domain => [macula] events through the default logger handler's filter chain.
Emit a metric. counter increments are summed across calls; gauge values overwrite the previous reading.
Drop all metric entries from the calling process's dictionary.
Snapshot all metrics held by the calling process.
Types
-type level() :: debug | info | notice | warning | error.
-type metric_type() :: counter | gauge.
-type sample() :: {Name :: binary(), metric_type(), number()}.
Functions
Emit a structured event at the default info level.
Emit a structured event at a specific level.
-spec install_domain_filter() -> ok.
Allow domain => [macula] events through the default logger handler's filter chain.
Every event this module emits is stamped domain => [macula] (above). On a release that includes sasl — true of every consumer's production build — the default handler installs a filter chain with filter_default => stop and only two explicit allows: events whose domain is [otp, sasl] (or a sub-domain of it) and events with no domain at all. [macula] matches neither, so every event/2,3 call was silently dropped before reaching any handler, in every consumer, always — confirmed live on the macula-station fleet (see CHANGELOG [10.5.5] there) after already being independently rediscovered and worked around three separate times at three separate call sites before anyone traced it to this one line. Call this once, from the macula application's own start/2, so every consumer gets it for free just by depending on macula — no per-consumer release config to remember.
-spec metric(binary(), metric_type(), number()) -> ok.
Emit a metric. counter increments are summed across calls; gauge values overwrite the previous reading.
-spec reset() -> ok.
Drop all metric entries from the calling process's dictionary.
-spec snapshot() -> [sample()].
Snapshot all metrics held by the calling process.