Kepler.Watch (Kepler v0.1.0)

Copy Markdown View Source

A single compiled watch declaration.

This is the runtime shape of what you wrote in a Kepler module. You do not build one by hand; the DSL produces them and Kepler.__kepler_watches__/0 returns them, in dependency order.

Reading one is the fastest way to see what a declaration actually cost: :tier says which signal tier it uses, and the sampling and hot-path notes in Kepler explain what each tier is charged.

Summary

Types

How raw observations are folded into a single number per tick.

Delivery semantics. Only :best_effort is implemented.

How loudly a consumer should react. Always present on an event.

Where a watch's occurrences come from.

t()

Functions

Human-readable name for an aggregate, for the event payload.

Named aggregates a telemetry measurement can use, excluding percentiles.

How many :counters slots this watch's aggregate needs, or nil if it does not use counters.

Whether a source produces discrete occurrences rather than a number per tick.

Delivery guarantees a watch may ask a sink for.

The measurement keys a source accepts.

Builds a watch from already-validated fields.

Fields a report source can be asked to enrich with.

Severities a watch may declare, quietest first.

System monitor conditions the VM can enforce on Kepler's behalf.

The signal tier a source belongs to.

Types

aggregate()

@type aggregate() ::
  :count | :rate | :sum | :average | :gauge | {:percentile, number()}

How raw observations are folded into a single number per tick.

guarantee()

@type guarantee() :: :best_effort | :at_least_once

Delivery semantics. Only :best_effort is implemented.

severity()

@type severity() :: :info | :warning | :error | :critical

How loudly a consumer should react. Always present on an event.

source()

@type source() ::
  {:telemetry, [atom()]}
  | {:process, atom() | pid()}
  | {:vm, :memory | :system | :scheduler}
  | {:system_monitor, atom() | {atom(), pos_integer()}}
  | {:supervisor_report, :child_terminated}
  | {:crash_report, :any}

Where a watch's occurrences come from.

t()

@type t() :: %Kepler.Watch{
  condition: {module(), atom()} | nil,
  condition_source: String.t() | nil,
  cooldown: non_neg_integer(),
  deps: [atom()],
  enrich: [atom()],
  filter: {module(), atom()} | nil,
  guarantees: %{required(atom()) => guarantee()},
  immediate: boolean(),
  measure: %{key: atom() | nil, aggregate: aggregate()} | nil,
  meta: map(),
  name: atom(),
  notify_resolved: boolean(),
  reads: [atom()],
  recent: %{size: pos_integer(), keys: :all | [atom()]} | nil,
  requires: [atom()],
  severity: severity(),
  sinks: :all | [atom()],
  source: source(),
  sustained: non_neg_integer(),
  tier: 0..2,
  unit: {System.time_unit(), System.time_unit()} | nil
}

Functions

aggregate_name(aggregate)

@spec aggregate_name(aggregate()) :: String.t()

Human-readable name for an aggregate, for the event payload.

aggregates()

@spec aggregates() :: [atom()]

Named aggregates a telemetry measurement can use, excluding percentiles.

counter_slots(watch)

@spec counter_slots(t()) :: pos_integer() | nil

How many :counters slots this watch's aggregate needs, or nil if it does not use counters.

Percentiles need the full histogram; everything else needs one or two words.

discrete?(arg1)

@spec discrete?(source()) :: boolean()

Whether a source produces discrete occurrences rather than a number per tick.

guarantees()

@spec guarantees() :: [guarantee()]

Delivery guarantees a watch may ask a sink for.

measurements(group)

@spec measurements(atom()) :: [atom()]

The measurement keys a source accepts.

Used by the DSL to reject measure :vibes at compile time rather than letting it sample nil forever.

new(fields)

@spec new(keyword() | map()) :: t()

Builds a watch from already-validated fields.

report_fields()

@spec report_fields() :: [atom()]

Fields a report source can be asked to enrich with.

These come out of the report OTP already assembled — by the time it arrives the process is gone, so there is nothing to introspect and everything worth having was captured at crash time.

severities()

@spec severities() :: [severity()]

Severities a watch may declare, quietest first.

system_monitor_types()

@spec system_monitor_types() :: [atom()]

System monitor conditions the VM can enforce on Kepler's behalf.

tier(arg)

@spec tier(source()) :: 0..2

The signal tier a source belongs to.

Tier 0 is enforced by the VM and costs nothing until it trips. Tier 1 is a telemetry handler doing an atomic increment. Tier 2 is work done on the tick.