ELK Stack для хранения логов Django приложения

от автора

Каждый из проектов, который перерастает этап прототипа, нуждается в организации логирования. Грамотное логирования решает уйму проблем и помогает понять состояние проекта. На начальном этапе логирование в файл меня устраивало пока проект не разросся и поиск по логам не начал отнимать время.

Решением было создание централизованного лог хранилища с агрегацией логов и поиском. Выбор пал на ELK стек. ELK — сочетание трех OpenSource проектов: ElasticSearch, Logstash и Kibana. ELK хранит логи, строит графики и есть поддержка полнотекстового поиска с фильтрами. В статье описывается процесс настройки ELK стека для хранения логов Django приложения.

Установка ELK

Для установки ELK стека будет использоваться Docker, за основу взят репозиторий docker-elk. Изменим настройку Logstash-а, добавим GROK паттерн для матчинга nginx логов и изменим output секцию, чтобы логи Django приложения и nginx логи сохранялись в разных индексах ElasticSearch-а. В итоге logstash.conf выглядит так:

input {     beats {     port => 5000     host => "0.0.0.0"   } } filter {    if [type] == "nginx" {      grok {         match => { "message" => "%{IPORHOST:remote_ip} - %{DATA:user_name} \[%{HTTPDATE:access_time}\] \"%{WORD:http_method} %{DATA:url} HTTP/%{NUMBER:http_version}\" %{NUMBER:response_code} %{NUMBER:body_sent_bytes} \"%{DATA:referrer}\" \"%{DATA:agent}\"" }       }    } } output {     if [type] == "nginx" {         elasticsearch {             hosts     => "elasticsearch:9200"             index    => "nginx-%{+YYYY.MM.dd}"         }     }     else if [type] == "django" {         elasticsearch {             hosts     => "elasticsearch:9200"             index    => "django-%{+YYYY.MM.dd}"         }     }     else {         elasticsearch {             hosts     => "elasticsearch:9200"             index    => "unknown_messages"         }     } }

После внесения изменений запускаем стек:

docker-compose up

После запуска стек слушает следующее порты:

  • 5000: Logstash TCP input.
  • 9200: Elasticsearch HTTP
  • 9300: Elasticsearch TCP transport
  • 5601: Kibana

Архитектура логирования

Рассмотрим архитектуру логирования Django приложения.

image

Как видно из схемы, приложение состоит из сервисов: nginx, django application, celery worker. Каждый из сервисов отправлял логи в ELK стек. Рассмотрим настройку каждого сервиса по отдельности.

Запись Nginx логов в ELK

Для работы с nginx логами потребуется дополнительный сервис Filebeat. Процесс установки Filebeat детально описан на официальном сайте. Пример установки Filebeat сервиса на Ubuntu сервер:

curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.4.0-amd64.deb sudo dpkg -i filebeat-6.4.0-amd64.deb

Filebeat будет читать логи из файла и отправлять в Logstash. Пример конфигурации:

filebeat.inputs: - type: log   enabled: true   paths:       - /var/log/nginx/access.log   fields:     type: nginx   fields_under_root: true   scan_frequency: 5s  output.logstash:   hosts: ["logstash:5000"]

Запускаем наш Filebeat сервис и наблюдаем за появлением логов в Kibana.

Запись Django логов в ELK

Для взаимодействия Django с сервисом Logstash установите дополнительный пакет Python-logstash.

pip install python-logstash

Изменим настройки Django приложения, чтобы логи отправлялись в Logstash сервис.

LOGGING = {   'version': 1,   'disable_existing_loggers': False,   'formatters': {       'simple': {             'format': 'velname)s %(message)s'         },   },   'handlers': {         'console': {             'level': 'INFO',             'class': 'logging.StreamHandler',             'formatter': 'simple'         },         'logstash': {             'level': 'INFO',             'class': 'logstash.TCPLogstashHandler',             'host': 'logstash',             'port': 5000,              'version': 1,             'message_type': 'django',  # 'type' поле для logstash сообщения.             'fqdn': False,             'tags': ['django'], # список тег.         },   },   'loggers': {         'django.request': {             'handlers': ['logstash'],             'level': 'INFO',             'propagate': True,         },         ...     } }

После этого приложение будет отправлять логи в Logstash. Пример использования:

import logging  logger = logging.getLogger(__name__)  def test_view(request, arg1, arg):     ...     if is_error:         # Отправляем лог сообщение         logger.error('Something went wrong!')

После этого настройте Kibana под себя, чтобы отображать необходимую информацию. Пример скриншотов собственной настройки:

image
image
image

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


ссылка на оригинал статьи https://habr.com/post/421819/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *