Мониторинг дисковой активности с помощью zabbix

Введение

Как мониторить дисковую активность с помощью zabbix писалось уже не раз, но ни один из вариантов меня полностью не устроил и я взял что-то из одного рецепта, что-то из другого, а что-то реализовал сам. В итоге получилось решение, которое устраивает меня и чтобы не забыть как я это сделал было решено задокументировать :) На все сторонние скрипты и идеи в конце статьи указаны ссылки.

Для мониторинга используется утилита iostat из пакета sysstat. Она в течерии минуты записывает показания в файл(с интервалом в одну секунду), а затем zabix-агент считывает среднеарифмитическое. Для автоподключения дисков к мониторингу был написан свой скрипт, который выполняет поиск блочных устройств, но не просто всех имеющихся, а по определенным, нужным мне критериям, т.е. поиск начинается с просмотра всех примонтированных файловых систем и определения их блочных устройств, далее если это логические устройства, они отсекаются, например вместо sda1 и sda2 будет мониториться только sda и т.д.

Подготовка хоста

Устанавливаем пакет sysstat. С помощью утилиты iostat из этого пакета будем собирать статистику загруженности дисков и сохранять в файл.

# apt-get install sysstat

Далее создаем скрипт, который будет собирать данные в течении 55с и сохранять их в файл /opt/zabbix/iostat_collect.sh:

#!/bin/bash

# Script for iostat monitoring
# Author Epikhin Mikhail
# michael at nomanlab.org

SECONDS=55
TOFILE=/tmp/iostat.log
IOSTAT=/usr/bin/iostat

DISK=$($IOSTAT -x 1 $SECONDS | awk 'BEGIN {check=0;} {if(check==1 && $1=="avg-cpu:"){check=0}if(check==1 && $1!=""){print $0}if($1=="Device:"){check=1}}' | tr '\n' '|')
echo $DISK | sed 's/|/\n/g' > $TOFILE
echo 0

Добавляем этот скрипт в крон, чтобы он выполнялся каждую минуту /etc/crontab:

  • * * * * root /opt/zabbix/iostat_collect.sh

И перезапускаем крон:

# /etc/init.d/crond restart

Теперь каждую минуту в файле /tmp/iostat.log будет появляться ежесекундная статистика по загрузке дисков.

Далее создаем скрипт, который будет парсить этот лог и считать среднеарифмитическое для заданного диска и заданного параметра /opt/zabbix/iostat_parse.sh:

#!/bin/bash
 
# Script for disk monitoring
# Author Epikhin Mikhail
# michael.nomanlab.org
# version 1.1

NUBMER=100500
FROMFILE=/tmp/iostat.log
DISK=$1
METRIC=$2

case "$2" in
"rrqm/s")
        NUMBER=2
;;
"wrqm/s")
        NUMBER=3
;;
"r/s")
        NUMBER=4
;;
"w/s")
        NUMBER=5
;;
"rsec/s")
        NUMBER=6
;;
"wsec/s")
        NUMBER=7
;;
"avgrq-sz")
        NUMBER=8
;;
"avgqu-sz")
        NUMBER=9
;;
"await")
        NUMBER=10
;;
"svctm")
        NUMBER=11
;;
"util")
        NUMBER=12
;;
esac
  
cat $FROMFILE | grep $DISK | tail -n +2 | tr -s ' ' | cut -f$NUMBER -d' ' | awk 'BEGIN {sum=0.0;count=0;} {sum=sum+$1;count=count+1;} END {printf("%.2f\n", sum/count);}'

#iostat -x | grep $1 | tr -s ' ' | cut -f$NUMBER -d' '

И еще один скрипт, которые будет выполнять поиск использующихся устройств /opt/zabbix/devs_discovery.py:

#!/usr/bin/env python

import os
import re

devs = []
mountsFD = open("/proc/mounts", "ro")
mounts = mountsFD.readlines()
jsonData = '{\n"data":[\n\n'
mountPoint = ''
md = re.compile('^md[0-9]+$')

for line in mounts:
    if line.startswith("/dev"):
        lineParts = line.split(" ")
        mountPoint = lineParts[1]

        if "/dev/mapper/" in lineParts[0]:
            dev = os.readlink(lineParts[0]).split("../")[1]

        else:
            dev = lineParts[0].split("/dev/")[1]

            # if not MD-drive
            if not md.match(dev):
                # removing numbers from string
                dev = ''.join([i for i in dev if not i.isdigit()])
                mountPoint = ""

        if dev not in devs:
            if jsonData != '{\n"data":[\n\n':
                jsonData += ',\n'
            jsonData += """{"{#DEV}": "%s", "{#MOUNTPOINT}": "%s"}""" % (dev, mountPoint)
        mountPoint = ""

        devs.append(dev)

mountsFD.close()

jsonData += "\n\n]\n}"

print(jsonData)

Подготовка системы закончена.

Настройка zabbix-агента

В конфиге агента ничего не обычного, главное прописать свои параметры, один для поиска устройств(с помощью скрипта devs_discovery.py), второй для получения показаний по нужной метрике(с помощью скрипта iostat_parse.sh):

UserParameter=custom.disks.discovery_python,/opt/zabbix/devs_discovery.py
UserParameter=custom.disks.iostat[*],/opt/zabbix/iostat_parse.sh $1 $2

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

Теперь перезапускаем агента и тестируем:

# zabbix_agentd -t custom.disks.discovery_python
custom.disks.discovery_python[/opt/zabbix/devs_discovery.py] [t|{
"data":[

{"{#DEV}": "dm-0", "{#MOUNTPOINT}": "/"},
{"{#DEV}": "sda", "{#MOUNTPOINT}": ""},
{"{#DEV}": "dm-2", "{#MOUNTPOINT}": "/home"},
{"{#DEV}": "sdb", "{#MOUNTPOINT}": ""}

]
}]

# zabbix_agentd -t custom.disks.iostat[sdb,util]
custom.disks.iostat[/opt/zabbix/iostat_parse.sh sdb util] [t|0.00]

Если все в порядке, настройка на этом завершена.

Настройка zabbix-сервера

Все настройки на стороне сервера проводятся через веб-интерфейс. Вначале создаем шаблон(Configuration → Templates → Create template), при добавлении которого хосту, на этом хосте будет производиться мониторинг дисковой активности. Ниже представлен скриншот с параметрами, задаем имя шаблона и добавляем его в группу templates.

Далее создаем приложение iostat (Configuration → Templates → Template IOstat Linux → Applications):

Теперь создадим регулярное выражение для фильтрации малоинтересных разделов, таких как /boot, /boot/efi и т.д. Назовем его Linux disk filter(Administration → General → Regulat expressions → New regular expression):

Zabbix поддерживает только posix регулярные выражения, при этом веб-интерфейс поддерживает как posix, так и perl регулярные выражения, что может привести к путанице. Например при составлении рег. выражения оно проходит тестирование в веб-интерфейсе, но по факту не работает, в этом случае надо проверить, соответствует ли оно стандарту posix.

Следующий шаг - создание discovery rule, т.е. правила, которое будет автоматически определять устройства и создавать для них указанные элементы(Configuration → Templates → Template IOstat Linux → Discovery):

Здесь важными параметры:

  • Key - наш собственный ключ, который указали в конфиге агента
  • Filter - параметры фильтрации объектов, в данном случае в качестве параметра по которому фильтруем - точка монтирования, если она известена, то она отдается агентом с именем параметра MOUNTPOINT, ну и соответственно указывается ранее созданное рег. выражение, которым фильтровать этот параметр.

Теперь создаем прототипы источников данных, т.е. на каждое устройство будет создан такой прототип и будет выполнятся коллекционирование данных, ниже приведен пример для метрики await(Configuration → Templates → Template IOstat Linux → Item prototypes → Create item prototype):

  • Key - тут опять же указывается ранее созданный пользовательский параметр и ему передаются два аргумента: имя блочного устройства(DEV)и имя интересующей нас метрики(await)

Параметры rsec/s и wsec/s возвращаются в кбайт, поэтому в прототипе для них нужно задать custom multiplier равный 1024

Таким образом создается нужное кол-во прототипов данных для интересующих метрик. Поддерживаются следующие метрики: rrqm/s, wrqm/s, r/s, w/s, rsec/s, wsec/s, avgrq-sz, avgqu-sz, await, svctm, util. Что они означают можно поглядеть в мануале по iostat. У меня получились следующие прототипы данных:

И в заключении создаются прототипы графиков. В примере ниже создается график, который отображается скорочть чтения/записи устройства(Configuration → Templates → Template IOstat Linux → Graph prototypes → Create graph prototype):

В итоге у меня получилось четыре прототипа графиков:

Заключение

Полученный результат можно увидеть на скриншотах ниже.

Использованная литература

zabbix_iostat.txt · Последние изменения: 2017/01/17 18:01 — metallic
 
Recent changes RSS feed