Skip to Content
Tares

Which aggregates and filter operators can a trigger condition use?

Tares trigger conditions use one of six aggregates: count, sum, avg, max, min or any. Filters use one of eight operators: eq, neq, contains, gt, lt, gte, lte or in. A filter field is a label your sources carry or one of event_type, source, text or key_value. Setting group_by to key_value evaluates the condition per entity.

How it works

A trigger watches one or more sources and checks its condition as events are ingested. When the condition holds, Tares pushes to every subscribed webhook.

Aggregates. The condition’s aggregate is one of:

  • count
  • sum
  • avg
  • max
  • min
  • any

The predicate sets the threshold, for example > 1.0, and window sets how far back the aggregate looks.

Filter operators. Filters narrow which events count and which are handed over. Each filter has the shape field, op, value. The op is one of:

  • eq
  • neq
  • contains
  • gt
  • lt
  • gte
  • lte
  • in

The in operator takes a list of values, such as a list of repos.

Filter fields. A filter field is a label the trigger’s sources carry, or one of four built-in fields:

  • event_type
  • source
  • text
  • key_value

Numeric field. Triggers aggregate a typed field, so at least one of the trigger’s sources must produce a numeric typed field. A Prometheus source that emits rate_5xx, labeled by service, is one example. The pr-merged example below counts events and sets no field at all.

Per entity. group_by: [key_value] evaluates the condition per entity, so each service fires independently. key_field names the label that identifies the entity across sources, and it defaults to the first source’s primary label.

Set it up

  1. Make sure at least one source produces a numeric typed field. For the max example below, a Prometheus source emitting rate_5xx and labeled by service works.
  2. Add the trigger on the project’s page (the + next to Triggers), under Triggers → Add trigger, or in the catalog YAML. Over MCP, an agent can use create_trigger and update_trigger, which take the same fields.
  3. Name the sources, the filters, the aggregate with its field and predicate, the window and group_by:
triggers: - name: error_spike project: checkout watch # optional; the Default project when left out sources: [checkout_metrics, checkout_logs] key_field: service # optional; default: the first source's primary label filters: # optional; only these events count - { field: env, op: eq, value: prod } condition: aggregate: max # count | sum | avg | max | min | any field: rate_5xx predicate: "> 1.0" # fire when max(rate_5xx) over the window exceeds 1.0 window: 1m group_by: [key_value] # evaluated per entity (per service) emit: kind: error_spike context_window: 15m # how much timeline to hand the agent cooldown: 5m # minimum gap between firings for the same entity
  1. To count events instead of aggregating a number, use count and leave field out. This trigger uses the in operator on the repo label, plus eq filters on event_type and action:
- name: pr-merged sources: [github] filters: - { field: event_type, op: eq, value: pull_request } - { field: action, op: eq, value: merged } - { field: repo, op: in, value: [acme/checkout-api, acme/payments] } condition: { aggregate: count, predicate: "> 0", window: 5m } cooldown: 5m
  1. Subscribe an agent to the trigger so a firing wakes it. The triggers guide covers subscriptions and the dispatch payload.

What you get

  • A condition that matches the incident shape you care about. For example, max(p99_ms) > 1000 fits latency and max(rate_5xx) > 1.0 fits an error storm.
  • Filters that keep unrelated events out of both the condition and the context handed to the agent.
  • Independent firing for each entity when you group by key_value, so one noisy service does not hide another.
  • A cooldown that sets the minimum gap between firings for the same entity, so a flapping condition does not fire repeatedly.
  • A logged firing every time, with the correlated timeline across the trigger’s sources over context_window. The agent gets context without a follow-up call.

The AI SRE guide shows how triggers fit with the rest of the monitoring flow.

When something else fits

  • To look at sources on a clock instead of on a condition, give the trigger a schedule with condition: every: 10m. It fires once per interval and hands over a summary of the window.
  • If you only need an agent to review events now and then rather than react to a threshold, a scheduled trigger is simpler than choosing an aggregate.

Still stuck? Get help

Last updated on