Мониторинг оборудования на Linux-сервере

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

Подопытным будет комп на PROXMOX, это по сути тот же Debian 11, только ядро немного свежее и подточенное для виртуализаций.

Первым делом определим перечень метрик, которые нам интересны

  • Температурные показатели - нагрев дисков, нагрев процессора, скорость вентиляторов
  • Текущая частота процессора
  • Заполненность оперативной памяти
  • Заполненность жесткого диска
  • Износ диска, метрики smart

Мониторинг датчиков lm-sensors

Самая полезная утилита в Linux, это lm-sensors, она снимает показания с датчиков, может отображать показания температур, напряжения на материнской плате и скорости вентиляторов.

apt install lm-sensors

Дальше нужно продетектить все сенсоры чтобы все нужные модули подгрузились

sensors-detect

На вопросы можно просто enter нажимать, обычно этого достаточно, но можно везде yes вводить

На свежих процессорах Ryzen 5XXX нужно ядро от 5.15 и выше ставить, на 5.13 адекватно мониторинг не работает

Дальше выхлоп команды sensors такой


k10temp-pci-00c3
Adapter: PCI adapter
Tctl:         +36.5°C  

nvme-pci-0100
Adapter: PCI adapter
Composite:    +41.9°C  (low  = -273.1°C, high = +81.8°C)
                       (crit = +84.8°C)
Sensor 1:     +41.9°C  (low  = -273.1°C, high = +65261.8°C)
Sensor 2:     +43.9°C  (low  = -273.1°C, high = +65261.8°C)

amdgpu-pci-0300
Adapter: PCI adapter
vddgfx:      731.00 mV 
vddnb:         1.14 V  
edge:         +36.0°C  
power1:        2.00 mW 

nct6793-isa-0290
Adapter: ISA adapter
in0:                    56.00 mV (min =  +0.00 V, max =  +1.74 V)
in1:                     1.86 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in2:                     3.39 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in3:                     3.39 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in4:                   256.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in5:                   136.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in6:                   720.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in7:                     3.39 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in8:                     3.25 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in9:                     1.84 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in10:                  184.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in11:                  136.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in12:                    1.86 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in13:                    1.73 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in14:                  200.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
fan1:                     0 RPM  (min =    0 RPM)
fan2:                   512 RPM  (min =    0 RPM)
fan3:                     0 RPM  (min =    0 RPM)
fan4:                     0 RPM  (min =    0 RPM)
fan5:                     0 RPM  (min =    0 RPM)
SYSTIN:                +115.0°C  (high =  +0.0°C, hyst =  +0.0°C)  sensor = thermistor
CPUTIN:                 +52.0°C  (high = +80.0°C, hyst = +75.0°C)  sensor = thermistor
AUXTIN0:                +42.0°C  (high =  +0.0°C, hyst =  +0.0°C)  ALARM  sensor = thermistor
AUXTIN1:               +108.0°C    sensor = thermistor
AUXTIN2:               +107.0°C    sensor = thermistor
AUXTIN3:               +105.0°C    sensor = thermistor
SMBUSMASTER 0:          +36.5°C  
PCH_CHIP_CPU_MAX_TEMP:   +0.0°C  
PCH_CHIP_TEMP:           +0.0°C  
PCH_CPU_TEMP:            +0.0°C  
intrusion0:            OK
intrusion1:            ALARM
beep_enable:           disabled

Из всего этого для меня полезно знать несколько не всё, поэтому, выхлоп команды sensors можно отфильтровать утилитой grep, а точнее можно использовать расширенную версию egrep для применения регулярок

sensors | egrep "(Composite|fan2|CPUTIN)"

Получим выхлоп типа такого

root@srv1:~# sensors | egrep "(Composite|fan2|CPUTIN)"
Composite:    +41.9°C  (low  = -273.1°C, high = +81.8°C)
fan2:                   510 RPM  (min =    0 RPM)
CPUTIN:                 +52.0°C  (high = +80.0°C, hyst = +75.0°C)  sensor = thermistor

Дальше можно применить утилиту sed для того, чтобы модифицировать текст, этакая русификация

sensors | egrep "(Composite|fan2|CPUTIN)"| \
sed \
-e "s/Composite/Температура NVME/" \
-e "s/fan2/Скорость вентилятора/" \
-e "s/CPUTIN/Температура CPU/"

То что в скобках и после них для нас не сильно интересно, добавим в sed еще одно преобразование

-e "s/(.*).*//"

Вроде уже прекрасно, но после двоеточий слишком много пробелов, давайте их затрем тоже

-e  "s/:\s*/: /"

Получилось то что нужно

Для удобства парсинга сторонними системами, лучше всего сделать key:val формат, поэтому, я сделаю что-то вроде

Параметр (единица измерения): 0.00

Написать одно преобразование у меня не удалось, регулярки в SED работают не так как я привык

Если бы не sed, то регулярка выглядела так

(.*):[^0-9]*([0-9.]+)\s*(.*)

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

-e "s/\(.*\):[^0-9]*\([0-9.]\+\)\s*\(.*\)/\1(\3): \2/" \
-e "s/\s*)/)/"

Получилось вот такая команда

sensors |\
`#фильтруем строки` \
egrep "(Composite|fan2|CPUTIN)" |
sed \
`#переводим значения` \
-e "s/Composite/Температура NVME/"  \
-e "s/fan2/Скорость вентилятора/"  \
-e "s/CPUTIN/Температура CPU/"  \
`#убираем хлам в скобках и после` \
-e "s/(.*).*//" \
`#убираем пробелы после двоеточий` \
-e  "s/:\s*/: /"  \
`#форматируем выхлоп в key:val` \
-e "s/\(.*\):[^0-9]*\([0-9.]\+\)\s*\(.*\)/\1(\3): \2/" \
`#пробелы перед скобками` \
-e "s/\s*)/)/" 

Мониторинг состояния дисков

На моей практике был только один погибший SSD диск, но он отработал более 6 лет в режиме 24/7, на нем крутились десятки виртуальных машин, которые я регулярно удалял, создавал, пересоздавал, делал снепшоты, в общем он активно отработал и в один момент выключился когда я его гонял в неттопе, вероятно от перегрева, сейчас у меня в сервере чуток больше места и радиатор установлен (смотрите видео на канале).

Единственная наверно программа для мониторинга любых дисков - это smartctl

apt install smartmontools

Чтобы проверить состояние диска достаточно ввести

smartctl -a /dev/nvme0
название устройства отличается на разных конфигурациях

Полезный выхлоп примерно такой

=== START OF SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

SMART/Health Information (NVMe Log 0x02)
Critical Warning:                   0x00
Temperature:                        42 Celsius
Available Spare:                    100%
Available Spare Threshold:          10%
Percentage Used:                    0%
Data Units Read:                    3,343,688 [1.71 TB]
Data Units Written:                 4,315,804 [2.20 TB]
Host Read Commands:                 19,343,569
Host Write Commands:                32,330,671
Controller Busy Time:               43
Power Cycles:                       62
Power On Hours:                     21
Unsafe Shutdowns:                   35
Media and Data Integrity Errors:    0
Error Information Log Entries:      0
Warning  Comp. Temperature Time:    0
Critical Comp. Temperature Time:    0
Temperature Sensor 1:               42 Celsius
Temperature Sensor 2:               44 Celsius

Error Information (NVMe Log 0x01, 16 of 64 entries)
No Errors Logged

Но тут опять же нас будет интересовать несколько параметров, поэтому опять примеим что-то похожее на прошлый скрипт с применением egrep + sed

smartctl -a /dev/nvme0 |\
`#фильтруем строки` \
egrep "(Percentage Used|Data Units Written)" |
sed \
`#переводим значения` \
-e "s/Percentage Used/Износ/"  \
-e "s/Data Units Written/Кол-во записей/"  \
`#убираем пробелы после двоеточий` \
-e  "s/:\s*/: /"  \
`#оставим только в квадратных скобках` \
-e  "s/\(.*\):.*\[\(.*\)\]/\1: \2 /"  \
`#форматируем выхлоп в key:val` \
-e "s/\(.*\):[^0-9]*\([0-9.]\+\)\s*\(.*\)/\1(\3): \2/" \
`#пробелы перед скобками` \
-e "s/\s*)/)/"

Расход оперативной памяти

Команда free -m выдаст количество свободной памяти в процентах

Опять же, можем прогнать через grep и сократить количество строк

Теперь попробуем применить более тяжелую артиллерию - утилиту awk

Вот так можно вывести 3й столбец, т.е. количество используемой

free -m | grep "Mem:" | awk '{print $3}'

А чтобы получить % занятости памяти - можно просто 3й столбец поделить на 2й и домножить на сто, т.е. количество занятой памяти делим на общее количество и умножаем на 100

free -m | grep "Mem:" | awk '{print $3/$2*100}'

далее можно пристыковать текстовые строки для красоты

free -m | grep "Mem:" | awk '{print "RAM Usage(%): "$3/$2*100}'

Заполнение диска

Обычно команда df -h отдает заполнение всех дисков в человекочитаемом виде.

А следующая команда отфильтрует ту позицию, которая примонтирована на корень

df -h | egrep '/$'

используя прошлые знания, мы можем через awk отфильтровать только значение 15%

df -h | egrep '/$' | awk '{print "Заполнение диска: "$5}'

Ну и добавив sed, можно причесать результат к общему формату

df -h | egrep '/$' | awk '{print "Заполнение диска: "$5}' | sed -e "s/\(.*\):[^0-9]*\([0-9.]\+\)\s*\(.*\)/\1(\3): \2/"

Текущая частота процессора

Мониторить текущую частоту всех процессорных ядер можно например такой командой

watch -n0.2 cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq

Частоту самого быстрого ядра в гигагерцах можно выдать примерно так

cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq |sort -r|awk '{print "Частота процессора(Ghz): "$1/1000000}'|head -1

Задержки сети

ping -q -c1 8.8.8.8 | grep avg | sed -e "s/s*\([0-9.]\+\)\/.*/\1/" -e "s/[^=]*=\s*//"|xargs echo "Ping (ms): "$1

А так самое наверно верное, показывает среднее

ping -q -c3 192.168.0.1 | grep avg |awk -v FS="/" '{print "Ping(ms): "$5}'

Результат вот такой

пинг до гугла

Пример скрипта на github

Показать комментарии