Мониторинг состояния своего ресурса при помощи Telegram-бота

Привет, Хабр! Я уже давно наблюдаю за тобой, но все никак не решаюсь сделать свой первый шаг. Теперь мне показалось что я готов. Расскажу о своем опыте работы с telegram ботом — последнее время эта тема достаточно популярна на просторах сети, да и на самом Хабре я встречал уже не мало статей. Но по большей части в них рассказывается о принципах создания ботов, и нет ни слова о том, какую практическую пользу можно из этих самых ботов извлечь.

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

Что такое «система мониторинга состояния»? По своей архитектуре это должен быть небольшой модуль, который отвечает за проверку состояния и за информирование об отклонениях от нормального состояния.

Есть множество готовых комплексных решений, включающих в себя такую систему мониторинга. Это и знаменитый zabbix и nagios, и yandex метрика и еще огромная куча аналогичных прекрасных инструментов.

Аналитика


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

Первое время любой свежий сайт мало интересен пользователям. Однако при достаточных усилиях или денежных вложениях (обычно и то и другое) на ресурсе появляется трафик.

Мы уже поместили в наш код скрипт google analytics и можем наблюдать за динамикой изменения нашей аудитории. Но этого не всегда бывает достаточно. Иногда хочется знать больше — хочется контролировать весь процесс нахождения пользователя на сайте, вести его, направлять. Анализируя заголовки запросов и ответов можно получить исчерпывающую информацию о том, что делал каждый пользователь, когда и зачем. Для этого рано или поздно вы начинаете читать логи вашего веб сервера — иногда там скрыта ошибка, которая поможет исправить вам серьезный баг, а иногда просто интересно понять: кто же все-таки спамит вашу гостевую книгу?

Бот


Python и django идеально подходят для работы с telegram ботом. Что такое бот? В этом контексте, бот — это интерфейс взаимодействия между вашим приложением и клиентом telegram. Этот интерфейс позволит отправлять сообщения в зависимости от бизнес логики вашего приложения.
Я не буду расписывать здесь весь процесс создания и настройки веб приложения на django — врят ли у меня получится сделать это лучше чем у создателей официальной докумментации. Скажу только, что это не должно занять у вас больше десяти минут, если вы уже работали с этим фреймворком.

Хочется сказать спасибо Павлу Дурову и его команде — благодаря возможности установки webHook, работать с ботом стало максимально просто и удобно. Все что необходимо это:

  • Создать своего бота при помощи интерфейса BotFather в клиенте телеграм и настроить его, следуя инструкциям папы бота

  • Установить webHook, используя свой token, который папа бот поможет вам получить. Для этого переходим по url: api.telegram.org/bot{{ token }}/setWebhook?url={{ url }}, где token — ваше кольцо аутентификации, а url — это ссылка, запрос на которую обрабатывает контроллер вашего телеграм бота. Отмечу так же, что использоваться может только https протокол, т.е. необходим SSL.

  • Создать контроллер, обрабатывающий url из пункта 2, создать бизнес логику для вашего бота. Привязать контроллер к обработчику url. В часть url необходимо так же добавить свой token чтобы обеспечить другие люди не могли слать запросы на этот адрес.

  • Добавить бота в свой список контактов. Это можно сделать через поиск в клиенте telegram или используя ссылку @{{ bot_name }}

Далее все сводится к простой схеме. Как только вашему боту приходит какое-то сообщение, на url, установленный в webHook приходит запрос с информацией об этом сообщении. В частности там есть информация о дате сообщения, об id чата отправителя, о самом отправителе. Эту информацию лучше сохранять в базу данных, чтобы случайно не потерять — с ней и нужно работать. Мы программируем бота таким образом, что если ему приходит сообщение, которое является командой — он выполняет какое-либо действие. Скажем, я хочу, чтобы бот отправлял мне сообщения в telegram с информацией о каждом запросе, что приходит на мой сайт. Для этого нужно задать ему всего две команды, например:

/requests и /stop_requests. Первая команда добавит в базу подписку на рассылку информации о запросах на сайт, вторая команда — удалит эту подписку. Далее необходимо создать свой context processor — это можно сделать в большинстве современных MVC фреймворков. В его коде необходимо обработать подписки на рассылку и далее отправить сообщения в чат с указанными id, который мы предварительно сохранили в базу, когда нам пришел запрос на наш webHook url. Так же мы можем оформлять подписки на абсолютно любые события на своем сайте: регистрации пользователя (удобно реализовывать через сигналы), комментарии, ошибки. Простор для творчества просто бездонный. На своем ресурсе born2fish, где можно редактировать информацию о реках и озерах Мира, я использовал бота для получения информации о том, когда сущность водоема кто-то изменял. Это помогает оперативно получать сообщения о водоемах, требующих проверки модератором.

Сама отправка сообщения зависит от реализации. На python она выглядит так:

def _send_msg(bot, chat_id, message):
    bot.sendMessage(chat_id=chat_id, text=message)

А вот так может выглядеть функция обработки подписок и отправки информации о запросе:

def send_requests_subscriptions(request, city):
    """ send Telegram messages to subscribed users """
    bot_message = request.META['HTTP_USER_AGENT'] + " request from " + get_client_ip(
        request) + " (" + str(city['city']) + ") url = [" + request.path_info + "]"
    subscriptions = RequestsSubscription.objects.all()
    for subscr in subscriptions:
        _send_msg(bot=bot, chat_id=subscr.chat_id, message=bot_message)

Этот метод позволяет отобразить пользователю помощь, которая считывается из файла help.md:

def _display_help():
    return render_to_string('help.md')

Вместо заключения


На словах все кажется очень простым, но отмечу, что таких ботов трудно тестировать. Оптимальным решением станет Unit Test, в котором вы будете симулировать запрос от telegram и проверять работу бизнес логики бота.

Что еще может пригодится? Не всегда информация в профиле пользователя telegram заполнена полностью, так что следует проверять значения на None перед сохранением в базу, чтобы не получить IndexError.

Вы можете добавить своего бота в группу. Это поможет не рассылать информацию каждому пользователю, а отправлять ее в единое место, откуда она уже будет доступна всем желающим. Сделать это можно через интерфейс клиента telegram, в настройках вашего бота и вашей группы.
В качестве примера хочу поделиться ссылкой на своего тестового бота: @born2fishBot, Напишите ему /help чтобы получить список возможных команд.

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

Подробнее
Реклама
Комментарии 12
  • +3
    Можно исключить одно звено из Вашей цепочки, убрав нетривиальную настройку HTTPS и сертификата, а именно:
    При наступлении какого-либо события вызывать URL:
    https://api.telegram.org/botBOT_ID:BOT_TOKEN/sendmessage?chat_id=CHAT_ID&text=test *test* test&parse_mode=Markdown

    Некоторые сервисы мониторинга позволяют в случае «алерта» «дёргать» произваольный URL.
    • 0
      Спасибо, об этом не знал — очень пригодится. Однако с установкой SSL сертификата я бы не советовал затягивать? т.к. в скором времени поисковые роботы будут применять санкции к сайтам не поддерживающим протокол https
    • +2
      А на тот случай если урлы дергать возможности нет, можно гонять это все через почту используя procmail и немного смекалки.

       $ cat .procmailrc                                                                                                                                                                                                                                                   [14:20:32]
      # send message to telegram
      #
      :0b:
      | $HOME/telegram
      
      chemist@monitoring: /opt/prometheus
       $ cat telegram                                                                                                                                                                                                                                                      [14:20:40]
      #!/bin/zsh
      #
      #
      DEVOPS="GROUPID"
      BOT=BOTID
      BOT_TOKEN=bot token here
      
      BODY=$(< /dev/stdin)
      
      alias urlencode='python -c "import sys, urllib as ul; print ul.quote(sys.argv[1])"'
      
      URL="https://api.telegram.org/${BOTID}:${BOT_TOKEN}/sendMessage?chat_id=${DEVOPS}&text=$(urlencode ${BODY})"
      
      /usr/bin/curl -i -X GET ${URL}
      
      • 0
        спасибо, буду пробовать!
        zsh — интересная оболочка
        • 0
          Про procmail поясните пожалуйста подробнее
          • 0
            Ну отправил письмо на почту, сработало прерывание, выполнился скрипт telegram, в котором отработал запрос на url sendMessage…
            В файле procmailrc указано, какие действия надо предпринять после получения сообщения.
            Как-то так.
        • +2
          Есть замечательный https://github.com/ableev/Zabbix-in-Telegram от ableev, пишущий сообщения заббикса в Телеграм. Нужд изобретать какие-то еще велосипеды не вижу.
          • 0
            Мой телеграм бот анализирует прогноз погоды на 24 часа, состоящий из 9 показателей. После этого он формирует прогноз клева рыбы на основе состояния этих показателей, нетрудных математических операций и собственного опыта, а следом отправляет этот прогноз всем, кто прежде отправил ему команду /forecast
            Что касается zabbix — я не сторонник аналогичных решений и это все же несколько иной функционал, нежели описан в статье. Те, кто отправил команду /requests боту @born2fishBot, начнут получать от него сообщения о каждом запросе на сайте born2fish.ru. Это не требует установки стороннего софта на сервер — достаточно создать бота и добавить отправку сообщения в context processor, как бы он у вас не выглядел. Это позволяет в режиме реального времени следить за индексацией сайта роботами, за брутфорсом http форм, за процессом регистрации пользователей, а так же еще много всего. По сути это аналог tail -f /var/log/nginx/access.log, который приходит вам в телеграм.
          • +2
            Если кому-то нужен мониторинг на основе телеграм бота, то я для себя и всех желающих сделал https://trafficrobot.tk/
            • 0
              Классный бот у вас! Удобно использовать как обвязку для email уведомлений.
              А исходники, случаем, не открыты?
              • 0
                Хмм. Может открыть, действительно.
                • 0
                  А почему-бы и нет :) Если вам кода «не жалко» и/или не преследуете коммерческих целей почему бы не сделать вклад в сообщество.

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