Class PipelineCounters

java.lang.Object
io.github.pimak.ntfy.core.PipelineCounters

public final class PipelineCounters extends Object
Read-only, monotonic observability counters for the alert pipeline, letting operators "alert on the alerter" (e.g. a spike in failed() signalling a revoked token or a topic ACL change).

Three lightweight tallies are tracked:

  • published() — notifications actually accepted by ntfy: a successful individual AlertEngine.submit(io.github.pimak.ntfy.core.AlertEvent) publish and a successful storm-digest publish (the latter also covers the synchronous flush on AlertEngine.stop()).
  • suppressed() — events the rate-limiter gate rejected (over the per-window allowance). This is the only increment site, so it is disjoint from failed() and never double-counts.
  • failed() — failed publish attempts: an unsuccessful individual publish, an unexpected exception during an individual publish, and an unsuccessful digest publish.

Pulled, never logged. The engine only ever increments these; nothing here is emitted through Diagnostics or any logger, so surfacing them cannot re-enter the logging pipeline and the loop-safe design is preserved. Callers read the values on demand.

Monotonicity. The increment methods are package-private, so only the engine mutates the counters; external callers can only read. Backed by plain AtomicLong, the class holds no threads, resources, or static initializers and is GraalVM native-image safe. When an adapter injects a single PipelineCounters instance into every engine it builds (as the Logback appender does), the counters accumulate monotonically across engine start()/stop() cycles and LoggerContext resets for the adapter's whole lifetime.

  • Constructor Details

    • PipelineCounters

      public PipelineCounters()
  • Method Details

    • published

      public long published()
      Notifications actually accepted by ntfy (individual + digest publishes).
    • suppressed

      public long suppressed()
      Events rejected by the rate-limiter gate (over the per-window allowance).
    • failed

      public long failed()
      Failed publish attempts (individual publish failure/exception + digest publish failure).
    • snapshot

      public PipelineCounters.Snapshot snapshot()
      A single read of all three counters. The reads are not taken under a common lock, so the triple is only near-atomic — adequate for observability where operators track rates/deltas, not exact cross-counter consistency at an instant.