Введение
Ни для кого не секрет, что на текущий момент регуляторы занимаются активным внедрением отечественных операционных систем на базе Linux/Unix в инфраструктуры государственных компаний. Это создает головную боль для рядовых пользователей, привыкших к интуитивно понятному интерфейсу Windows, работающих с соответствующими текстовыми редакторами и привычными за годы программами, а также для сетевых инженеров, годами работающих с Windows инфраструктурой. Перед ними стоят задачи миграции сервисов на другую ОС и, часто, обучение пользователей работе в новой среде.
Как правило, рано или поздно система приходит к равновесному состоянию: часть пользователей работает на рабочих станциях Windows, специалисты — на Unix-подобных операционных системах. Наша инфраструктура становится гетерогенной, и для её устойчивой работы важно обеспечить мониторинг.
В этой статье мы рассмотрим достоинства и недостатки популярных систем мониторинга, а также развернем их в гетерогенной среде Windows-Linux.
Мой телеграмм канал - сообщество, где делятся опытом
Немного теории
Что дает мониторинг?
1. Вовремя обнаружить проблемы
2. Оценить производительность серверов и хостов и не дать им "упасть"
3. Обнаружить аномальную активность и среагировать на попытки вторжения
4. Анализировать тренды и своевременно планировать оптимизацию хостов и сети
5. Подготовить отчеты и аналитику для руководства, чтобы аргументированно доказать необходимость в денежных инвестициях
Как и всегда выбор средства зависит от задач. Сравним систему Zabbix с Prometheus (для визуализации метрик будем использовать Graphana ).
Zabbix
Преимущества:
1. Полное решение из одного источника: Zabbix является комплексным решением, которое предлагает мониторинг, оповещения и построение отчетов в одной системе.
2. Готовность к использованию из коробки: Имеет множество предустановленных шаблонов и интеграций, что облегчает его настройку и развертывание.
3. Сбор данных в реальном времени: Поддерживает длинные задержки между запросами и может отслеживать данные в реальном времени.
4. Поддержка различных типов данных: Может работать с агентами для различных платформ, поддерживать SNMP, IPMI, JMX, и др.
5. Разветвлённая система оповещений: Поддержка различных каналов уведомлений и гибких условий срабатывания триггеров.
Недостатки:
1. Сложность настройки: Несмотря на наличие шаблонов, интеграции и адаптация для специфических нужд могут требовать значительных усилий.
2. Хранение данных: Использует реляционные БД для хранения данных, что в больших масштабах может требовать серьёзных ресурсов.
3. Масштабируемость: На больших объемах данных может возникнуть проблема масштабируемости и производительности.
Prometheus + Grafana
Преимущества:
1. Модульность и гибкость: Prometheus отвечает за сбор, хранение и обработку метрик, тогда как Grafana используется для их визуализации, обеспечивая гибкость в выборе инструментов.
2. Хорошая масштабируемость: Prometheus разработан для сбора метрик на больших и динамических системах, обеспечивая высокую производительность и масштабируемость.
3. Мощный язык запросов: PromQL позволяет выполнять сложные аналитические задачи и получать необходимую информацию из собранных метрик.
4. Интеграция с облачными сервисами: Поддержка для облаков и контейнерных сред, таких как Kubernetes.
5. Сообщество и экосистема: Большая экосистема и сильное сообщество разработчиков и пользователей.
Недостатки:
1. Кратковременное хранение данных: Преимущественно ориентирован на кратковременное хранение данных, хотя интеграция с внешними хранилищами позволяет решить эту проблему.
2. Отсутствие интегрированной системы оповещений: Хотя Prometheus включает механизм alertmanager, он меньше интегрирован по сравнению с Zabbix.
3. Сложность настройки и эксплуатации: Нужно настраивать и администрировать два или больше отдельных компонента (Prometheus и Grafana) плюс Alertmanager.
Практика
Последовательно развернем системы в соответствии с со схемами
Zabbix
Установить Zabbix сервер очень просто. На официальном сайте есть конфигуратор со всеми необходимыми командами с помощью которых можно подготовить Linux хост, подробно рассматривать этот вопрос не будем.
Конфигурация сервера
Если мы хотим автоматизировать процесс подключения агентов к серверу, группировать их по типу операционной системы и привязывать к конкретным шаблонам, то следует настроить авторегистрацию. Для этого проходим в:
Оповещение - действие - действие авторегистрации
Создать - имя - autoreg_linux
Условия - Метаданные узлов сети - содержит - Linux
Операции:
Добавить узел сети
Активировать узел сети
Отправить сообщение пользователям: Admin через все способы оповещения
Добавить в группы узлов сети: Station_linux
Присоединить к шаблонам: Linux by Zabbix agent
Создать - имя - autoreg_windows
Условия - Метаданные узлов сети - содержит - Windows
Операции:
Добавить узел сети
Активировать узел сети
Отправить сообщение пользователям: Admin через все способы оповещения
Добавить в группы узлов сети: Station_Windows
Присоединить к шаблонам: Windows by Zabbix agent
Не забываем заранее создать соответствующие группы.
Подготовка хостов - Linux
Установка в ручном режиме так же проста как сервера.
Давайте лучше рассмотрим, как произвести установку централизованно в автоматическом режиме. Я использую Puppet и Ansible для этих целей. Первый для поддержки долговременной инфраструктуры, где хосты не являются рабочими машинами и периодически могут быть недоступны, второй преимущественно для виртуальных хостов и серверов.
Почему так? Puppet использует агентов на хостах, периодически сверяющих конфигурацию системы с конфигурацией на сервере. Сверка происходит регулярно и рано или поздно все машины будут приведены к единообразию. Для Ansible же важно чтобы хост в текущий момент времени был включен и готов принять автономный пакет python который ему шлет сервер. Агентов у Ansibe нет, что является его преимуществом и одновременно недостатком в определенных случаях.
В нашем случаем используем Ansible и для работы мы должны создать 3 каталога со своей структурой:
инвентарь (как создавать подробно описал в статье)
роль
плейбук
Из особенностей укажем в глобальных переменных адрес сервера Zabbix. Заранее извиняюсь, если непривычно, но для компактности и без того длинной статьи укажу все команды и комментарии в кодовой строке в таком вот специфичном формате:
touch inventory/group_vars/all.yml
#>
---
zabbix_server_addr: 192.168.2.101
#<>
Роль
mkdir roles
# создание каталогов роли
ansible-galaxy role init roles/zabbix_agent
# редактируем:
roles/zabbix_agent/tasks/main.yml
#>
---
- name: Add repo Zabbix
ansible.builtin.template:
src: zabbix.list.j2
dest: /etc/apt/sources.list.d/zabbix.list
owner: root
group: root
mode: '0644'
- name: Add Zabbix GPG Key
ansible.builtin.copy:
src: zabbix-official-repo.gpg
dest: /etc/apt/trusted.gpg.d/
owner: root
group: root
mode: '0644'
notify: Update_apt_cache
- name: Install Zabbix
ansible.builtin.apt:
name: zabbix-agent
state: present
- name: Config Zabbix-agent
ansible.builtin.template:
src: zabbix_agentd.conf.j2
dest: /etc/zabbix/zabbix_agentd.conf
owner: zabbix
group: zabbix
mode: '0755'
vars:
current_hostname: "{{ ansible_facts.hostname }}"
- name: Ensure log directory exists
ansible.builtin.file:
path: /var/log/zabbix
state: directory
owner: zabbix
group: zabbix
mode: '0755'
- name: Start, autostart Zabbix-agent
ansible.builtin.service:
name: zabbix-agent
state: restarted
enabled: true
# --- тест службы
- name: Pause
ansible.builtin.pause:
seconds: 3
tags: test
- name: Test service status
ansible.builtin.systemd:
name: zabbix-agent
state: started
register: service_status
tags: test
- name: Message service fail
ansible.builtin.fail:
msg: "Служба не запущена!"
when: service_status.status.ActiveState != 'active'
- name: Message service success
ansible.builtin.debug:
msg: "Служба запущена успешно!"
when: service_status.status.ActiveState == 'active'
#<>
touch roles/zabbix_agent/templates/zabbix.list.j2
#>
# Generate for Ansible
{% for repo in zabbix_agent__repo %}
{{ repo }}
{% endfor %}
#<>
roles/zabbix_agent/defaults/main.yml
#>
---
zabbix_agent__repo:
- deb https://repo.zabbix.com/zabbix/6.4/debian bookworm main
- deb-src https://repo.zabbix.com/zabbix/6.4/debian bookworm main
#<>
# переносим ключ репозитория в роль
cp /etc/apt/trusted.gpg.d/zabbix-official-repo.gpg roles/zabbix_agent/files/
# обработчик
roles/zabbix_agent/handlers/main.yml
#>
---
# обновление кеша пакетного менеджера
- name: Update_apt_cache
ansible.builtin.apt:
update_cache: true
#<>
# шаблон конфига zabbix agent
touch roles/zabbix_agent/templates/zabbix_agentd.conf.j2
#>
# Generate for Ansible
PidFile=/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=0
Server={{ zabbix_server_addr }}
ServerActive={{ zabbix_server_addr }}
Hostname={{ current_hostname }}
# Include=/etc/zabbix/zabbix_agentd.d/*.conf
HostMetadataItem=system.uname
#<>
Что делает роль:
Подключает репозитории через шаблон и добавляет соответствующий ключ, который нужно загрузить заранее (он появится у вас при установке zabbix сервера)
Устанавливает агента и конфигурирует также через шаблон jinja (в конфигурации агента строка HostMetadataItem=system.uname позволяет службе авторегистрации сервера понять с какой операционной системой ему работать)
Проверяет что служба агента работает без ошибок.
Не забываем открыть порт 10050 на хосте и 10051 на сервере.
Плейбук
mkdir playbooks
touch playbooks/zabbix.yml
playbooks/zabbix.yml
#>
- name: Zabbix
hosts: station
roles:
- zabbix_agent
#<>
После запуска плейбука указанные хосты появятся на нашем сервере подключатся к необходимым шаблонам.
Подготовка хостов - Windows
Качаем пакет msi с официального сайта, проверяем чтобы версия установщика совпадала с версией сервера. Распространять пакет удобнее всего через групповые политики домена Active Directory, подробно описывать не буду, так как это момент простой и материалов на эту тему много. Скажу лишь, что перед распространением наш пакет msi необходимо модифицировать с применением редактора Orca. Можно править и конфигурационной файл, но лично мне такой способ нравится больше.
Для этого в таблицу Property вводим строки со значениями:
SERVER = 192.168.2.101
SERVERACTIVE = 192.168.2.101
LISTENPORT = 30001
Не забываем что для авторегистрации на сервере нам нужно передать метаданные в конфигурационный файл агента, для этого готовим скрипт и организуем его запуск чрез групповые политики
Обновляем политики, убедимся что нужные порты открыты и идем на сервер
Prometheus + Grafana
Тут все немного сложнее, поскольку Prometheus предназначен больше для легковесного запуска в контейнерах, для запуска в качестве сервера мониторинга нам нужно создать службы для работы соответствующих исполняемых файлов, подключить необходимые компоненты для оповещений. Руками делать все это крайне долго, развернем сервер через Ansible с помощью роли
mkdir roles
# создание каталогов роли
ansible-galaxy role init roles/prometheus_server
# редактируем:
roles/prometheus_server/tasks/main.yml
#>
---
# Promrtheus
- name: Create Prometheus directory
ansible.builtin.file:
path: /etc/prometheus
state: directory
mode: '0755'
- name: Download Prometheus
ansible.builtin.get_url:
url: "{{ prometheus_server__url }}"
dest: "{{ prometheus_server__archive_path }}"
mode: '0644'
force: no
- name: Extract Prometheus
ansible.builtin.unarchive:
src: "{{ prometheus_server__archive_path }}"
dest: /tmp/
remote_src: true
- name: Move Prometheus binaries
ansible.builtin.copy:
src: "{{ prometheus_server__extract_path }}/{{ item }}"
dest: /usr/local/bin/
mode: '0755'
remote_src: true
with_items:
- prometheus
- promtool
- name: Move Prometheus configs
ansible.builtin.copy:
src: "{{ prometheus_server__extract_path }}/{{ item }}"
dest: /etc/prometheus/
remote_src: true
mode: '0644'
with_items:
- consoles
- console_libraries
- name: Create Prometheus user
ansible.builtin.user:
name: prometheus
shell: /bin/false
- name: Change ownership of Prometheus directories
ansible.builtin.file:
path: /etc/prometheus
owner: prometheus
group: prometheus
recurse: true
- name: Create Prometheus directory
ansible.builtin.file:
path: /var/lib/prometheus/
state: directory
mode: '0755'
owner: prometheus
group: prometheus
# Alertmanager
- name: Create configuration directory Alertmanager
ansible.builtin.file:
path: /etc/alertmanager
state: directory
mode: '0755'
- name: Download Alertmanager
ansible.builtin.get_url:
url: "{{ prometheus_server__alertmanager_url }}"
dest: "{{ prometheus_server__alertmanager_archive_path }}"
mode: '0644'
- name: Extract Alertmanager
ansible.builtin.unarchive:
src: "{{ prometheus_server__alertmanager_archive_path }}"
dest: /tmp/
remote_src: true
- name: Move Alertmanager binaries
ansible.builtin.copy:
src: "{{ prometheus_server__alertmanager_extract_path }}/{{ item }}"
dest: /usr/local/bin/
mode: '0755'
remote_src: true
with_items:
- alertmanager
- amtool
- name: Create Alertmanager user
ansible.builtin.user:
name: alertmanager
shell: /bin/false
- name: Change ownership of Alertmanager directories
ansible.builtin.file:
path: /etc/alertmanager
owner: alertmanager
group: alertmanager
recurse: true
- name: Create Alertmanager directory
ansible.builtin.file:
path: /var/lib/alertmanager/
state: directory
mode: '0755'
owner: alertmanager
group: alertmanager
# config files
- name: Deploy config alert_rules
ansible.builtin.copy:
src: "files/{{ item }}"
dest: /etc/prometheus/
owner: prometheus
group: prometheus
mode: '0644'
with_items:
- alert_rules.yml
- name: Deploy config prometheus
ansible.builtin.template:
src: "prometheus.yml.j2"
dest: /etc/prometheus/prometheus.yml
owner: prometheus
group: prometheus
mode: '0644'
- name: Deploy config alertmanager
ansible.builtin.template:
src: "alertmanager.yml.j2"
dest: /etc/alertmanager/alertmanager.yml
owner: alertmanager
group: alertmanager
mode: '0644'
# service
- name: Template Prometheus service
ansible.builtin.template:
src: templates/prometheus.service.j2
dest: /etc/systemd/system/prometheus.service
mode: '0644'
- name: Template Alertmanager service
ansible.builtin.template:
src: templates/alertmanager.service.j2
dest: /etc/systemd/system/alertmanager.service
mode: '0644'
- name: Reload systemd
ansible.builtin.systemd:
daemon_reload: true
- name: Enable and restart Prometheus service
ansible.builtin.systemd:
name: prometheus
enabled: true
state: restarted
- name: Enable and restart Alertmanager service
ansible.builtin.systemd:
name: alertmanager
enabled: true
state: restarted
# --- tests
- name: Pause
ansible.builtin.pause:
seconds: 3
tags: test
- name: Test service status prometheus
ansible.builtin.systemd:
name: prometheus
state: started
register: service_status_prometheus
tags: test
- name: Test service status alertmanager
ansible.builtin.systemd:
name: alertmanager
state: started
register: service_status_alertmanager
tags: test
- name: Message service fail prometheus
ansible.builtin.fail:
msg: "Служба не запущена! - prometheus"
when: service_status_prometheus.status.ActiveState != 'active'
- name: Message service fail alertmanager
ansible.builtin.fail:
msg: "Служба не запущена! - alertmanager"
when: service_status_alertmanager.status.ActiveState != 'active'
- name: Message service success prometheus
ansible.builtin.debug:
msg: "Служба запущена успешно! - prometheus"
when: service_status_prometheus.status.ActiveState == 'active'
- name: Message service success alertmanager
ansible.builtin.debug:
msg: "Служба запущена успешно! - alertmanager"
when: service_status_prometheus.status.ActiveState == 'active'
#<>
# создаем шаблоны служб и конфигурационных файлов prometheus и alertmanager
roles/prometheus_server/templates/alertmanager.service.j2
#>
[Unit]
Description=AlertManager Service
After=network.target
[Service]
User=alertmanager
ExecStart=/usr/local/bin/alertmanager \
--config.file=/etc/alertmanager/alertmanager.yml \
--storage.path=/var/lib/alertmanager
Restart=always
[Install]
WantedBy=multi-user.target
#<>
roles/prometheus_server/templates/alertmanager.yml.j2
#>
route:
group_by: ['alertname', 'instance', 'severity']
group_wait: 20s
group_interval: 20s
repeat_interval: 12h
receiver: 'telepush'
receivers:
- name: 'telepush'
webhook_configs:
- url: '{{ prometheus_server__url_telepush }}'
http_config: {}
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
#<>
roles/prometheus_server/templates/prometheus.service.j2
#>
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target
[Service]
User=prometheus
ExecStart=/usr/local/bin/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/var/lib/prometheus/
[Install]
WantedBy=multi-user.target
#<>
roles/prometheus_server/templates/prometheus.yml.j2
#>
global:
scrape_interval: 20s
evaluation_interval: 10s
rule_files:
- alert_rules.yml
alerting:
alertmanagers:
- static_configs:
- targets:
- localhost:9093
# server
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# --- lup
- job_name: 'linux'
static_configs:
- targets: ['192.168.2.101:9100']
- targets: ['192.168.2.103:9100']
# windows
- job_name: 'windows'
static_configs:
- targets: ['192.168.2.100:9182']
- targets: ['192.168.2.102:9182']
#<>
# внутренние переменные роли для создания ссылок для скачивания и директорий размещени файлов
roles/prometheus_server/vars/main.yml
#>
---
prometheus_server__url: "{{ prometheus_server__repo }}/v{{ prometheus_server__version }}/prometheus-{{ prometheus_server__version }}.linux-amd64.tar.gz"
prometheus_server__repo: "https://github.com/prometheus/prometheus/releases/download"
prometheus_server__archive_path: "/tmp/prometheus-{{ prometheus_server__version }}.linux-amd64.tar.gz"
prometheus_server__extract_path: "/tmp/prometheus-{{ prometheus_server__version }}.linux-amd64"
prometheus_server__alertmanager_url: "https://github.com/prometheus/alertmanager/releases/download/{{ prometheus_server__alertmanager_filename }}.tar.gz"
prometheus_server__alertmanager_filename: "v{{ prometheus_server__alertmanager_version }}/alertmanager-{{ prometheus_server__alertmanager_version }}.linux-amd64"
prometheus_server__alertmanager_archive_path: "/tmp/alertmanager-{{ prometheus_server__alertmanager_version }}.linux-amd64.tar.gz"
prometheus_server__alertmanager_extract_path: "/tmp/alertmanager-{{ prometheus_server__alertmanager_version }}.linux-amd64"
#<>
# обработчик для обновления кеша пакетного менеджера
roles/prometheus_server/handlers/main.yml
#>
---
- name: Update_apt_cache
ansible.builtin.apt:
update_cache: true
#<>
# конфиг с правилами алертменеджера разместил в директрии files из за ошибок при работе с шаблонами (нужно экранировать определенные символы, решил не мучать себя этим, тем более переменных не передаю)
roles/prometheus_server/files/alert_rules.yml
#>
groups:
- name: Critical alerts
rules:
- alert: InstanceDown
expr: up == 0
for: 5m
labels:
severity: critical
annotations:
description: '{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minute.'
summary: Instance {{ $labels.instance }} down
#<>
# ну и в дефолте разместил переменные которые можно переопределить при запуске плейбуков
roles/prometheus_server/defaults/main.yml
#>
---
prometheus_server__version: "2.54.0"
prometheus_server__alertmanager_version: "0.27.0"
#<>
В моем случае оповещение работает через телеграмм, поэтому добавляем в инвентарь файл sinventory/secrets.yml с переменной "prometheus_server__url_telepush" c url для связи с телеграмм ботом telepush. Не забываем шифровать данный файл с помощью Ansible Vailt. Как это делать, можно подсмотреть тут.
Оповещения о работе хостов в моем случае выглядят так.
Настройка станций Linux
Для настройки станций нужна роль, создающая службы для работы исполняемых файлов и устанавливающая Node Exporter
mkdir roles
# создание каталогов роли
ansible-galaxy role init roles/prometheus_nodeexporter
# редактируем:
roles/prometheus_nodeexporter/tasks/main.yml
#>
- name: Skip
when: ansible_os_family != 'Debian'
block:
- name: Message
ansible.builtin.debug:
msg: "Skipping tasks ."
- name: Install Node Exporter
when: ansible_os_family == 'Debian'
block:
- name: Download Node Exporter
ansible.builtin.get_url:
url: "{{ prometheus_nodeexporter_url }}"
dest: "/tmp/node_exporter.tar.gz"
mode: '0644'
- name: Extract Node Exporter
ansible.builtin.unarchive:
src: "/tmp/node_exporter.tar.gz"
dest: "/usr/local/bin"
remote_src: true
- name: Move Node Exporter binaries
ansible.builtin.copy:
src: /usr/local/bin/node_exporter-{{ prometheus_nodeexporter__exporter_version }}.linux-amd64/node_exporter
dest: /usr/local/bin/node_exporter
owner: root
group: root
mode: '0755'
remote_src: true
- name: Template service
ansible.builtin.template:
src: node_exporter.service.j2
dest: /etc/systemd/system/node_exporter.service
mode: '0644'
- name: Reload systemd
ansible.builtin.systemd:
daemon_reload: true
- name: Enable and start Node Exporter service
ansible.builtin.systemd:
name: node_exporter
enabled: true
state: restarted
- name: Clean up
ansible.builtin.file:
path: /tmp/node_exporter.tar.gz
state: absent
# --- тест службы
- name: Pause
ansible.builtin.pause:
seconds: 3
tags: test
- name: Test service status
ansible.builtin.systemd:
name: node_exporter
state: started
register: service_status
tags: test
- name: Message service fail
ansible.builtin.fail:
msg: "Служба не запущена!"
when: service_status.status.ActiveState != 'active'
- name: Message service success
ansible.builtin.debug:
msg: "Служба запущена успешно!"
when: service_status.status.ActiveState == 'active'
#<>
roles/prometheus_nodeexporter/templates/node_exporter.service.j2
#>
[Unit]
Description=Node Exporter
[Service]
User=nobody
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=default.target
#<>
roles/prometheus_nodeexporter/vars/main.yml
#>
---
prometheus_nodeexporter_url: "https://github.com/prometheus/node_exporter/releases/latest/download/{{ prometheus_nodeexporter_file }}"
prometheus_nodeexporter_file: "node_exporter-{{ prometheus_nodeexporter__exporter_version }}.linux-amd64.tar.gz"
#<>
roles/prometheus_nodeexporter/files/prometheus.yml
#>
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
#<>
roles/prometheus_nodeexporter/defaults/main.yml
#>
---
prometheus_nodeexporter__exporter_version: "1.8.2"
#<>
Настройка станций Windows
Просто качаем msi последнего Windows Exporter с github и устанавливаем через GPO.
Не забываем открыть порт 9182 на Windows станциях через gpo. Можно для теста сделать это командой PowerShell.
New-NetFirewallRule -DisplayName "Allow Port 9182" -Direction Inbound -Protocol TCP -LocalPort 9182 -Action Allow
Graphana
Ставится просто через пакет с официального сайта.
sudo apt-get install -y apt-transport-https software-properties-common wget
wget https://dl.grafana.com/oss/release/grafana_8.4.2_amd64.deb
sudo dpkg -i grafana_8.4.2_amd64.deb
sudo systemctl enable grafana-server; systemctl start grafana-server
sudo apt --fix-broken install
sudo ufw allow 3000/tcp
Заходим в http://localhost:3000
Логин и пароль по умолчанию в Grafana: **admin : admin**
Для подключения Prometheus ищем в консоли Grafana - Connections - Data sources - Add data source - Prometheus - http://localhost:9090 - Save & Test
Как язык запросов PromQL (Prometheus Query Language) тут писать не буду, но он крайне мощный. Это точно тема отдельной статьи.
Поэтом просто импортируем дашборд из библиотеки:
Dashboard - Import dashbord - Data Source: Prometheus
Для Windows мне понравился - id 20763
Для Linux - id 11074
В нашем случае полезно будет в перспективе модифицировать дашборд из готовых, сделав источником не только Node Exporter, но и Windows Exporter, чтобы наблюдать за всеми станциями разом.
Prometheus и приложения
Отдельно хочу отметить что prometheus имеет множество клиентских библиотек. Например в приложении, разработанном мной на Python для инвентарного учета технических средств
я собираю такие вот метрики:
Выводы
Обе системы мониторинга имеют свои преимущества и недостатки, "идеального" решения как всегда нет.
Zabbix - комплексное решение с мощной системой оповещения и поддержкой множества стандартов из коробки, но менее гибок в работе с метриками.
Prometheus - обладает отличной масштабируемостью, гибок, удобен для контейнерных или облачных технологий, а также приложений, однако сложнее в настройке.