При обеспечении высокой доступности веб-инфраструктуры критически важно иметь перед глазами полную картину происходящего с сервером. В этой статье мы разберем структуру эффективного дашборда Grafana для веб-сервера Nginx, который собирает и анализирует данные напрямую из логов с помощью Grafana Loki без использования тяжелых экспортеров.
Дашборд решает три главные задачи:
- мгновенное обнаружение аномалий (атаки, всплески ошибок),
- замер реальной производительности бэкенда под нагрузкой
- аудит сетевого трафика.
Архитектура и структура дашборда
Дашборд логически разделен на три уровня визуализации:
- Оперативные индикаторы (Singlestat / Stat panels) — верхний ряд для мгновенной оценки ситуации.
- Аналитические тренды (Time series) — графики в центре для выявления паттернов нагрузки и скорости во времени.
- Сырые аномалии (Logs volume) — нижняя детальная панель для глубокого расследования причин сбоев.
— Концепт визуализации метрик в едином пространстве.

Конфигурирум Nginx
Первым делом правим конфиг Nginx
nano /etc/nginx/nginx.conf
Добавляем параметры для сброра времени ответа
log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"' 'rt=$request_time urt=$upstream_response_time';

nginx -t
systemctl restart nginx
Проверяем конфиг Alloy
nano /etc/alloy/config.alloy
local.file_match "nginx_logs" {
path_targets = [
{
__path__ = "/var/log/nginx-from-dmz/*.log",
job = "nginx-dmz",
app = "nginx",
host = "dmz",
},
]
}
loki.source.file "nginx" {
targets = local.file_match.nginx_logs.targets
forward_to = [loki.process.nginx.receiver]
}
loki.process "nginx" {
stage.regex {
expression = "^(?P<remote_addr>\\S+) - - \\[(?P<time>.*?)\\] \"(?P<method>\\S+) (?P<uri>.*?) (?P<protocol>.*?)\" (?P<status>\\d+) (?P<body_bytes_sent>\\d+) \"(?P<referer>.*?)\" \"(?P<user_agent>.*?)>
}
stage.labels {
values = {
remote_addr = "",
method = "",
status = "",
app = "",
host = "",
}
}
forward_to = [loki.write.default.receiver]
}
Рисуем дашборд в Grafana
Ключевые метрики дашборда и LogQL запросы
Для того чтобы дашборд корректно отображал данные за любой выбранный пользователем период (Таймпикер в Grafana), все суммирующие панели переведены в режим Type: Instant с использованием макроса [$__range].
1. Количество успешных ответов (Код 200)
Показывает базовый уровень здоровья легитимного трафика. Стабильный рост или плато — норма, резкое падение до нуля — критический инцидент.
- Тип панели: Stat (Зеленый цвет при нормальных значениях)
- Запрос LogQL:
sum(count_over_time({job="nginx-dmz", status="200"}[$__range]))

2. Ошибки доступа и аномалии (403, 404, 444)
Критически важный блок для обнаружения сетевых сканеров, ботов и попыток взлома.
- 403 Forbidden — обращение к закрытым директориям и файлам.
- 404 Not Found — поиск уязвимых скриптов конфигурации.
- 444 Connection Closed Without Response — специальный код Nginx, сигнализирующий о том, что сервер успешно сбросил соединение подозрительного бота без траты ресурсов на ответ.
- Тип панели: Мульти-индикатор Stat (Группировка по меткам).
- Запрос LogQL
sum by (status) (count_over_time({job="nginx-dmz", status=~"403|404|444"}[$__range]))
3. Ошибки сервера (Группа 5xx)
Самый критичный триггер для дежурного администратора. Появление кодов 500 (ошибки кода), 502 (упавший бэкенд) или 503/504 (перегрузка и таймауты под нагрузкой) требует немедленной реакции.
- Тип панели: Stat с настроенным порогом (Thresholds:
>50— критический красный цвет, привлекающий внимание). - Запрос LogQL:

sum(count_over_time({job="nginx-dmz", status=~"5.."}[$__range]))
4. График отданного трафика
Позволяет отслеживать сетевую утилизацию канала. Разделение линий по успешным статусам (200 и 201) наглядно демонстрирует, что отдача медиаконтента (200) формирует основной объем гигабайт, в то время как создание объектов (201) утилизирует канал минимально.
- Тип панели: Time series (Ось Y настроена в единицах Data -> bytes (IEC)).
- Запрос LogQL:promql
sum by (status) (sum_over_time({job="nginx-dmz"} | pattern `<_> - - [<_>] "<_>" <status> <body_bytes_sent> "<_>" "<_>"` | status=~"20." | unwrap body_bytes_sent [$__interval]))
5. Скорость ответа сервера (Latency)
Метрика, отражающая реальный пользовательский опыт (User Experience). Позволяет увидеть, как ведет себя приложение под стресс-тестами (например, при нагрузке в 100 виртуальных пользователей через k6). Кастомный формат логов Nginx (rt=$request_time) дает возможность строить графики задержек.
- Тип панели: Time series (Ось Y переведена в Time -> seconds (s)).
- Запрос LogQL (Среднее время):

sum(avg_over_time({job="nginx-dmz"} | regexp `rt=(?P<rt>[0-9.]+)` | unwrap rt [$__interval]))
Детальный анализ: Панель «Живых» логов
Нижний ярус дашборда занимает панель Logs. В нее выводятся только строки с ошибками 5xx. Это избавляет инженера от необходимости заходить на сервер по SSH. При фиксации всплеска на графике Latency, достаточно прокрутить дашборд вниз и увидеть в логах, например, строки атаки инструмента нагрузочного тестирования Grafana Cloud k6 на тяжелые скрипты бэкенда (/wp-comments-post.php), из-за которых сервер начал отвечать кодом 503 Service Unavailable.

Результат
Получаем красивый информативный дашборд.

Видно работу плагина Worldfence, который начал блокировку сканера по достижению порогов и логи по 5ХХ
