Grafana OnCall - это инструмент, который поможет организовать надежное оповещение при инцидентах для вашей команды, поддерживающее интеграцию со Slack и Telegram.

Более подробно о данном продукту можно узнать из статьи или из видео. Целью же данной статьи является выполнение небольшой лабораторки в ходе которой вы ближе познакомитесь с продуктом и пройдете основные этапы работ с ним.

Цель лабораторки, как и всё в этом мире, крайне проста - запустить контейнер nginx и если он отключен прислать оповещение в Slack.
Цепочка взаимодействий будет следующая: используя Prometheus будем считывать метрики Nginx и передавать их в Grafana. Grafana будет отслеживать состояние метрик и реагировать на них соответствующем образом (оповещение в Slack).

Grafana - это сервис по управлению метриками и создания алертов.
Grafana OnCall - плагин позволяющий настраивать оповещение об алертах более детально.

Разобьем нашу задачу на шаги:

  • Запустим Grafana/OnCall в docker compose;

  • Добавим плагин “Grafana/OnCall” в “Grafana/Grafana”;

  • Добавим в docker compose контейнер “nginx” и “prometheus”;

  • Отследим метрики контейнера “nginx” при помощи “prometheus” и передавать их в “Grafana/OnCall”;

  • Настроить сценарий реагирования для инцидента останов сервиса Nginx;

  • Создать бота для Slack и выполнить интеграцию c Grafana/Oncall;

  • Создадим расписания для оповещений.

Grafana/OnCall и docker compose

GitHub. Для данной задачи мы будем использовать среду: hobby.

Выполним команду:

curl -fsSL https://raw.githubusercontent.com/grafana/oncall/dev/docker-compose.yml -o docker-compose.yml

Выполним команду:

echo "DOMAIN=http://localhost:8080 COMPOSE_PROFILES=with_grafana SECRET_KEY=my_random_secret_must_be_more_than_32_characters_long RABBITMQ_PASSWORD=rabbitmq_secret_pw MYSQL_PASSWORD=mysql_secret_pw" > .env

Выполним команду:

docker-compose up -d

Откроем порт 3000 в браузере: localhost:3000

Логин и пароль - admin. После входа нам предложат изменить пароль, этот шаг можно пропустить нажав кнопку skip.

Плагин “Grafana/OnCall” в “Grafana/Grafana”

Находясь на странице “Grafana” в панели меню в левой части экрана выберите “Configuration” и перейдите в раздел “Plugins”. В поисковой строке наберите “OnCall” и выберите его.

Grafana/Configuration/Plugins
Grafana/Configuration/Plugins

Для инициализации плагина потребуется токен. Для этого выполните команду:

docker-compose run engine python manage.py issue_invite_for_the_frontend --override

Полученный токен необходимо скопировать и вставить в графу “Invite token”, как показано на скрине ниже.

Invite token
Invite token

Нажмите кнопку “Enable” для плагина OnCall, убедитесь, что ввели полученный токен в графу “Invite token” и нажмите “Connect”. После добавления плагин Grafana/OnCall появится в меню быстрого доступа в левой части экрана.

Nginx и Prometheus

Добавим в файл docker-compose.yml код:

web:
  image: nginx:1.23.1
  ports:
    - "8000:80"

Добавим в файл docker-compose.yml код:

prometheus:
  image: prom/prometheus:latest
  volumes:
    - ./prometheus.yml:/etc/prometheus/prometheus.yml
  container_name: prometheus
  hostname: prometheus
  command:
    - --config.file=/etc/prometheus/prometheus.yml
  ports:
    - 9090:9090
restart: unless-stopped networks:
    - default

В директорию c файлом docker-compose.yml добавим новый файл prometheus.yml и добавим в него код:

global:
  scrape_interval: 50s #как часто обновлять таргет
  evaluation_interval: 60s #как часто производить оценку правил
  scrape_timeout: 50s #через сколько времени до истечения срока ожидания запросить обновление

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: [ 'localhost:9090' ]
  - job_name: 'nginx'
    metrics_path: /metrics
    static_configs:
      - targets: [ 'web:8000' ]
  - job_name: 'grafana'
    metrics_path: /metrics
    static_configs:
      - targets: [ 'grafana:3000' ]

Для наглядности мы добавим для Prometheus 3 источника метрик: Prometheus; Nginx и Grafana. Вновь выполним команду :

docker-compose up -d

Отслеживание метрик контейнера Nginx при помощи Prometheus

Откроем порт “prometheus” 9090 в браузере (localhost:9090). В верхнем меню открывшегося окна выберем “Status/Targets”, подождем выполнения проверки метрик. По итогу мы должны получить следующие.

Prometheus 9090
Prometheus 9090

Как видим два сервиса из трех в состоянии “up”. Причина в том, что для сервиса Nginx не включена функция отображения метрик.

Добавим функцию отображения метрик для нашего контейнера Nginx. Для этого нам потребуется изменить файл конфигурации Nginx default.conf.

Создадим в нашей директории файл default.conf и добавим в него следующий код:

server {
  listen 80;
  listen [::]:80;
  server_name localhost;

  #access_log /var/log/nginx/host.access.log main; 7
  location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
  }

location /metrics { # Те самые строки кода,
  stub_status on;   # которых нам не хватало
}

#error_page 404 /404.html;

  error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root /usr/share/nginx/html;
  }

Дополним код для файла docker-compose.yml:

web:
 image: nginx:1.23.1
 volumes:
  - ./default.conf:/etc/nginx/conf.d/default.conf
 ports:
  - "8000:80"

И так мы квлючили оображение метрик для нашего Nginx, однако новая сложность состоит в том, что формат метрик Nginx не подходит для Prometheus. Для решения этой задачи мы будем использовать контейнер nginx/nginx-prometheus-exporter .

Добавим в файл docker-compose.yml новый блог кода:

exporter:
    image: nginx/nginx-prometheus-exporter:0.11
    ports:
      - 9113:9113
    command:
      - -nginx.scrape-uri=http://web:80/metrics

Не забудем обновить файл prometheus.yml:

global:
  scrape_interval: 50s
  evaluation_interval: 60s
  scrape_timeout: 50s
  
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: [ 'localhost:9090' ]
  - job_name: 'nginx'
  metrics_path: /metrics # Примечание. Если не указать metrics_path, то применится стандартный путь /metrics 
  static_configs:
    - targets: [ 'exporter:9113' ] # Заменили источник метрик на exporter
  - job_name: 'grafana'
  metrics_path: /metrics
  static_configs:
    - targets: [ 'grafana:3000' ]

Выполните останов всех контейнеров и перезапустите docker-compose командой:

docker-compose up -d

Повторно выполним вход на порт localhost:9090. Перейдем в раздел “Status/Targets”. На этот раз статусы всех ресурсов должны быть в состоянии “up”.

Status/Targets
Status/Targets

Посмотрим какие метрики Prometheus считывает с сервиса Nginx. Откроем порт 9113 в браузере localhost:9113/metrics. Для нашей конечной задачи нам потребуется отслеживать метрику nginx_up , которая отвечает за состояние сервиса (up/down).

Настроить сценарий реагирования для инцидента Останов сервиса Nginx

Добавим плагин Prometheus в Grafana. Откроем порт 3000 в браузере localhost:3000 и перейдем в раздел “Configurations/Plugins”. Выполним поиск: Prometheus.

Prometheus
Prometheus

Нажмем на кнопку “Create a Prometheus data source” и выполним настройку. Необходимо задать путь до сервиса Prometheus в графе URL, как показано на скрине ниже.

Create a Prometheus data source
Create a Prometheus data source

Остальные настройки оставляем по умолчанию и нажимаем “Save & Test”.

Done
Done

Создадим цепочку эскалации для OnCall (сценарий реагирования на инцидент). Перейдем в раздел “OnCall/Escalations Chains”.

Escalations Chains
Escalations Chains

Наш сценарий будет уведомлять пользователя admin об инциденте, выжидать 1 минут и повторно направлять уведомление.

На данном этапе сценарий не будет подразумеваться применения Slack

My new EChain
My new EChain

Перейдем в раздел “Integrations” и создадим новую интеграцию для оповещений, нажав кнопку “New Integration receiving alerts”. Выберем “Grafana Alerting” нажав кнопку “Quick Connect”.

Grafana Alerting
Grafana Alerting

Далее нажимаем “Open Escalations Settings” и выберем ранее созданный сценарий эскалации.

Open Escalations Settings
Open Escalations Settings

Далее необходимо внести изменения в настройки “Contact points”. Перейдем в раздел “Alerting/Contact points”.

Contact points
Contact points

Перейдем в настройки точки доступа.

Grafana Alerting
Grafana Alerting

В графе URL изменим путь с localhost:8080 на engine:8080. Для проверки точки контакта выполните “Test/Sent test notification” (в правой части окна). Вы должны увидеть сообщение об успешном выполнении теста.
Нажимаем “Save Contact Point” и переходим к настройке “Notification policies”, для этого перейдем в соответсвующий раздел.

Notification policies
Notification policies

Перейдет в настройки “Root policy - default for all alerts” и поменяем “Default contact point” на созданный нами ранее. Сохраним изменения.

Перейдем в раздел “Alert Rules” для завершения настроек.
Нажмем кнопку “New Alert Rules”. Для отслеживание состояния сервисов выберем плагин Prometheus, Metric = nginx_up.

Метрика nginx_up передает значение 1 при работе сервиса и 0 при его отключении. Таким образом нам необходимо получать оповещение, когда значение метрики не равно 1. Для этого настроим модуль “B - expression” следующим образом.

B - expression
B - expression

В графе “Set alert condition” выберем “B - expression”. Выполним проверку настроенного Alert нажав кнопку “Preview alert” при этом вы не должны получить ошибку в появившемся окне.
Заполним информацию для данного правила оповещения.

Add details for your alert
Add details for your alert

Нажмем кнопку “Save and exit”.

Перед проверкой созданного оповещения перейдем в раздел “OnCall/Alert Group”. В таблице будет ранее созданное нами оповещение, которое мы получили при выполнении теста конфигурации “Contact point”.

TestAlert
TestAlert

Проверим работу настроенного оповещения

Произведем останов контейнера Nginx и проверим работу настроенного нами Grafana/OnCall. Откроем в браузере порт 9113 http://localhost:9113/metrics и увидим изменение отслеживаемой нами метрики nginx_up, параметр должен быть равен 0.
Проверим наличия оповещения в “OnCall/Alert Group”.

Nginx_onoff
Nginx_onoff

Оповещение не придет мгновенно: Prometheus обновляет метрики раз в 60s, настроенный нами Alert rules выполняет проверку раз в минут, после проверки и получение значения 0 от метрики nginx_up состояния Alert измениться с “Norm” на “Pending”, ожидая в течении 5 минут восстановления нормального состояния (=1) и только после этого переведет Alert в состояние “Firing”.

Проверим состояние “Alerting/Alert rules”.

Firing Nginx_onoff
Firing Nginx_onoff

Создадим бота для Slack и выполним интеграцию c Grafana/Oncall;

Для интеграции со Slack контейнер с движком Grafana/OnCall (engine) должен использовать протокол https (localtunel).

Установим localtunel выполнив команду npm install -g localtunnel и добавим в наш проект выполнив команду в директори с doker-compose yarn add localtunnel

Запустим контейнер Grafana/OnCall (engine) используя протокол https:

lt --port 8080 -s <URL_ADDRESS> --print-requests
например
lt --port 8080 -s galgameth-fcm-96 --print-requests

Откроем наш URL и завершим установку.

Continue
Continue

Создайте рабочее пространство в Slack или используйте существующее.

Перейдем по ссылке https://api.slack.com/apps и добавим нашего бота, нажав на Create an App. Выберем From an app manifest и определим рабочее пространство для бота.

Создадим yaml манифест.

_metadata: 
  major_version: 1 
  minor_version: 1
display_information: 
  name: <YOUR_BOT_NAME>
features: app_home:
  home_tab_enabled: true 
  messages_tab_enabled: true 
  messages_tab_read_only_enabled: false

  ...
  
  interactivity:
    is_enabled: true
    request_url: <ONCALL_ENGINE_PUBLIC_URL>/slack/interactive_api_endpoint/
  org_deploy_enabled: false
  socket_mode_enabled: false

<YOUR_BOT_NAME> - имя вашего бота, например test_bot_rb .
<ONCALL_ENGINE_PUBLIC_URL> - ранее созданный url адрес для контейнера engine, в нашем случае https://galgameth-fcm-96.loca.lt/ .

Нажимаем Next - Create. Выполним верификацию для нашего бота: test_bot_rb/Features/App manifest. Нажмем Click here to verify и завершим настройку бота.

Click here to verify
Click here to verify

Установим наш бот в рабочее пространство test_bot_rb/Settings/Basic informations

Применить
Применить

Проверим наши настройки

Check
Check

Проведем интеграцию Slack и Grafana/OnCall.

Зайдем на порт localhost:3000 и выполним вход в Grafana. Перейдем в раздел Grafana OnCall/ChatOps и впервую очередь произведем настройку ENV variables.

ENV variables
ENV variables

Нам необходимо внести следующие данные:

  • SLACK_CLIENT_OAUTH_ID = Basic Information -> App Credentials -> Client ID;

  • SLACK_CLIENT_OAUTH_SECRET = Basic Information -> App Credentials -> Client Secret;

  • SLACK_SIGNING_SECRET = Basic Information -> App Credentials -> Signing Secret;

  • SLACK_INSTALL_RETURN_REDIRECT_HOST = << OnCall external URL >>.

App Credentials
App Credentials

Вернемся в раздел ChatOps и нажмем Install Slack integration, далее I’ll check.. и Разрешить. Вы получите сообщение “Не удается получить доступ к сайту”, интеграция выполнена.

Вновь войдите в раздел ChatOps и настройте ваш Slack integration.
Для данного бота был создан канал в Slack “grafana oncall“. Выберем данный канал для оповещений от OnCall.

Настройка интегрированного Slack
Настройка интегрированного Slack

Создадим расписание оповещений

Перейдем в раздел Schedules и нажмем Add schedule for on-call rotation. Для нашего расписания будем использовать “google calendar”.
Укажем название нашего расписания и добавим ical url, для этого перейдем в календарь, выберем интересующий нас календарь и зайдем в его настройки

Settings and sharing
Settings and sharing

и скопируем “Secret address ical format”.

Secret address ical format
Secret address ical format

Внесем данные и завершим создание расписания нажав Create Schedule.

Nginx Schedule
Nginx Schedule

Создадим расписание при котором с 9:00 до 14:00 оповещения будут приходить пользователю “Roman”, а с 14:00 и до 21:00 пользователю “admin”.

Пользователь "admin" создается по умолчанию, доп. пользователь создается в разделе доступном администратору: Server Admin/Users - New user

Перейдем в календарь и выполним настройку расписания. Для каждой временного участка мы указали соответсвующее имя пользователя Grafana. Для пользователя admin дополнительно указали [L1], что позволяет разделить наших пользователей по уровням. Перейдем в раздел Grafana OnCall/Schedules и нажмем Reload для нашего распис

Schedule: Nginx
Schedule: Nginx

На скрине выше представлена информация из календаря, а также пользователь, которому в данный момент будут приходить оповещения (OnCall now).

Обновим ранее созданное оповещение в разделе Grafana OnCall/Integrations выполнив следующие настройки:

  • Направим оповещения в канал Slack: Grafana OnCall;

  • Добавим “Notify user from on-call schedule” и выберем наше расписание.

New settings
New settings

Выполним тестирование нашего оповещения нажав “Send demo alert” (верхний правый угол скрина выше). Проверим получение оповещения в Slack.

Проверим работу оповещения остановив контейнер Nginx

Получаем наше оповещение от алерта: Nginx RUN or NOT
Получаем наше оповещение от алерта: Nginx RUN or NOT

Поздравляю, вы дошли до конца!
Надеюсь данная статья хоть немного помогла Вам с освоением продукта Grafana/OnCall.

Комментарии (9)


  1. skymal4ik
    21.11.2022 02:17
    +1

    Расскажите, чем не подошёл или не устроил AlertManager от Prometheus? Вроде по функционалу то же самое, но с настройкой явно проще, по сути один yaml с правилами и всё.


    1. onegreyonewhite
      21.11.2022 10:58
      -1

      Наверное это для адептов мышкакликательных свидетелей гуя. Они же не умеют в cli и конфиги, им GUI подавай и 100500 кликов мышкой.


      1. RoCman Автор
        21.11.2022 14:48

        Большую часть операций выполненных в мануале можно описать в docker-compose файле. Например используя Provision Grafana.

        Сразу скажу, что я не являюсь амбассадором Grafana и не пытаюсь её кому либо навязать :)


      1. sergeykons
        23.11.2022 08:21

        OnCall умеет в Escalation plans и прочие нужные фичи. Настраивать да все приходится через GUI.
        Но как Oss альтернатива PagerDuty вполне неплохо


    1. RoCman Автор
      21.11.2022 14:42

      У Prometheus AlertManager функционал примерно такой же, как у Grafana Alerting. Отследим метрики, сгруппируем алерты и направим письмо на почту.
      OnCall же позволяет создавать цепочки эскалации, расписание для сотрудников и интегрируется со Slack и Telegram.


      1. skymal4ik
        21.11.2022 15:43

        Спасибо, это интересно, надо будет глянуть ради расширения кругозора.

        Ps начиная с версии v0.24 AlertManager так же умеет telegram нативно.


    1. Wernisag
      23.11.2022 07:41

      Тут скорее аналогично вопросу про мониторинг. Зачем нужна вика, пром, заббикс, [подставь что-то своё], когда есть ещё какая-то система мониторинга.

      Собственно, одна система что-то умеет, другая нет, третья делает это лучше, а четвертая проще. OnCall скорее нужен для дополнения AlertManager, а не вместо него.

      Вот тут чуть подробнее про возможности OnCall


    1. nspickiy
      23.11.2022 08:21

      Grafana OnCall это всё таки аналог не Alert Manager, а PagerDuty, opsGenie и прочее, то есть когда у вас есть команды, дежурства, расписания, эсколации, постмортемы и так далее.


  1. Matvey-Kuk
    21.11.2022 15:57
    +1

    Отличная статья! Спасибо за такое подробное описание всей связки!

    Несколько добавлений: