Современные веб‑сайты требуют постоянного контроля, чтобы обеспечивать стабильную работу, высокую скорость загрузки и бесперебойный пользовательский опыт. Мониторинг позволяет своевременно выявлять сбои, снижать время простоя и повышать качество обслуживания пользователей. Без постоянного мониторинга можно столкнуться с проблемами, такими как медленная загрузка страниц, недоступность ресурсов или даже утечка данных из‑за уязвимостей безопасности.
Поискав бесплатные решения — понял, что это всего лишь сыр в мышеловке, и особо н едает желаемого результата. Так почему бы не сделать свой? Всего то надо немного познаний в проектировании сервисов и ChatGPT для ускорения процесса разработки.
И так, начинаем пилить, а для начала бы неплохо разобраться — а какие вообще бывают типы мониторинга.
Типы мониторинга сайтов
Мониторинг веб-сайта можно классифицировать по различным параметрам, в зависимости от целей и задач, которые он решает:
Сетевой мониторинг — отслеживание доступности сервера, проверки ICMP (ping), анализ времени отклика DNS-запросов, проверка доступности портов и работоспособности серверных соединений.
Мониторинг загрузки страниц — измерение времени отклика сервера, скорости рендеринга, объема переданных данных и времени выполнения JavaScript-кода на стороне клиента.
Мониторинг ошибок — контроль HTTP-кодов (404 - страница не найдена, 500 - внутренняя ошибка сервера и т. д.), выявление ошибок JavaScript, проблем с API-интерфейсами и сбоев в работе баз данных.
Мониторинг безопасности — контроль сроков действия SSL-сертификатов, обнаружение потенциальных уязвимостей, защита от DDoS-атак и попыток несанкционированного доступа.
Из всего выше перечисленного, мне бы хотелось иметь для начала простой монитор загрузки и получение кодов ответа от сервера, благо эти функции можно уместить в один запрос.
Время загрузки страницы: технический подход
Одним из аспектов мониторинга производительности является контроль времени загрузки страницы. Различные метрики помогают оценить скорость работы сайта и выявить узкие места. Основные из них:
TTFB (Time To First Byte) — время до получения первого байта ответа от сервера. Показывает, насколько быстро сервер реагирует на запрос.
FCP (First Contentful Paint) — время, через которое появляется первый элемент контента на экране пользователя.
LCP (Largest Contentful Paint) — время загрузки самого крупного элемента на странице, обычно изображений или видео.
Эти параметры помогают понять, где находятся задержки в загрузке и как можно улучшить производительность сайта.
Однако первый байт нам не даст понимания что творится с отслеживаемым ресурсом, а для загрузки ВСЕХ элементов на странице — надо достаточно много ресурсов (времени и трафика). Так что можно остановиться на банальной загрузке html кода страницы и его заголовков. Да, на странице может быть «зависающий ресурс», элемен на загрузку которого требуется время (js, css, или jpeg), но об этом подумаем потом.
Код на Python: отправка запроса и замер времени ответа
Для базового мониторинга доступности сайта и времени его отклика используем requests.get() запрос с некоторым числом параметров:
собственно сам отслеживаемый ресурс;
максимальное время на отклик;
user‑agent для понимания что это запрос моего бота и где искать его описание;
А вот и пример кода такого запроса на Python, само собой для красоты завернем его в класс:
from app import USER_AGENT, USER_AGENT_SITE, MAX_PAGE_LOAD_TIMEOUT
import requests
import time
from requests.exceptions import ConnectionError, Timeout, HTTPError
# Запрос к серверу с получением html страницы (только один файл)
class HtmlLoaded:
url: str
def __init__(self, url):
self.url = url
def get(self):
headers = {
"User-Agent": f"{USER_AGENT} (+{USER_AGENT_SITE}/html_loaded_bot)"
}
timeout = int(MAX_PAGE_LOAD_TIMEOUT)
# Запоминаем стартовое время
start_time = time.time()
try:
# Делаем запрос к сайту
response = requests.get(self.url, timeout=timeout, headers=headers)
# Фиксируем время окончания
end_time = time.time()
result = {
'requestTime': round(end_time - start_time, 5),
'requestCod': response.status_code
}
return result
except ConnectionError as e:
error = str(e)
except Timeout as e:
end_time = time.time()
result = {
'requestTime': round(end_time - start_time, 5),
'requestCod': 408,
}
return result
except HTTPError as e:
end_time = time.time()
result = {
'requestTime': round(end_time - start_time, 5),
'requestCod': e.response.status_code,
}
return result
except Exception as e:
error = str(e)
end_time = time.time()
result = {
'requestTime': round(end_time - start_time, 5),
'requestCod': 900,
'error': error
}
return result
По сути этот скрипт делает запрос фиксируя время перед и после, а разница — наше искомое значение. Так‑же вытягиваем код ответа сервера. А что еще надо подобного мониторинга?
Однако сам по себе запрос бесполезен, где‑то надо как минимум ставить задачу на проверку, а после обрабатывать полученный результат.
Архитектура системы мониторинга
По моему мнению эффективная система мониторинга должна состоять из нескольких ключевых компонентов:
Ядро (оно же core)
Оно отвечает за следующий функционал:
Планирование проверок по расписанию.
Назначение задач воркерам.
Анализ результатов и генерацию отчетов.
Отправку оповещений в случае обнаружения проблем.
Тут у нас будет база данных для хранения задач, и результатов запросов. Планировщик типа cron — для постановки задач на опрос в очередь и в дальнейшем отправки отчетов о текущем состоянии скажем раз в сутки. Так же можно придумать и прикрутить массу функционала, но не будем забывать что это всего лишь один из микросервисов общей системы, посему запросы и фронтенд вынесем отдельно.
Воркер (Worker )
Это вспомогательный процесс, выполняющий задачи по мониторингу. Его функции:
Получение задания от ядра.
Выполнение HTTP‑запроса или других проверок.
Обратная передача результатов в ядро.
Могут существовать несколько воркеров, работающих параллельно для повышения производительности, а также могут быть запущены на нескольких серверах.
Фронтенд (UI)
А вот тут уже могут быть несколько вариаций, например как сайт или же Telegram Бот. Я выбрал реализацию в виде бота. Как минимум удобство в разработке такого решения, как максимум — возможность отправки оповещений сразу пользователю. Да СМС это не заменит, но как говорится — джип эта та машина, которая застрянет там, куда другая не доедет. А для решения проблем с сайтам нам как минимум нужен приемлемый интернет и «джип» в виде СМС тама и не нужен по сути.
Добавление и управление трекерами мониторинга
Получение уведомлений при недоступности ресурса
В дальнейшем отображение статистики и истории проверок.
А также графики и отчеты для анализа производительности сайта.
Деплой и масштабирование
Все перечисленные компоненты можно разнести по отдельным микросервисам и развернуть на разных серверах. Такой подход увеличивает отказоустойчивость и масштабируемость системы, а также позволяет гибко настраивать нагрузку.
Те же самые Воркеры в идеале разместить на отдельной «голой» машине, а так‑же закрыть все ненужные порты, чтобы ничего не мешало делать запросы.
Для удобства разработки и обновления можно использовать Docker, который позволит изолировать сервисы и легко управлять их зависимостями, а также масштабировать систему в ширь, добавляя новые сервера с Воркерами.
А для быстрого и удобного обновления, можно заручиться поддержкой чего‑то типа GitLab и его функций CI/CD, что обеспечит автоматизированное развертывание новых версий компонентов, тестирование и обновление системы мониторинга без ручного вмешательства.
В итоге
И в качестве заключения приведу ссылку на то что уже получилось у меня сделать, а именно бота по мониторингу сайтов. Конечно не все вне гладко, и требует тестирования и отладки, но базовый функционал уже доступен и работает. Во избежания злоупотреблением сервиса, в системе работает биллинг, где один запрос = один point, А получить их можно там‑же бесплатно, в возможностью добавлять в последующем там‑же способом.
В дальнейшем постараюсь описать проблемы с которыми столкнусь, и результатами работы всей этой системы. О новых функциях буду сообщать в Телеграм канале из описания к боту.
SeveR31
Статья пахнет нейронкой из-за соотношения текста к спискам. Реклама своего бота это тоже сильно, из-за этого вся статья выглядит подводкой к ней, а не осмысленным содержимым.
Пихать одну функцию в целый класс "для красоты" это накладно и незачем, если хотели совсем красиво могли бы сделать декоратор для замера времени и просто в функцию запрос к нужному адресу(любому) вынести, вышло бы изящно и универсально. Или хотя бы дописать к классу set_url метод, чтобы с помощью одного класса шерстить много url-ов подряд.
Если с метриками анализа сайта я соглашусь, то делать расписание на основе cron/crontab это лишний башевый гемморой. Можно подключить Celery или ему подобный инструмент и сделать расписание там, задачи ещё и параллельно будут выполнятся на разных ядрах с поддержкой масштабируемости.
Параграф деплоя выглядит лишним и недоделанным,т.к не несёт в себе никакой существенной информации, кроме двух инструментов.