Опрос устройств печати по SNMP протоколу, пока печатает принтер



    Расскажу Вам свой опыт по созданию приложения, который собирает статистику о печати устройств по SNMP протоколу. Всего более 1000 устройств и опрос выполняется в режиме реального времени, пока печатает принтер. Как это все реализовано вы узнаете из статьи.



    Введение


    SNMP это стандартный интернет-протокол для управления устройствами в IP-сетях на основе архитектур TCP/UDP.

    С помощью SNMP не собрать информацию о пользователе, который отправил на печать файл. Кроме этого, SNMP нельзя использовать для локальных принтеров подключенных по USB.
    Чтобы решить эти задачи необходимо создать клиента, который должен собирать информацию и отправлять всю статистику на сервер. В организации было так заведено, что на все клиентские машины устанавливали одинаковые ОС Linux. Соответственно клиент по сбору статистики печати написан в Linux системе, как демон (аналог службы в Windows).

    Клиент сбора информации о печати


    Клиент сбора печати (написан на Python) выполняет следующие задачи:

    1. перехватывает сообщения из сервиса печати CUPS
    2. сохраняет информацию о печати в CSV-файл
    3. отправляет CSV файлы в папку на сервер по FTP

    CSV файл содержит следующие поля:

    1. Дата и время задания печати
    2. IP-адрес или доменное имя компьютера, с которого отправлен документ на печать
    3. IP-адрес или хост устройства печати
    4. Идентификатор работы (Cups Job ID) — ID задания из сервиса печати CUPS
    5. Наименование работы — чаще всего это имя файла
    6. Имя пользователя, отправившего на печать
    7. Количество страниц
    8. Размер задания печати (Размер задания в КБ)
    9. Статус печати (Статус задания)
    10. Количество копий (Кол-во копий)
    11. Кол-во копий по файлу задания — служит для более точного определения количества копий;
    12. Количество страниц по SNMP-протоколу — служит для более точного определения количества страниц
    13. SNMP доступно — это признак, что устройство должно непрерывно опрашиваться по SNMP-протоколу, пока документ распечатывается
    14. Счетчик устройства печати на время начала печати (Значение переменной SNMP) — это проверочный счетчик, по которому определяется начало SNMP-опроса сервером

    Клиент не имеет GUI-интерфейса, все настройки прописаны в конфигурационном файле

    Пример конфигурационного файла
    [main]
    # Основной каталог с приложением
    app_directory = /opt/printwatcher
    
    # Директория данных. Здесь располагаются данные приложения
    # подготовленные к отправке файлы отчётов и служебные файлы)
    stat_file_directory = /opt/printwatcher/data
    
    # Файл, в котором хранится внутреннее состояние системы
    state_file = /opt/printwatcher/data/state.pickle
    
    # Файл, в котором хранится номер последней выполненной команды
    command_state_file = /opt/printwatcher/data/command.state
    
    # Шаблон имени файла отчёта
    # Возможные именованные аргументы:
    #  datetime - дата создания в формате ISO 8601
    #  random - случайный идентификатор из 8 символов
    stat_filename_template = {random}_print_jobs.csv
    
    # Максимальный размер файла отчёта в МБ
    # (при превышении начальные строки удаляются)
    max_stat_file_size_mb = 10
    
    # Разделитель CSV. Возможные значения: TAB, SPACE, SEMICOLON, COMMA
    csv_delimiter = SEMICOLON
    
    # Запускать ли поток наблюдения за очередью
    start_service = start
    
    
    [logging]
    
    # Уровень логирования (DEBUG, INFO, TRACE)
    level = DEBUG
    
    # Расположение лога
    log_file = /var/log/printwatcher.log
    
    # Временный лог для загрузки после рестарта
    restart_log_file = /var/log/printwatcher-restart.log
    
    # Максимальный размер лога
    # (при превышении архивируется/удаляется системной утилитой logrotate)
    max_log_file_size_mb = 10
    
    
    [cups]
    
    # Директория, в которой хранятся временные файлы CUPS
    spool_directory = /var/spool/cups/
    
    # Удалять временные файлы CUPS по прошествии этого времени
    # (в часах)
    job_file_lifetime_hours = 48
    
    # Не обновлять в отчёте информацию по задаче по прошествии этого времени
    # (в часах)
    job_info_lifetime_hours = 48
    
    
    # Настройки FTP
    [ftp]
    
    host = 192.168.1.39
    user = ftpuser
    password = P@ssw0rd
    port = 21
    
    # Задержка перед следующей попыткой при неудачном соединении по FTP
    # (в секундах)
    connection_retry_seconds = 10
    
    # Максимальная задержка, после которой прекращаются попытки соединения по FTP
    # (в секундах)
    connection_timeout_seconds = 3600
    
    # Задержка между проверками файла с командами на FTP сервере
    # (в секундах)
    polling_interval = 30
    
    # Каталог управления агентом на ftp-серевер
    management_directory = /management
    
    # Каталог для записи ответов агентом на ftp-серевер
    response_directory = /management
    
    # Каталог обновления агента
    update_directory = /update
    
    # Каталог в котором ищется конфигурационный файл
    data_directory = /data
    
    # Настройки SNMP
    [snmp]
    # следует ли опрашивать устройство по SNMP
    retrieve_snmp_info = false
    community = public
    oid = 1.3.6.1.2.1.43.10.2.1.4.1.1
    port = 161
    


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

    Архитектура сервера сбора информации о печати


    Сервер написан на языке C#, СУБД — MSSQL.

    1. Конфигуратор БД — GUI приложение, позволяющее создать и удалить БД.
      БД максимально нормализована таким образом, чтобы в основной таблице статистики не было текстовых полей для экономии места на диске.
    2. Приложение настройки сбора статистики, это GUI приложение позволяющее внести изменения в БД по SNMP-опросу, настроить OIDы, а также запускать и останавливать службу сбора статистики печати.



    3. Собственно приложение сбора и обработки статистики (служба Windows)

    Сервер сбора информации о печати


    Задачи сервера


    1. следить за очередью печати при обработке большого количества CSV-файлов
    2. постоянно сканировать папку на наличие CSV файлов
    3. парсить CSV-файлы и записывать информацию о печати в БД
    4. сохранение копии CSV-файлов в архив (параметр настраивается) [помогает для отладки]
    5. удаление CSV-файла после обработки
    6. ожидать разрешения конфликта
    7. вычислять выражения над значениями OID'ов
    8. раз в месяц информация выгружается в архив, а старая информация удаляется

    Подробное описание алгоритмов работы внутри сервера


    Прежде чем служба будет отслеживать печать в режиме реального времени, необходимо выполнить парсинг старых CSV-файлов (которые накопились, пока не работал сервер) и сохранить информацию в БД. Будем называть этот пункт «первым чтением каталога CSV-файлов», который может помочь быстро собрать статистику старой печати и сохранить в БД.

    Затем служба переходит в постоянное отслеживание появления CSV-файлов в папке в отдельном потоке с интервалом 1 сек. Каждый CSV-файл обрабатывается в отдельном потоке.

    Если CSV файлов в папке очень много, то на этот случай предусмотрено ограничение количества одновременных потоков чтения файлов, чтобы приложение стабильно работало. При запуске службы в папке может быть очень много CSV-файлов и эти файлы обрабатываются без SNMP-опроса, соответственно на первое чтение каталога установлено отдельное ограничение на количество потоков обработки CSV-файлов (опытным путем было установлено, что количество потоков при первом чтении CSV-файлов должно быть значительно меньше, чем количество потоков после обработки большого количества файлов).

    В алгоритме предусмотрено определение IP-адреса по имени устройства и наоборот (определение имени устройства по IP-адресу) с помощью метода System.Net.Dns.GetHostEntry(). В случае отсутствия наличия связи с устройством, метод System.Net.Dns.GetHostEntry() выполняется очень долго, в связи с этим был доработан клиент, который предоставляет эту информацию в CSV. Но на сервере эта проверка осталась и метод System.Net.Dns.GetHostEntry() до сих пор является узким местом.

    Сохранение информации в БД


    Кроме информации о печати, в БД хранится информация для статистики:

    1. время начала и окончания SNMP-опроса
    2. общее количество строк в CSV-файле
    3. количество строк с включенным SNMP-опросом.

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

    После прочтения всего CSV-файла собирается информация о всех заданиях печати в объект List, которые должны быть проконтролированы SNMP-опросом. После чтения CSV-файла, он переносится в архив, если это задано настройками, и затем CSV-файл удаляется.

    После того, как CSV-файл полностью прочитан проверяется, что заданы настройки опроса по SNMP-протоколу, затем устройства сортируются по приоритетам:

    1. Группа по-умолчанию, в которой есть все устройства базы «ricoh_dmnx» — так называется БД системы мониторинга от производителя Ricoh, из которой мы берем список опрашиваемых устройств.
    2. Устройства, которые есть в базе ricoh_dmnx, но нет в группах
    3. Устройства, которые есть в базе ricoh_dmnx и есть в группах
    4. Устройства, которых нет в базе ricoh_dmnx, но есть в базе нашей службы

    У каждого устройства создается очередь печати, чтобы в один момент времени SNMP-опрос работал только с одним заданием печати. Таким образом, пока устройство опрашивается по SNMP-протоколу, пользователь может отправить на печать еще какой-нибудь файл и на сервер может поступить новый CSV-файл, который сохраняется сразу в БД, но опрос по нему будет выполняться после того, как закончится печать текущего документа.

    При SNMP-опросе отслеживается изменение счетчика печати, статус устройства и признак ошибки устройства во время печати. Время ожидания между SNMP-опросами — 300 мс.

    Подводные камни


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

    1) Не продолжать опрос, пока устройство находится в состоянии ошибки (например: замята бумага)

    2) Ошибка принтера может меняться с течением времени, поэтому таймаут SNMP-опроса не должен срабатывать в случае изменения ошибки (например, в принтере закончилась бумага, но после добавления бумаги в лоток статус принтера сменился)

    3) Если на устройство печати отправляется несколько заданий одновременно, то при этом счетчик после печати первого задания:
    — не изменяет статус
    — изменяет счетчик

    Системные OID-ы устройств печати


    На основе анализа этих трех OID'ов было написано мое приложение опроса SNMP-устройств:

    1) [1.3.6.1.2.1.43.10.2.1.4.1.1] — Общий счетчик устройства

    2) [1.3.6.1.2.1.25.3.5.1.1.1] — Статус устройства



    3) [1.3.6.1.2.1.25.3.2.1.5.1] — Ошибка устройства в процессе печати

    Отчеты


    Отчеты реализованы с помощью SQL Server Reporting Services.

    Отчет по сравнению данных печати по месяцам




    Печатные задания по пользователям




    Сводный отчет по SNMP запросам




    Статистика SNMP запросов




    Вывод


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

    Особенностью в реализации проекта сбора печати была еще в том, что я не имел при себе ни одного принтера. Работал через эмулятор, который можно быстро установить и настроить (достаточно иметь MIB-файл настроек устройства печати).

    В дальнейшем напишу о том, как было сделано управление агентами печати.
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 2

      0
      3) отправляет CSV файлы в папку на сервер по FTP

      сегодня это выглядит несколько странно (мягко говоря)

        0
        а как кошерно? посылать json post со всей таблицей с gzip компрессией?

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое