Packages

An event router that lives inside your Elixir app. Declare the occurrences you care about; Kepler enriches them with in-VM context and delivers them to an external consumer.

Current section

Files

Jump to
kepler CHANGELOG.md
Raw

CHANGELOG.md

# Changelog
All notable changes to this project are documented here. The format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
Watch names are the event ids consumers route on, and the event payload is
versioned by its `"schema"` field. A change to either is a breaking change and
will be called out here.
## [Unreleased]
## [0.1.0]
Initial release. Ships signal tiers 0 through 2; tracing is deliberately out of
scope.
### Added
- `use Kepler` and the `watch` DSL: `source`, `measure`, `filter`, `enrich`,
`recent`, `severity`, `sink`, `meta`, and `fire`.
- **Crash attribution.** `source crash_report: :any` and
`source supervisor_report: :child_terminated` deliver OTP crash and
supervisor reports, with `enrich` pulling the dying process's state, last
message, stacktrace, and `Logger` metadata into the event. One crash produces
one event despite OTP emitting three reports for it.
- A two-part event contract: a small, fully-required core (`id`, `node`,
`watch`, `timestamp`, `severity`, `state`) plus a best-effort `context` map
whose inapplicable keys are absent rather than null.
- Named sinks with per-watch routing (`sink :siem`), and a `guarantee:` key
declaring `:best_effort` or `:at_least_once`. Only `:best_effort` is
implemented; asking for `:at_least_once` warns at boot and delivers
best-effort.
- An optional `c:Kepler.Sink.format/1` callback, so a sink's wire format is
replaceable without reimplementing its transport.
- Compile-time checking of every declaration — unknown measurements, unknown
identifiers in conditions, duplicate watch names, and cycles between
conditions are build failures.
- Tier 0 sources: `system_monitor:`, with graceful yielding when another
process already holds the node's single system monitor.
- Tier 1 sources: `telemetry:`, with `:count`, `:rate`, `:sum`, `:average`, and
`percentile:` aggregates backed by lock-free counters and a log-linear
histogram.
- Tier 2 sources: `process:` and `vm:`, sampled from a declared watchlist on
the tick.
- Composite conditions across watches, evaluated in dependency order.
- `sustained:` and `cooldown:` debouncing as part of the declaration, plus
optional `resolve: true` notices.
- Ring buffer capture (`recent`), so an event carries the observations around it.
- `Kepler.Sink.Webhook` with HMAC-SHA256 signing and TLS verification, and
`Kepler.Sink.Callback` — two implementations rather than three, so the
behaviour is shaped by real use rather than guessed at in three directions.
- `Kepler.Transport` for plugging in an HTTP client you already run.
- Bounded, non-blocking emission with a configurable drop policy. An event
routed to several sinks is delivered to all of them concurrently and in
isolation: a sink that raises, exits, or wedges is recorded as that sink's
failure and cannot stop its siblings. A sink that stops responding is killed
after `:delivery_timeout`.
- `Kepler.Budget`: self-measured overhead and automatic shedding.
- `Kepler.status/0`, `Kepler.watches/0`, `Kepler.recent/1`, `Kepler.tick/0`,
and `Kepler.drain/1` for introspection and testing.
[Unreleased]: https://github.com/houllette/kepler/compare/v0.1.0...HEAD
[0.1.0]: https://github.com/houllette/kepler/releases/tag/v0.1.0