Доброго времени суток!

imageКДПВ

Данная статья – небольшой мануал, написанный в несколько художественной форме. В статье много картинок, заботливо упрятаных в спойлеры.

Для кого написана эта статья? Для начинающих сисадминов, еще слабо знакомых с UNIX-системами, Zabbix’ом, но имеющих желание централизованно собирать информацию с принтеров.

Вводная. Имеется:

  • Zabbix 5.0
  • CentOS 8
  • Принтер, который не отдает нужную информацию о расходниках по SNMP (в данном мануале взят в качестве примера Oki C834)
  • Практически отсутствующие знания о Zabbix, UNIX-системах
  • Очень большое желание собирать информацию о расходниках с принтеров централизованно.

Поехали!

Причины и логические обоснования


Лень – двигатель прогресса. В одно прекрасное утро я понял, что мне лень обходить принтеры, установленные в офисе, для того чтобы контролировать состояние расходных материалов – таких, как тонер-картриджи, драм-юниты, ленты и печи. А также собирать время от времени показатели счетчиков напечатанных страниц – на их основе принимается решение о ТО принтера.

«Это ж сколько времени можно экономить, собирая такую информацию централизованно!» — эта мысль не выходила из моей головы. Было принято решение развернуть систему мониторинга. С подсказки более старших товарищей был выбран Zabbix – с расчетом, что помимо принтеров постепенно подключится мониторинг серверов и сетевого оборудования.

В качестве операционной системы был установлен CentOS 8 – ибо я был хоть немного знаком именно с ним. Возможно, кто-то в данный момент уже пишет, что ай-яй-яй, надо изучать UNIX-системы, если уж взялся за сисадминство. Отвечу вам – да, вы абсолютно правы.

Изучение мануалов по мониторингу принтеров обещало крайне простую процедуру – snmpwalk, вычленение нужных параметров, подключение OID к Zabbix’у, профит. Реальность же немного пошатнуло эту прекрасную картину. Не было показателей состояния расходников. Даже отдаленно похожих не было. Вообще.

Статья Получаем в Zabbix статистику с устройств Kyocera натолкнула на поиск проприетарного ПО для мониторинга принтера и перехват общения ПО с принтером. Такое нашлось – Configuration Tool, утилита от Oki для мониторинга состояния принтеров. Скачиваем, запускаем, и…. по SNMP Configuration Tool получает информацию об имени принтера, МАС-адресу, да версии ПО. Информация же о расходниках передается в теле пакетов TCP/IP.

«Что ж, великолепно, приключения начинаются» — подумалось мне. Обдумывание вариантов решения привело к следующей логической цепочки:

  1. На данном этапе я не умею и не знаю как правильно сымитировать тот запрос, что отсылает Configuration Tool на принтер.
  2. Принтер имеет собственную веб-страницу, на которой он размещает информацию о состоянии расходных материалов и количестве отпечатанных страниц
  3. Решение моей проблемы – вытаскивать (парсить) по расписанию информацию с веб-страницы принтера и неким образом передавать эту информацию в Zabbix.

Поиск инструмента по парсингу дал следующие результаты:

  1. Bash
  2. PHP
  3. Python

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

Я выбрал Bash – и вот почему:

  1. Предустановленность на большей части UNIX-систем. Мне не нужно ставить дополнительное ПО.
  2. Простота. Команды логичны, и вполне понятны после небольшого изучения синтаксиса.
  3. Необходимость изучения UNIX-систем. Изучить синтаксис команд явно не будет лишним в данном направлении.

Разбор веб-страницы принтера


Прежде, чем приступать к парсингу – давайте разберем, что из себя представляет веб-страница принтера.

Примечание
Прошу прощения, если выражусь неправильно относительно элементов веб-страницы принтера. Я, все таки, начинающий сисадмин, а не веб-разработчик.

Переходим на веб-страницу принтера и видим следующее

Веб-страница принтера
image

Замечаем, что справа сверху на странице есть показатели состояния тонера. Теперь нам остается понять, как именно на веб странице появляются данные показатели. ПКМ-> Inspect. Нам открывается следующая картина.

Инспекция кода страницы
image
image

Подмечаем, что значения тонера, на самом деле, получаются через страницу /status.htm
Видим, что значение показателей тонера передаются в тегах:

После чего с помощью JavaScript значения округляются до десятков и подставляются в страницу.

Переходим на страницу 192.168.***.***/status.htm – и да, действительно нужные нам значения тонера мы видим на данной странице

status.htm
image

Теперь мы знаем, где хранятся нужные нам значения состояния тонера. Приступим к парсингу.

Парсинг


Примечание: далее будет описание построения скрипта для парсинга страницы с примерами и картинками. Я постараюсь, что бы описание было понятно даже тем, кто очень слабо знаком с Bash. Если же вы имеете желание прочитать уже результат – прошу пролистывать дальше.
Итак, Bash. Рубикон пройден, как сказали две тысячи лет назад на берегу одноименной реки.
Первым делом я предлагаю ознакомиться с синтаксисом языка. Он крайне прост и незамысловат – но это нам поможет при написании скрипта и автоматизации.

Далее обратим внимание на cURL – command line and tool, как заявлено на официальном сайте этого инструмента. cURL поддерживает огромное количество протоколов, из которых нам требуется поддержка HTTP – помним, что именно по этому протоколу идет «общение» с веб-страницей принтера.
Напишем первый запрос:

$ curl 192.168.***.***/status.htm

Вывод терминала
image

В ответ нам вываливается прямо в командную строку огромное количество информации, которую не совсем удобно читать в терминале, не говоря уже об обработке данной информации.
Перенаправим вывод в файл – так будет явно удобнее. В этом нам поможет спецсимвол '>'

$ curl 192.168.***.***/status.htm > Oki.txt

Открываем получившийся файл в редакторе Vi

$ vi Oki.txt

Oki.txt в редакторе Vi
image

Уже гораздо лучше, не правда ли? Однако, вся страница нам все равно не нужна. Нужны лишь значения состояния тонера. Начинаем вычленять данные. В этом нам поможет grep – утилита, ищущая строки, в которых содержится значение, равное указанному регулярному значению.

Внимательно рассмотрим теги, в которых содержится значения тонера. Видим, что в них мы встречаем одно и то же выражение ‘value=”***”’

Примечание
Почему три звездочки? Потому что тонер-картридж может быть полон и отдавать значение 100.

Примечание
Более опытные читатели так же могут заметить, что можно отсеять данные по регулярному выражению “hidden”. Да, вы абсолютно правы. Для подтверждения прикрепляю скриншот вывода терминала. Как можете видеть – результат абсолютно такой же, как и при отсеивании через ‘value=”***”’

image

«Грепаем» результаты, полученные через cURL. Дабы немного ускорить и визуализировать процесс – выводим значения сразу в терминал.

$ curl 192.168.***.***/status.htm | grep ‘value=”***”’ 

Результаты grep'a
image

Отлично. Достаточно лаконичный вывод. Далее нам нужно избавиться от текста и оставить лишь числовые значения.

Примечание
Возможно, более опытные читатели сейчас воскликнули – «Можно ведь и в Zabbix’е обрезать строки и получить числовые результаты!». Можно, не спорю. Но мое мнение – лучше завести числовые значения. Это лаконичнее и элегантнее.

Отсеем текстовые данные, оставив лишь числовые значения. В этом нам снова поможет grep c флагом -Eo. Он позволить вывести только числовые значения.

$ curl 192.168.***.***/status.htm | grep ‘value=”***”’ | grep -Eo ‘[0-9]{1,}’

Вывод чисел
image

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

Curl 192.168.***.***/status.htm | grep ‘value=”***”’ | grep -Eo ‘[0-9]{1,}’ | sed -n 1p

Результат работы sed
image

Разберем часть с sed. 1p – дать на вывод первую строку. -n – отсеять все, кроме указанной строки. Как видим – после данной команды на выводе – лишь численное значение состояния голубого тонера.

Теперь займемся написание скрипта.

Bash-скрипты имеют некоторую особенность по сравнению с теми же bat-скриптами. Они обязательно должны начинаться с шебанга – «#!». Дальнейшие строки, начинающиеся с # — будут интерпретированы как комментарии.

Скрипт же будет выглядеть следующим образом:

#! /bin/bash 
#This script received toner level's from Oki_834
curl 192.168.***.***/status.htm | grep ‘value=”***”’ | grep -Eo ‘[0-9]{1,}’ | sed -n 1p >/var/cyan.txt
curl 192.168.***.***/status.htm | grep ‘value=”***”’ | grep -Eo ‘[0-9]{1,}’ | sed -n 2p >/var/magenta.txt
curl 192.168.***.***/status.htm | grep ‘value=”***”’ | grep -Eo ‘[0-9]{1,}’ | sed -n 3p >/var/yellow.txt
curl 192.168.***.***/status.htm | grep ‘value=”***”’ | grep -Eo ‘[0-9]{1,}’ | sed -n 4p >/var/black.txt

Добавляем файл скрипта в crontab, и тем самым автоматизируем его выполнение. Автор выставил */15 * * * * — выполнение каждые 15 минут.

Итог – веб-страница принтера автоматически парсится, мы получаем необходимые нам числовые значения и сохраняем их в нужной нам директории.

Перенос полученных значений в Zabbix


Теперь займемся переносом данных в Zabbix.

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

Создадим новый элемент данных. Именуем как нам угодно, тип указываем Zabbix agent.

ВНИМАНИЕ
Я проводил все вышеописанные манипуляции на сервере с установленным Zabbix-server и Zabbix-agent. На вашем сервере, где вы провели вышеуказанные манипуляции, тоже должен быть установлен Zabbix-agent.

Самое интересное и важное у нас на данном этапе – ключ. Нам необходим vfs.file.contents[файл,<кодировка>]. Файл – абсолютный путь к файлу.

Создание элемента данных в Zabbix
image

Указываем наш путь к файлу и проверяем правильность. На выводе теста мы должны увидеть наше значение черного тонера.

Успешно выполненный тест
image

Итог – мы осуществили перенос данных в Zabbix, и теперь можем контролировать состояние расходных материалов централизованно.

Заключение


Мы освоили получение данных с помощью парсинга веб-страниц. В данном примере был взят принтер Oki 834, и успешно осуществлено получение данных о тонере. Я ответственно заявляю, что таким же способом было осуществлено получение данных о состоянии драм-юнитов, ленты и печи.

Доказательства в скриншотах
image

image

Таким образом возможно получение информации о расходниках с практически всех принтеров, и не только о принтерах. Парсинг – достаточно удобный инструмент, и работать с ним мне очень понравилось. И если моя статья поможет хотя бы одному человеку – значит, все было не зря.

Хочу так же выразить огромную благодарность redheaddeer, akozhevnikov97 и человеку, пожелавшему быть анонимом за помощь в написании статьи. Всем спасибо!