Documentation
¶
Overview ¶
Package syntheticalert emits a synthetic alert measurement so you can prove, continuously and in production, that your alerting pipeline works.
A SyntheticAlert's Value method is 1 while the synthetic alert should be firing and 0 otherwise, on a memoryless schedule. Hand Value to whichever metrics client you already use, alert on the resulting gauge, and route that alert to a Triple Pat check-in timer (https://triplepat.com); every delivered alert becomes a check-in, and the timer raises an alarm if the alerts stop arriving — the one failure your alerting system cannot report about itself.
Prometheus:
alert, err := syntheticalert.New()
promauto.NewGaugeFunc(prometheus.GaugeOpts{Name: "triplepat_synthetic_alert", Help: "..."}, alert.Value)
OpenTelemetry:
gauge, _ := meter.Float64ObservableGauge("triplepat.synthetic.alert")
meter.RegisterCallback(func(_ context.Context, o metric.Observer) error {
o.ObserveFloat64(gauge, alert.Value())
return nil
}, gauge)
The library owns no metric, starts no goroutine, and has no dependencies.
Index ¶
Constants ¶
const ( DefaultMeanInterval = time.Hour DefaultMinInterval = 10 * time.Minute DefaultMaxInterval = 2 * time.Hour DefaultFiringDuration = 10 * time.Minute )
Defaults for the memoryless schedule, overridable with WithMeanInterval, WithMinInterval, WithMaxInterval, and WithFiringDuration. The max bound exists because an unbounded exponential distribution occasionally produces gaps long enough to false-alarm the check-in timer this library exists to feed; the min bound guarantees the alert visibly resolves between firings.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Option ¶
type Option func(*config) error
Option configures New.
func WithFiringDuration ¶
WithFiringDuration sets how long Value reports 1 during each firing. It must be shorter than the mean interval between firings.
func WithMaxInterval ¶
WithMaxInterval sets an upper bound on the silent gap between firings. It must be at least the mean interval. See WithMinInterval for the all-equal case.
func WithMeanInterval ¶
WithMeanInterval sets the mean of the exponential distribution the silent gaps are drawn from, before truncation to the min and max bounds. The gap is measured from the end of one firing to the start of the next. Truncation pulls the realized average toward the window's interior: with the defaults it is about 49 minutes, not an hour.
func WithMinInterval ¶
WithMinInterval sets a lower bound on the silent gap between firings, guaranteeing the alert stays resolved at least that long. It must not exceed the mean interval. Setting min, mean, and max all equal is allowed: every gap is then exactly that long and the schedule is periodic, which is pointless in production but handy for deterministic debugging.
type SyntheticAlert ¶
type SyntheticAlert struct {
// contains filtered or unexported fields
}
SyntheticAlert is a measurement callback for a synthetic alert.
Each firing holds Value at 1 for exactly the firing duration. The silent gap between firings, from the end of one to the start of the next, is exponentially distributed (memoryless) with the configured mean: an attempt at a Poisson process, which cannot synchronize with cron jobs or scrape cycles. As a nod to practicality the gap is truncated to the configured min and max, which makes the process only roughly Poisson; widen the bounds to get closer.
The schedule advances lazily: nothing happens until Value is called, at which point every transition up to time.Now() is replayed, on the monotonic clock. Value is safe for concurrent use.
func New ¶
func New(opts ...Option) (*SyntheticAlert, error)
New returns a SyntheticAlert with the given options applied to the defaults. It returns an error if an option is invalid.
func (*SyntheticAlert) Value ¶
func (a *SyntheticAlert) Value() float64
Value returns 1 if the synthetic alert should be firing right now and 0 otherwise. It replays every schedule transition between the last call and now, so the realized schedule is the same whatever the scrape cadence.