macula_diagnostics (macula v11.4.0)
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.
bounded_event/3 logs an event at most once per 10 seconds per event name, node-wide, with a count of the rest (macula_diagnostics_bound).
Topic namespacing convention:
_macula.*— protocol-layer events (SDK)_hecate.*— station-layer events (Hecate-specific)
Summary
Functions
Emit a structured event at most once per 10 seconds per event name, node-wide. An event inside that window is counted instead, and the next line for the name carries the latest properties with suppressed, the number held back since the line before. Callers update the counts table themselves, so a burst of events never queues on a process.
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 most once per 10 seconds per event name, node-wide. An event inside that window is counted instead, and the next line for the name carries the latest properties with suppressed, the number held back since the line before. Callers update the counts table themselves, so a burst of events never queues on a process.
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.