Введение
![img](https://habrastorage.org/getpro/habr/upload_files/495/4fc/17e/4954fc17e9ff33b506654e6d8dd6338c.png)
Многие, наверняка, сталкивались с мемом this is fine, или оригинальным комиксом. Так выглядит типичный день для многих дежурных сотрудников. Оперативные дежурные получают много оповещений, и работа со слишком большим количеством оповещений может привести к усталости от оповещений — чувству истощения, вызванному реагированием на оповещения, которые не имеют приоритета или четких действий. Убедиться в том, что оповещения действенны и точны, а не являются ложными срабатываниями, крайне важно, потому что если дежурные сотрудники постоянно получают ложные уведомления, они могут перестать обращать на них внимание и игнорировать даже важные сообщения. С этой целью в Cloudflare многочисленные команды проводят периодический анализ оповещений, каждая команда разрабатывает свои собственные панели мониторинга для отчетности. Как члены команды Observability, мы столкнулись с ситуациями, когда команды сообщали о неточностях в уведомлениях или случаях, когда уведомления не срабатывали, а также помогали бороться с создающими шум/флапающими (flapping) уведомлениями.
Команда Observability стремится расширить понимание технологической стека, собирая и анализируя более широкий спектр данных. В этом посте мы углубимся в мониторинг уведомлений, обсуждая ее важность и подход Cloudflare к ее достижению. Мы также рассмотрим, как мы преодолеваем недостатки в отчетности уведомлений в нашей архитектуре, чтобы упростить устранение неполадок с помощью открытых инструментов и лучших практик. Если вам интересна тема эффективного использования уведомлений и улучшения контроля, устойчивости и здоровья дежурных сотрудников, то продолжайте читать, чтобы узнать больше о наших подходах и решениях.
![Alert fatigue](https://habrastorage.org/getpro/habr/upload_files/84d/d9e/55f/84dd9e55fa16284e8d634154dfaa8593.png)
Дежурство может быть настоящим стрессом: нарушает режим сна, портит социальную жизнь и досуг, и может привести к эмоциональному выгоранию. Хотя эмоциональное выгорание может быть вызвано несколькими факторами, одним из них может быть получение избыточных или ложных уведомлений, которые не важны и не требуют действий. Анализ уведомлений может помочь снизить риск такого выгорания, уменьшив ненужные прерывания и улучшив общую эффективность процесса дежурства. Он включает периодический обзор и обратную связь с системой для улучшения качества уведомлений. К сожалению, только некоторые компании или команды проводят анализ уведомлений, хотя это является важной информацией, к которой должен иметь доступ каждый дежурный или менеджер.
Анализ оповещений полезен для дежурного персонала, позволяя ему легко увидеть, какие оповещения сработали во время его смены, чтобы помочь составить записки о передаче дел и не пропустить ничего важного. Кроме того, менеджеры могут создавать отчеты на основе этой статистики, чтобы увидеть улучшения со временем, а также оценить уязвимость дежурных к выгоранию. Анализ оповещений также помогает при составлении отчетов о происшествиях, чтобы узнать, были ли поданы оповещения, или определить, когда начался инцидент.
Давайте сначала разберемся, как устроен стек оповещений и как мы использовали инструменты с открытым исходным кодом для получения большей видимости (visibility), что позволило нам проанализировать и оптимизировать его эффективность.
Архитектура Prometheus в Cloudflare
![img](https://habrastorage.org/getpro/habr/upload_files/05c/6da/8c9/05c6da8c9ccf05ab6d395898cf7c8199.png)
В Cloudflare мы в значительной степени полагаемся на Prometheus для мониторинга. У нас есть дата‑центры в более чем 310 городах, и в каждом из них установлено несколько экземпляров Prometheus. В общей сложности у нас более 1100 серверов Prometheus. Все оповещения отправляются в центральный Alertmanager, где у нас настроены различные интеграции для их маршрутизации. Кроме того, используя webhook‑ки alertmanager‑а, мы сохраняем все оповещения в хранилище данных для анализа.
Жизненный цикл оповещения
Prometheus собирает метрики с настроенных целей через заданные промежутки времени, оценивает выражения правил, отображает результаты и может запускать оповещения при выполнении условий оповещений. Как только оповещение переходит в состояние срабатывания (fire), оно отправляется в alertmanager.
![Alertmanager core concepts](https://habrastorage.org/getpro/habr/upload_files/9f7/388/f79/9f7388f79f72a92ef991e70a1ce24862.png)
В зависимости от конфигурации, получив оповещение, Alertmanager может подавить (inhibit), сгруппировать (group), заглушить (silence) или направить (route) оповещения в подходящую интеграцию с приемником, например, в чат, PagerDuty или тикет‑систему. При правильной настройке Alertmanager может уменьшить шум от оповещений. К сожалению, так происходит не всегда, поскольку не все оповещения настроены оптимально.
![LifeCycle of an alert (Alertmanager)](https://habrastorage.org/getpro/habr/upload_files/505/c9c/de9/505c9cde9a679194a78927b00173e519.png)
В Alertmanager оповещения первоначально переходят в состояние firing, где они могут быть подавлены (inhibited) или заглушены на время (silenced). Они возвращаются в состояние firing, когда истекает срок действия заглушания или устраняется подавляющее оповещение, и в конечном итоге переходят в состояние resolved.
Alertmanager отправляет уведомления о firing
и resolved
событиях оповещения через интеграцию с webhook‑ами. Мы использовали alertmanager2es, который получает уведомления об оповещениях через webhook от Alertmanager и вставляет их в индекс Elasticsearch для поиска и анализа. Alertmanager2es был надежным инструментом для нас на протяжении многих лет, предлагая способы мониторинга объема оповещений, шумных оповещений и создания своего рода отчетов по оповещениям. Однако у него были свои недостатки. Отсутствие состояний «заглушено» (silenced) и «подавлено» (inhibited) для оповещения затрудняло поиск и устранение проблем. Мы часто гадали, почему оповещение не срабатывает — было ли оно заглушено другим оповещением или, возможно, подавлено одним из них? Не имея конкретных данных, мы не могли подтвердить, что происходит на самом деле.
Поскольку Alertmanager через интеграции с использованием webhook‑ами не предоставляет уведомлений о событиях «заглушенного» или «подавленного» оповещения, отчетность по оповещениям, которую мы делали, была несколько недостаточной или неполной. Однако Alertmanager API предоставляет возможность запросов, и, запросив у alertmanager эндпоинт /api/alerts, мы можем получить данные про оповещения silenced и inhibited. Наличие всех четырех состояний в хранилище данных расширит наши возможности по улучшению отчетности по оповещениям и устранению проблем с Alertmanager.
![Интерфейсы для предоставления информации о состояниях оповещения. Alertmanager alert notifications](https://habrastorage.org/getpro/habr/upload_files/cb5/f39/050/cb5f39050f554d5a13950b323d5fdff3.png)
Решение
Мы решили объединить все состояния оповещений (firing, silenced, inhibited и resolved) в хранилище данных. Учитывая, что мы собираем данные из двух разных источников (webhook и API), каждый из которых имеет разный формат и потенциально представляет разные события, мы соотносим оповещения из обоих источников с помощью поля fingerprint — это уникальный хэш набора меток оповещения, который позволяет нам сопоставлять оповещения в ответах от веб‑хука Alertmanager и API.
![Вебхук Alertmanager и ответ API на одно и то же событие оповещения Alertmanager webhook vs API response](https://habrastorage.org/getpro/habr/upload_files/a8f/dd7/df2/a8fdd7df2c4223eef3d498186d0e4576.png)
API Alertmanager предлагает дополнительные поля по сравнению с webhook (выделены пастельно‑красным цветом справа), такие как идентификаторы silencedBy
и inhibitedBy
, которые помогают идентифицировать оповещения в статусахsilenced
и `inhibited. Мы храним ответы на вызовы вебхуков и API в хранилище данных в виде отдельных строк. При запросе мы сопоставляем оповещения по полю fingerprint.
Мы решили использовать экземпляр vector.dev, чтобы преобразовывать данные по мере необходимости и хранить их в хранилище данных. Vector.dev (приобретен Datadog) — это высокопроизводительный конвейер данных о наблюдениях, имеющий открытый исходный код, и поддерживающий широкий спектр источников для чтения данных и множество приемников для записи данных, а также различные операции по преобразованию данных.
![Здесь мы используем один векторный экземпляр http_server для получения уведомлений от веб-хуков Alertmanager, два источника http_client для запросов к эндпоинтам API оповещений и их заглушения, а также два приемника для записи всех журналов состояния в ClickHouse в таблицы оповещений и заглушения Proposed solution](https://habrastorage.org/getpro/habr/upload_files/72d/5c6/f04/72d5c6f04e5b1e5f7d4f61bf6301323e.png)
Хотя мы используем ClickHouse для хранения этих данных, здесь может быть использована любая другая база данных. ClickHouse была выбрана в качестве хранилища данных потому, что она предоставляет различные возможности манипулирования данными. Она позволяет агрегировать данные при вставке с помощью материализованных представлений, уменьшает количество дубликатов с помощью механизма таблиц replacingMergeTree и поддерживает операторы JOIN.
![Схема таблицы ClickHouse ClickHouse table schema](https://habrastorage.org/getpro/habr/upload_files/9e6/e1b/529/9e6e1b5299687afece2aa5c2736a2674.png)
Если бы мы создали отдельные столбцы для всех меток оповещений, количество столбцов росло бы в геометрической прогрессии с добавлением новых оповещений и уникальных меток. Вместо этого мы решили создать отдельные столбцы для нескольких общих меток, таких как приоритет оповещения, имя инстанса, дашбоард, alert‑ref, alertname и т. д., что поможет нам анализировать данные в целом, а все остальные метки хранить в столбце типа Map(String, String)
. Это было сделано потому, что мы хотели сохранить все метки в хранилище данных с минимальным использованием ресурсов и позволить пользователям запрашивать определенные метки или фильтровать оповещения на основе определенных меток. Например, мы можем выбрать все оповещения Prometheus, используя labelsmap['service'] = 'Prometheus'
.
Дашбоарды
![Outcome](https://habrastorage.org/getpro/habr/upload_files/619/7ae/6a5/6197ae6a5d13dc75878470b57ca5ae50.png)
На основе этих данных мы создали несколько приборных панелей:
Обзор оповещений: Чтобы получить представление обо всех оповещениях, которые получает Alertmanager.
Обзор имен оповещений: Чтобы детализировать конкретное оповещение.
Обзор оповещений по получателям: аналогичен обзору оповещений, но относится к конкретной команде или получателю.
Временная шкала состояния оповещений: Эта приборная панель показывает моментальный снимок объема оповещений.
Обзор оповещений: Чтобы получить представление о том, какие оповещения получает система тикетов.
Обзор заглушенных: Чтобы получить представление о загушенных оповещениях Alertmanager.
Обзор оповещений
![Collapsed alerts overview dashboard](https://habrastorage.org/getpro/habr/upload_files/5af/3f6/296/5af3f6296ebf9c6d1f82978626f544e6.png)
На изображении снимок экрана дашбоарда свернутых оповещений по приемнику. Эта панель включает в себя общую статистику, компоненты, службы и разбивку по именам оповещений. На панели также отображается количество оповещений P1 / P2 за последние один день / семь дней / тридцать дней, топ оповещений за текущий квартал и сравнение одного квартала с другим.
Разбивка элементов по компонентам
![Receiver component breakdown status history](https://habrastorage.org/getpro/habr/upload_files/d31/f97/c9e/d31f97c9e0ef600fa87edb798ea4e7fd.png)
Мы направляем оповещения в команды, а в команде может быть несколько сервисов или компонентов. На этой панели показано количество компонентов оповещений с течением времени для приемника. Например, оповещения отправляются в команду observability, которая владеет несколькими компонентами, такими как логирование, метрики, трассировки и ошибки. Эта панель показывает количество компонентов оповещений с течением времени и дает представление о том, какой компонент и в какое время шумит.
Временная шкала оповещений
![img](https://habrastorage.org/getpro/habr/upload_files/cad/805/b0f/cad805b0f611fb2bc68f8ee27dbef5bd.png)
Мы создали это представление с помощью панели временной шкалы состояний Grafana для приемников. Панель показывает, насколько занят был дежурный и в какой момент. Красный цвет здесь означает, что тревога началась, оранжевый — что тревога активна, а зеленый — что она разрешилась. Здесь отображается время начала, продолжительность активности и разрешение тревоги. Это выделенное оповещение слишком часто меняет состояние от «fired» до «resolver» — это похоже на флапающее оповещение. Флаппингом мы называем ситуации, когда оповещение слишком часто меняет состояние. Это может происходить, когда оповещения настроены неправильно и нуждаются в корректировке, например, в изменении порога оповещения или увеличении значения величины for duration
в правиле оповещения. Поле for duration
в правилах оповещения указывает временной интервал до момента, когда оповещение начнет срабатывать. Другими словами, предупреждение не сработает, пока условие не будет выполнено в течение 'X' минут.
Выводы
В ходе нашего анализа было сделано несколько интересных выводов. Мы обнаружили несколько оповещений, которые срабатывали, но не имели установленной метки уведомления, что означает, что оповещения срабатывали, но не отправлялись и не направлялись ни в одну команду, создавая ненужную нагрузку на Alertmanager. Мы также обнаружили несколько компонентов, генерирующих большое количество оповещений, и, покопавшись в них, выяснили, что они относятся к кластеру, который был выведен из эксплуатации, а оповещения не были удалены. Эти дашбоарды дали нам возможности для улучшения видимости и очистки ненужного.
Подавления Alertmanager
Подавления на стороне Alertmanager позволяют подавить некоторый набор предупреждений, если уже имеется в наличии некий другой набор предупреждений. Мы обнаружили, что иногда подавления Alertmanager не работают. Поскольку не было способа узнать об этом, мы узнали об этом только тогда, когда пользователь сообщил, что получает уведомления о подавленных оповещениях. Представьте себе диаграмму Венна, на которой изображены сработавшие и подавленные оповещения, чтобы понять, что такое несработавшие подавления. В идеале они не должны пересекаться, потому что подавленные оповещения не должны срабатывать. Но если они пересекаются, это означает, что подавленные предупреждения срабатывают, и такое совпадение считается неудачно подавленным уведомлением.
![Диаграмма Венна неудачных подавлений Failed inhibition venn diagram](https://habrastorage.org/getpro/habr/upload_files/31e/333/ac7/31e333ac789515c18e3550f3f7568ff3.png)
После сохранения уведомлений в ClickHouse мы смогли придумать запрос, чтобы найти fingerprint тех alertnames
, в которых подавления оказались неудачными:
SELECT $rollup(timestamp) as t, count() as countFROM( SELECT fingerprint, timestamp FROM alerts WHERE $timeFilter AND status.state = 'firing' GROUP BY fingerprint, timestamp) AS firingANY INNER JOIN( SELECT fingerprint, timestamp FROM alerts WHERE $timeFilter AND status.state = 'suppressed' AND notEmpty(status.inhibitedBy) GROUP BY fingerprint, timestamp) AS suppressed USING (fingerprint)GROUP BY t
Первая панель на изображении ниже - общее количество тревожных сигналов, вторая - количество неудачных запретов.
![img](https://habrastorage.org/getpro/habr/upload_files/87c/640/d48/87c640d48c5bd4ae49c637b1a5ea0ad9.png)
Мы также можем создать разбивку для каждого неудачно подавленного оповещения
![img](https://habrastorage.org/getpro/habr/upload_files/89f/901/888/89f9018880bdcd5444539bb77942a244.png)
Просмотрев fingerprint-ы из базы данных, мы смогли сопоставить подавления оповещений и обнаружили, что неудачной подавленные оповещения имеют «круговое» подавление (или, если хотите, подавление по кругу). Например, оповещение Service_XYZ_down
подавлено оповещением server_OOR
, оповещение server_OOR
подавлено оповещением server_down
, а server_down
подавлено оповещением server_OOR
.
![img](https://habrastorage.org/getpro/habr/upload_files/b91/890/a5a/b91890a5a8c50004e50c8b701a0d49c8.png)
Неудачных подавлений можно избежать, если тщательно настроить подавление уведомлений.
Заглушение
![Alertmanager silences](https://habrastorage.org/getpro/habr/upload_files/2ba/32c/8fb/2ba32c8fb8a6fc1a444ad08f84fa07bc.png)
Alertmanager предоставляет механизм для отключения оповещений на время работы над ними или во время обслуживания. Заглушение (silence) может отключать оповещения на определенное время и может быть настроено при помощи матчеров, которые могут срабатывать по точному совпадению, по regex, по имени оповещения или по любой другой метке. Матчер заглушения не обязательно должен давайть на выходе имя оповещения. Проведя анализ оповещений, мы смогли сопоставить идентификаторы оповещений и заглушений, выполнив JOIN‑запрос к таблицам оповещений и заглушений. Мы также обнаружили множество «устаревших» молчаний, когда молчание было создано на весьма длительный период времени и уже не является актуальным.
Анализ оповещений «Сделай сам»
В этом каталоге содержится базовое демо для реализации наблюдаемости алертов. Выполнение docker-compose up
запустит несколько контейнеров, включая Prometheus, Alertmanager, Vector, ClickHouse и Grafana. Контейнер vector.dev через API будет получать оповещения Alertmanager и, после их преобразования, запишет данные в ClickHouse. Дашбоард в Grafana продемонстрирует обзор Alerts и Silences.
Убедитесь, что у вас установлен docker, и запустите docker compose up
.
Зайдите на адрес http://localhost:3000/dashboards, чтобы ознакомиться с готовыми демонстрационными дашбоардами.
Заключение
Как часть команды Observability, мы управляем Alertmanager, которая является многопользовательской системой. Для нас очень важно иметь возможность обнаруживать и устранять неправильное использование системы, обеспечивая надлежащее оповещение. Использование инструментов анализа оповещений значительно улучшило работу и дежурного персонала, и нашей команды, обеспечив быстрый доступ к системе оповещений. Возможность наблюдения за оповещениями облегчила поиск неисправностей, например, почему не сработало оповещение, почему сработало подавленное оповещение, или какое оповещение заглушило/подавило другое оповещение, что позволяет получить ценные сведения для улучшения управления оповещениями.
Кроме того, дашбоарды оповещений способствуют быстрому просмотру и корректировке, оптимизируя работу. Команды используют эти дашбоарды в еженедельных обзорах оповещений, чтобы предоставить видимые доказательства того, как прошла дежурная смена, определить, какие оповещения срабатывают чаще всего, становясь кандидатами на удаление или объединение с другими, тем самым предотвращая бестолковое использование системы и повышая общий уровень управления оповещениями. Кроме того, мы можем определить службы, которые могут потребовать особого внимания. Рост «наблюдаемости» оповещений также позволил некоторым командам принять обоснованные решения об изменении графика дежурств, например, перейти на более длительные, но менее частые смены или объединить дежурства и незапланированные рабочие смены.
В заключение следует отметить, что возможность наблюдения за оповещениями играет решающую роль в предотвращении выгорания, минимизируя прерывания и повышая эффективность дежурств. Предоставление возможности наблюдения за оповещениями в качестве услуги выгодно всем командам, поскольку избавляет от необходимости разрабатывать индивидуальные приборные панели и способствует формированию культуры проактивного мониторинга.