Вы используете Nginx? А как у вас организован мониторинг логов Nginx?

Знаете ли вы, что мониторя логи nginx, вы можете значительно повысить стабильность и надежность своего веб-приложения?

В этой статье я покажу вам, как организовать мониторинг логов Nginx, использовать их в качестве метрик и что вообще можно из них выжать.

Зачем мониторить логи Nginx?

Чтобы обеспечить доступность нашей системы — Система считается доступной при отсутствии сбоев или когда количество сбоев не превышает определенный порог. Анализируя статус-коды HTTP, мы можем определить допустимый процент сбоев и следить за доступностью нашей системы.

HTTP-ответы за определенный временной период
HTTP-ответы за определенный временной период

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

Чтобы своевременно удалять устаревшие конечные точки  — В идеале мы бы хотели сразу удалять устаревшие конечные точки. Но мы не можем просто взять и сделать это, так как некоторые из наших клиентов могут еще использовать их. Мы могли бы проанализировать использование интересующих нас конечных точек, просмотрев историю, и принимать решение об их удалении, опираясь на реальные данные.

Базовый рабочий процесс

Базовый рабочий процесс решения выглядит следующим образом.

  1. Мы собираем метрики Nginx с помощью модуля filebeat [1].

  2. Filebeat публикует собранные метрики в elasticsearch.

  3. Мы можем визуализировать собранные метрики с помощью Kibana.

  4. Мы можем информировать нашу команду с помощью наблюдателей (watchers) [2].

Базовая структура нашего решения для сбора метрик Nginx
Базовая структура нашего решения для сбора метрик Nginx

Реализация решения

Весь код можно найти здесь: monitor-nginx-logs

Сбор метрик Nginx

Мы собираем метрики Nginx, используя следующий код:

filebeat.modules:  
- module: nginx  
  access:  
    var.paths: ["/var/log/nginx/host.access.log"]

Метрики публикуются в elasticsearch с помощью следующего кода:

output.elasticsearch:  
  hosts: ["http://elasticsearch:9200"]

Вы можете просмотреть собранные метрики, используя Discover в Kibana по адресу localhost:5601. http.response.status_code — интересующая вас метрика.

Метрики Nginx, собранные с помощью filebeat.
Метрики Nginx, собранные с помощью filebeat.

Визуализация статус-кодов HTTP в Kibana

Выберите Visualize Library и создайте визуализацию

Выберите TSVB.

Сгруппируйте статус-коды HTTP, как показано на следующей диаграмме.

Группируем статус-коды HTTP
Группируем статус-коды HTTP

Сразу приношу свои извинения за слабую читабельность текста на изображении. Я попытался увеличить масштаб, но он все равно не читался. Поэтому я выпишу текст ниже:

Часть слева: http.response.status_code>= 200 and http.response.status_code<= 299

Часть справа: 200

По аналогии прописываем это для всех остальных статус-кодов

Наконец, мы можем посмотреть красивую инфографику со статус-кодами HTTP за все время.

Статус-коды HTTP, разбитые по временным интервалам
Статус-коды HTTP, разбитые по временным интервалам

Информирование команды о неудачных запросах

Информирование нашей команды мы можем реализовать с помощью специального API наблюдателя [3]. Наблюдатель будет регулярно извлекать данные через определенные промежутки времени и информировать нашу команду, если будет выполняться заданное нами условие. Своевременное получение уведомлений позволит нашей команде действовать наиболее эффективным образом.

Предположим, мы хотим запускать наблюдателя каждый час:

"trigger": {  
  "schedule": {  
    "interval": "1h"  
  }  
}

Так как мы храним метрики в индексе filebeat:

"indices": [  
  "<filebeat-*-{now/d}>"  
]

мы можем определить неудачные запросы, используя следующую конфигурацию:

{
 "size": 0,
 "query": {
  "bool": {
   "must": [
    {
     "range": {
      "@timestamp": {
       "gte": "now-1h"
      }
     }
    },
    {
     "exists": {
      "field": "http.response.status_code"
     }
    }
   ]
  }
 },
 "aggs": {
  "response_code_ranges": {
   "range": {
    "field": "http.response.status_code",
    "keyed": true,
    "ranges": [
     {
      "key": "server_errors",
      "from": 500,
      "to": 599
     }
    ]
   }
  }
 }
}

Следующее условие триггерит наш наблюдатель и сообщит нашей команде, когда процент неудачных запросов превысит 0,3%. Вы можете настроить этот порог в соответствии с вашими соображениями:

"condition": {  
  "script": {  
    "source": "(double) ctx.payload.aggregations.response_code_ranges.buckets.server_errors.doc_count/(double) ctx.payload.hits.total > params.threshold",  
    "lang": "painless",  
    "params": {  
      "threshold": 0.003  
    }  
  }  
}

Мы можем информировать команду через slack:

-- copied from https://www.elastic.co/guide/en/elasticsearch/reference/7.17/actions-slack.html

"actions" : {  
  "notify-slack" : {  
    "transform" : { ... },  
    "throttle_period" : "5m",  
    "slack" : {  
      "message" : {  
        "to" : [ "#admins", "@chief-admin" ],   
        "text" : "..."   
      }  
    }  
  }  
}

Спасибо за внимание.

Ресурсы:

[1] filebeat-module-nginx.html
[2] watcher-ui.html
[3] watcher-api-put-watch.html


Материал подготовлен в преддверии старта курса «Observability: мониторинг, логирование, трейсинг». Ознакомиться подробнее с программой обучения и пройти вступительный тест для определения уровня знаний можно по ссылке.

Комментарии (1)


  1. FSA
    26.10.2022 19:31

    У меня нет каких-то серьёзных проектов. Так, несколько маленьких сайтов. Обычно логи из nginx кладу в journald и помечаю тегом с именем приложения. Точно также делаю в коде php. Если нужна какая-то отладочная информация, то тоже отправляю в syslog с тем же тегом. Как результат, легко посмотреть что происходит в приложении. Есть ошибки, тут же видно отладочные данные. В любой момент можно запустить journalctl -t app_name -f и посмотреть логи вместо того, чтобы писать длинный путь для tail -f... Да и вообще journald много чего позволяет делать.