Telegram-бот мониторинга состояния серверов на Haskell
Одним из преимуществ функциональных языков является удобство обработки списков из-за встроенного механизма рекурсий и сравнения образцов, но многие разработчики не используют их для разработки реальных приложений, в которых такие задачи встречаются.
Рассмотрим возможность применения функционального языка Haskell на задаче мониторинга состояния серверов и анализа их логов. Задача является важной, так как чем дольше сервер находится в неработоспособном состоянии, тем больше проблем это приносит его пользователям.
Основная задача программы – регулярно осуществлять проверку серверов пользователя, записывать результаты в базу данных и при необходимости, выдавать собранную статистику.
Для функционирования программы необходимо создать базу данных и три таблицы:
- Users – таблица с информацией о пользователях.
- UrlList – хранит URL-адрес, состояние сервера на момент проверки и ID пользователя, добавившего адрес.
- UrlState – в данной таблице сохраняются логи обращений к серверу, а именно: имя сервера, состояние и дата состояния.
Схема таблиц
В данной программе взаимодействие с базой данных производится с помощью модуля Database.SQLite.Simple. Рассмотрим пример функции, которая добавляет новый URL-адрес. Необходимо открыть соединение с базой данных и передать функции SQ.execute открытое соединение и текст запроса на языке SQL, затем закрыть соединение.
Листинг 1. Пример вставки новой строки в таблицу.
Все взаимодействие с пользователем осуществляется через Telegram-бот. У него есть несколько основных команд:
- Add url – добавляет новый URL-адрес;
- Remove url – удаляет данный URL-адрес;
- Show – показывает список URL-адресов текущего пользователя;
- Analyze url – производит анализ логов данного URL-адреса;
- Ping url – отправляет запрос на данный URL-адрес, ждет ответ и выводит актуальную статистику.
Для взаимодействия с Telegram-ботом используется функция handleAction, которая обрабатывает все активности в чате. Функция определяет пользователя: если текущего пользователя нет в базе данных, то в чат отправляется сообщение со списком возможных команд и новый пользователь записывается в таблицу Users. Если пользователь известен, то команды из чата анализируются и обрабатываются с помощью конструкции case. Для каждой команды предусмотрены свои функции и ответы в чате.
Листинг 2. Пример взаимодействия с Telegram-ботом.
Рассмотрим подробнее основные функции. Функция ping принимает на вход URL-адрес и пытается получить ответ от сервера. Для работы с http-запросами в Haskell используется модуль Network.HTTP.Simple. С помощью функции httpLBS получаем ответ от сервера: если произошла ошибка и к серверу невозможно подключиться, то фиксируем состояние ошибки в базе данных в таблице с логами. Если ошибки не произошло, то фиксируем нормальное состояние.
Листинг 3. Пример работы с HTTP-запросами.
Функция analyze изначально вызывает функцию getUrlState для получения логов состояний по данному URL-адресу, при этом логи возвращаются отсортированными от более новых записей к более старым. Затем полученная информация передается в функцию analyseLog, которая принимает следующие параметры: массив логов, состояние, количество попыток соединения и имя сервера. Рекурсия, заложенная в функциональных языках, позволяет удобно обрабатывать логи, хранящиеся в массиве.
Листинг 4. Пример рекурсивной обработки списка.
Основная задача функции analyseLog – сформировать статистику работоспособности сервера. Если состояние сервера на момент последней проверки в логе равно «1», то функция возвращает сообщение о том, что сервер функционирует нормально, а также время последней проверки.
Если состояние сервера на момент последней проверки – «0», но до этого в логе видно, что сервер работал, то выдается сообщение о том, что сервер находится в неработоспособном состоянии, а также его последнее время работы.
Если в логах всегда встречается состояние «0», то выводится сообщение о том, что сервер никогда не работал, а также количество попыток связаться с ним.
В приведенном примере мы можем увидеть реализацию полноценного приложения на функциональном языке. В приложении сочетаются методы взаимодействия с HTTP серверами, Telegram-ботом, базой данных и применение рекурсий для анализа логов. Для чистых функций Haskell хранит результаты вычисления в кэше, поэтому, если функция вызывается с теми же параметрами, она не будет выполняться, а возьмет результат из кэша. Эта особенность позволяет сэкономить время на выполнение некоторых функций.
Полный код программы вы можете найти на моем GitHub: https://github.com/ValentinaFedorova/Ping_Server_Bot.
Поделитесь своим опытом разработки на функциональных языках в комментариях!