Условия канала - умная фильтрация уведомлений

Фильтрация уведомлений Echobell с помощью условных выражений: операторы, правила по времени и практики, снижающие усталость от оповещений.


Условия канала — это мощные выражения, которые определяют, когда следует отправлять уведомления. Задав условия для канала, вы можете фильтровать уведомления по содержимому переменных или HTTP-заголовков, чтобы подписчики получали только релевантные оповещения. Это необходимо, чтобы снизить усталость от оповещений и поддерживать высокое соотношение сигнала к шуму в системе уведомлений.

Считайте условия привратником для ваших уведомлений: они проверяют входящие данные триггера и пропускают уведомления только тогда, когда выполнены заданные критерии.

Как работают условия

Условия — это выражения, которые вычисляются в true или false. Когда канал запускается:

  • Если условия не заданы (пусто), уведомления отправляются всем подписчикам.
  • Если условия заданы, уведомления отправляются только тогда, когда выражение вычисляется в true.

Как писать условия

Условия записываются как выражения без обёрток {{}}, которые используются в шаблонах. Например:

status == "active"

Это условие разрешает отправку уведомлений только тогда, когда переменная status равна "active".

Частые сценарии

Вот несколько практических примеров использования условий:

Базовые проверки переменных

amount > 100

Уведомлять только тогда, когда переменная "amount" больше 100.

message != ""

Уведомлять только тогда, когда переменная "message" не пуста.

isUrgent == true

Уведомлять только тогда, когда переменная "isUrgent" равна true.

Проверка HTTP-заголовков

Доступ к HTTP-заголовкам возможен через специальную переменную header:

header["x-webhook-source"] == "grafana"

Уведомлять только тогда, когда пользовательский заголовок источника точно равен "grafana".

header["content-type"] == "application/json"

Уведомлять только тогда, когда тип содержимого — JSON.

header["x-priority"] == "high"

Уведомлять только тогда, когда пользовательский заголовок приоритета имеет значение "high".

Все ключи заголовков записываются строчными буквами.

Сложные условия

Несколько условий можно объединять логическими операторами:

(temperature > 30 || pressure > 100) && status == "monitoring"

Уведомлять только тогда, когда температура превышает 30 или давление превышает 100 и при этом статус равен "monitoring".

environment == "production" && (errorLevel == "critical" || errorLevel == "high")

Уведомлять только о критических ошибках или ошибках высокого уровня в производственной среде.

Поддерживаемые операторы

В выражениях условий поддерживаются следующие операторы:

ОператорОписаниеПример
==Равноstatus == "active"
!=Не равноstatus != "inactive"
!Логическое НЕ!isCompleted
<Меньшеcount < 10
>Большеprice > 99.99
<=Меньше или равноbattery <= 20
>=Больше или равноconfidence >= 0.95
&&Логическое ИisAdmin && isActive
||Логическое ИЛИisError || isWarning

Переменные условий

Когда канал запускается через вебхук, вам доступны:

  1. Параметры запроса из URL
  2. JSON-тело из POST-запросов
  3. HTTP-заголовки через объект header

Для email-триггеров доступны:

  • from: адрес отправителя письма
  • to: адрес получателя
  • subject: тема письма
  • text: тело письма в виде обычного текста
  • html: тело письма в формате HTML

Системные переменные времени (UTC)

Эти переменные доступны только для чтения и всегда есть и в условиях, и в шаблонах. Все значения вычисляются в UTC.

Следующие значения подставляются напрямую (плоско) и доступны по имени:

  • year: год из 4 цифр (число)
  • month: номер месяца 1–12
  • dayOfMonth: день месяца 1–31
  • dayOfWeek: день недели 0–6 (воскресенье = 0)
  • hour: час 0–23
  • minute: минута 0–59
  • second: секунда 0–59
  • date: строка YYYY-MM-DD
  • time: строка HH:mm:ss
  • iso: текущее время как строка ISO‑8601 (например, 2025-05-06T12:34:56.789Z)

Дополнительные значения доступны только в пространстве имён sys. (они не подставляются как плоские имена):

  • sys.timezone: константная строка "UTC"
  • sys.now: текущее время как строка ISO‑8601 (то же значение, что и iso)
  • sys.epochMs: миллисекунды с начала эпохи Unix (число)
  • sys.epochSeconds: секунды с начала эпохи Unix (число)
  • sys.monthName: название месяца January–December
  • sys.dayOfWeekName: название дня недели Sunday–Saturday

Пространство имён sys. также дублирует каждое плоское значение (например, sys.year, sys.hour).

Примеры:

// Будни с 09:00 до 17:00 UTC
hour >= 9 && hour < 17 && dayOfWeek >= 1 && dayOfWeek <= 5

// Только выходные
dayOfWeek == 0 || dayOfWeek == 6

// Первый день месяца в начале часа
dayOfMonth == 1 && minute == 0

Рекомендации

Начинайте с простого

Начните с базовых условий и усложняйте их по мере необходимости:

Этап 1: одиночные условия

temperature > 30

Этап 2: логические операторы

temperature > 30 && location == "server-room"

Этап 3: вложенная логика

(temperature > 30 || humidity > 80) && location == "server-room" && status == "monitoring"

Тестируйте тщательно

Проверьте условия на разных входных данных, чтобы убедиться, что они работают как задумано:

  1. Проверьте на обычных значениях — убедитесь, что условия срабатывают в ожидаемых сценариях
  2. Проверьте граничные случаи — что происходит ровно на пороговом значении?
  3. Проверьте с отсутствующими переменными — как условие обрабатывает недостающие данные?
  4. Проверьте с неожиданными типами — что если число придёт строкой?
  5. Используйте тестовые вебхуки — отправляйте тестовые триггеры с разными комбинациями данных

Документируйте условия

Добавляйте пояснения в поле заметки канала, чтобы объяснить сложные условия:

Заметка канала:
Условие: (cpu > 80 && memory > 90) || diskSpace < 10

Это условие вызывает оповещения, когда:
- загрузка CPU выше 80% И память выше 90%
- ИЛИ когда свободного места на диске остаётся меньше 10 ГБ

Так участники команды поймут логику оповещений, не разбирая само выражение.

Учитывайте граничные случаи

Предусмотрите отсутствующие переменные и неожиданные значения:

  • Отсутствующие переменные: неопределённые переменные вычисляются как пустое значение или false — учтите это в логике
  • Числовые сравнения: <, >, <= и >= приводят оба операнда через Number(), поэтому сравнивают числа, а не строки. "100" > "20" даёт true (100 > 20), а не результат лексикографического порядка.
  • Нечисловые значения: если одна из сторон сравнения <, >, <= или >= не является числом, Number() возвращает NaN, и сравнение всегда даёт false.
  • Равенство и сравнение: == и != используют нестрогое равенство (поэтому count == "5" совпадает с числом 5), а операторы порядка всегда сравнивают как числа.
  • Регистр символов: status == "Active" — это не то же самое, что status == "active"

Предотвращайте шторм оповещений

Используйте условия, чтобы не получать шквал уведомлений из-за кратковременных сбоев:

errorCount > 5    # А не просто errorCount > 0
cpuUsage > 90     # А не cpuUsage > 50
failureRate > 0.1 # А не просто hasFailures

Подбирайте пороги так, чтобы снизить шум и не пропустить критические события.

Фильтруйте по рабочим часам

Комбинируйте уровень серьёзности с условиями по времени:

severity == "critical" || (severity == "high" && hour >= 9 && hour < 17)

Так критические оповещения приходят круглосуточно, а оповещения высокого приоритета — только в рабочие часы.

Проверяйте заголовки

Проверяйте источник вебхука, чтобы отсечь спам и неавторизованные запуски:

header["x-webhook-source"] == "grafana" || header["x-webhook-source"] == "prometheus"

Проверка источника запроса добавляет дополнительный уровень безопасности.

Примеры из практики

Мониторинг серверов — оповещения по нарастанию

# Оповещать только при стабильно высокой загрузке CPU, а не при кратковременных всплесках
cpu > 80 && duration >= 300

Электронная коммерция — крупные заказы

# Уведомлять только о заказах дороже $500 или заказах с подозрением на мошенничество
orderAmount > 500 || isFraudSuspected == true

Разработка — критические сбои сборки

# Оповещать только о сбоях в основной ветке или неудачных развёртываниях
(branch == "main" || branch == "master") && status == "failed"

IoT — мониторинг окружающей среды

# Выход температуры за допустимый диапазон
temperature < 15 || temperature > 28

Безопасность — неудачные попытки входа

# Несколько неудачных входов с одного IP за короткое время
failedAttempts >= 3 && timeSinceFirst < 300

CI/CD — отслеживание развёртываний

# Уведомлять только о развёртываниях в production или сбоях в staging
(environment == "production") || (environment == "staging" && status == "failed")

Трейдинг — оповещения по цене

# Значительные движения цены сверх порога
(priceChange > 5 || priceChange < -5) && volume > 1000000

Поддержка — нарушения SLA

# Тикеты, приближающиеся к границе SLA или уже нарушившие её
ticketAge > slaThreshold || priority == "urgent"

Типовые шаблоны условий

Оповещения по порогу

value > threshold
percentage >= 90
count < minimumRequired

Фильтрация по статусу

status == "error" || status == "critical"
state != "healthy"
isActive == true

Фильтрация по временному окну

# Только рабочие часы (с 9:00 до 17:00 UTC, с понедельника по пятницу)
hour >= 9 && hour < 17 && dayOfWeek >= 1 && dayOfWeek <= 5

# Только нерабочее время
hour < 9 || hour >= 17 || dayOfWeek == 0 || dayOfWeek == 6

# Окна обслуживания в выходные
(dayOfWeek == 0 || dayOfWeek == 6) && hour >= 2 && hour < 6

Условия по нескольким факторам

# Комбинация нескольких критериев
severity == "high" && environment == "production" && region == "us-east-1"

# Либо критический уровень, либо production с высоким уровнем
severity == "critical" || (severity == "high" && environment == "production")

Сравнение строк

# Точное совпадение (оператора "contains" нет)
status == "error"
errorType == "database"

# Сравнение строк
environment == "production"
username != "test-user"

Условия вместе с шаблонами

Условия и шаблоны работают вместе и дают умные, контекстные уведомления:

Условие (отбирает, какие триггеры отправят уведомление):

temperature > 30 || humidity > 80

Шаблон (форматирует содержимое уведомления):

Title: Оповещение о среде: {{location}}
Body: Температура: {{temperature}}°C, влажность: {{humidity}}%

Такое разделение позволяет вам:

  1. Отфильтровать ненужные уведомления условиями
  2. Оформить важные уведомления шаблонами
  3. Адаптировать содержимое уведомления под уровень серьёзности

Подробнее о синтаксисе и возможностях шаблонов.

Отладка условий

Если условия работают не так, как ожидалось:

  1. Упростите условие — проверяйте по одному сравнению за раз
  2. Проверьте имена переменных — они должны совпадать точно, с учётом регистра
  3. Проверьте типы данных — подтвердите типы переменных тестовыми вебхуками
  4. Проверьте логику — разбейте сложное условие на части
  5. Проверьте приоритет операторов — используйте скобки, чтобы задать явный порядок
  6. Проверьте опечаткиheader["content-type"], а не header["Content-Type"]

Связанная документация

Дальнейшие шаги

Теперь, когда вы разобрались с условиями:


Грамотно применяя условия, вы снизите шум уведомлений и добьётесь того, что подписчики получают только те оповещения, которые для них релевантны и требуют действий. Начните с простых условий и постепенно усложняйте логику фильтрации по мере роста задач.