YALS (Yet Another Logging Stack) – еще один стек логирования

21 2

Периодически возникает потребность анализировать большие объемы логов в поисках чего-то интересного. Причем ситуация усложняется тем, что в руки разработчика может попасть набор логов сразу с нескольких серверов кластера и приходится собирать цепочку, которая, например прошла с клиента до Worker. В идеале хотелось бы делать всё это в одно действие, сразу по всем необходимым файлам. 

Ограничение – речь пойдёт про достаточно новые версии RX 4.*, поскольку идеально подходит для наших JSON логов.

Желаемый результат

  • простой метод сбора логов; 
  • расширенные возможности поиска;
  • индексация данных для быстрого поиска;
  • поддержка сразу нескольких проектов;
  • экономия ресурсов.

Предлагаемое решение

Используется стек от Grafana. На сервере устанавливается Promtail, который будет перехватывать изменения в логах и отправлять в БД Loki. Grafana уже предоставляет доступ к данным, позволяет писать запросы и получать данные.

  1. Сбор логов с сервера / клиента – Promtail
  2. БД и запросы – Loki
  3. Интерфейс взаимодействия с пользователем – Grafana

Приятная особенность– весь набор приложений отлично работает как под Windows, так и под Linux.

Суммарное потребление ресурсов:

Процесс

Рабочий набор (память)

Место на диске

promtail-windows-amd64.exe

45М

80М

loki-windows-amd64.exe

100М

60М
+ данные БД

grafana-server.exe

50М

230М

ИТОГО

~200М RAM

~ 1Г HDD/SSD

Для оптимизации накладных расходов на стенд (DEV / TEST) достаточно установить Promtail, который будет отправлять логи на единый сервер Loki (например на машине разработчика), Grafana так же установлена в одном экземпляре:

 
А можно на каждом стенде размещать полный комплект, это уже зависит от привычек и удобства. 

Настройка

  1. Скачиваем с https://github.com/grafana/loki/releases файлы loki-windows-amd64.exe.zip, promtail-windows-amd64.exe.zip (в случае с Linux смотрите документацию на сайте).

  2. Скачиваем с https://grafana.com/grafana/download?platform=windows , Edition – OSS, Standalone Windows Binaries, файл .zip

Распаковать всё в каталог С:\LOKI. Итоговый результат после всех настроек будет выглядеть так:

 
Loki

Документация: https://grafana.com/docs/loki/latest/

Пример конфига: https://raw.githubusercontent.com/grafana/loki/main/cmd/loki/loki-local-config.yaml 

Требуется создать конфиг-файл C:\LOKI\loki-config.yaml:

auth_enabled: false

server:
    http_listen_port: 3100
    grpc_listen_port: 9096

schema_config:
  configs:
    - from: 2021-08-01
      store: tsdb
      object_store: filesystem
      schema: v12
      index:
        prefix: index_
        period: 24h

limits_config:
    enforce_metric_name: false
    reject_old_samples: true
    reject_old_samples_max_age: 30d
    max_query_length: 0h
    max_query_parallelism: 32
    ingestion_rate_strategy: local
    ingestion_rate_mb: 1000
    ingestion_burst_size_mb: 1000
    max_streams_per_user: 0
    max_global_streams_per_user: 0

querier:
    max_concurrent: 2048

frontend:
  max_outstanding_per_tenant: 4096
  compress_responses: true

common:
  instance_addr: 127.0.0.1
  path_prefix: c:\loki\db
  storage:
    filesystem:
      chunks_directory: c:\loki\db\chunks
      rules_directory: c:\loki\db\rules
  replication_factor: 1
  ring:
    kvstore:
      store: inmemory

query_range:
  split_queries_by_interval: 0
  parallelise_shardable_queries: false
  results_cache:
    cache:
      embedded_cache:
        enabled: true
        max_size_mb: 1000

ruler:
  alertmanager_url: http://localhost:9093

analytics:
  reporting_enabled: false

Что здесь настроено: 
•    авторизации нет – локальное использование, не production
•    путь до файлов БД - path_prefix: С:\LOKI\db
•    блок limits_config – подобранный за время использования набор настроек, которые снимают ограничения при импорте больших пачек логов и для больших аналитических запросов, более подробно читайте в документации. 
•    Записи старше 30 дней отбрасываются (reject_old_samples_max_age)

Команда запуска для командной строки (абсолютные пути, чтобы запускать откуда угодно):
C:\LOKI\loki-windows-amd64.exe --config.file=c:\LOKI\loki-config.yaml

Promtail

Документация: https://grafana.com/docs/loki/latest/send-data/promtail/ 
Пример конфига: https://github.com/grafana/loki/blob/main/clients/cmd/promtail/promtail-local-config.yaml 
Требуется создать конфиг-файл C:\LOKI\promtail-config.yaml:

server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: C:\LOKI\promtail-positions.yaml

clients:
  - url: http://127.0.0.1:3100/loki/api/v1/push

scrape_configs:
- job_name: system
  static_configs:
  - targets:
      - localhost
    labels:
      job: rx/DEMO
      __path__: c:\inetpub\logs\*\*.log

  pipeline_stages:
  - json:
      expressions:
        logger: lg
        level: l
        msg: mt
        pid: pid
        timestamp: t
  - labels:
      logger:
      level:

  - timestamp:
      source: timestamp
      format: "2006-01-02 15:04:05.999-07:00"

На что обратить внимание: 
•    filename: C:\LOKI\promtail-positions.yaml – путь до файла, где хранится текущая позиция отслеживания по логам, если его удалить – логи будут перечитываться с нуля.
•    url: http://127.0.0.1:3100/loki/api/v1/push - путь до сервера Loki, если он вынесен на компьютер разработчика – поменять на его IP адрес, убедиться, что брандмауэр разрешает внешние подключения на 3100 порт.
•    job: rx/DEMO – метка, по которой можно различать стенды и проекты, для каждого экземпляра нужно прописать свою, чтобы можно было искать только в рамках проекта.
•    Путь до логов: __path__ – пути до логов, в 4.2+ они по умолчанию складываются уже в один каталог, в примере указан поиск для двухуровневого хранения логов, если смотреть для новых версий по умолчанию, то параметр будет выглядеть так: __path__: C:\Storage\logs\*.log .
•    блок pipeline_stages - реализует первичное извлечение необходимых данных
•    блок expressions – из лога извлекаются поля для укрупнённой фильтрации и называются более удобными именами
•    блок labels -дополнительные названия потоков для использования в конструкторе запроса. По ним строится первичный индекс, рекомендуется не увлекаться с их количеством
•    format: "2006-01-02 15:04:05.999-07:00" – шаблон метки времени, анализируется время лога их файла и отправляется на сервер Loki в качестве метки времени (если этого не указать, меткой времени считается время поступления строки), очень удобно если требуется подгрузить для анализа исторические данные. Встречал вариант, когда время в логе было без часового пояса, в этом случае потребуется использовать format: "2006-01-02 15:04:05.999"
Формат этой строки использует строку формата из GO, все значения в строке не случайны. Допустимые значения: https://go.dev/src/time/format.go   

Команда запуска (абсолютные пути, чтобы запускать откуда угодно):
C:\LOKI\promtail-windows-amd64.exe --config.file=c:\LOKI\promtail-config.yaml

Grafana

Дополнительные настройки не требуются. После скачивания переименовать подкаталог в Grafana, чтобы не зависеть от версии.
Запускать - c:\LOKI\Grafana\bin\grafana-server.exe
При входе в первый раз потребуется предварительная настройка:
1.    Зайти в Grafana: http://localhost:3000, вход – admin:admin, сразу предложит сменить пароль
2.    Раздел Home -> Connections -> Data sources / Add data source. Выбрать Loki, указать URL: http://localhost:3100, Save & test

Запускаем всё сразу

Создаём в каталоге командный файл start_all.cmd, чтобы запускать всё в один заход:

start C:\LOKI\loki-windows-amd64.exe --config.file=c:\LOKI\loki-config.yaml
start C:\LOKI\promtail-windows-amd64.exe --config.file=c:\LOKI\promtail-config.yaml
cd C:\LOKI\grafana\bin
grafana-server.exe 

Как использовать

Работа с данными производится в разделе Home / Explore (аналог Discovery в Kibana). 

Интерфейс выглядит следующим образом:

  1. Конструктор запроса, можно справа переключить из режима «Builder» в режим написания кода «Code». Полученный в ходе конструирования запрос пишется в низу блока.
  2. Период, чаще всего требуются только недавние логи.
  3. Запуск запроса.
  4. Позволяет смотреть в реальном времени логи по введённому фильтру. Значимой задержки заметить не удалось, это действительно реальное время.
  5. Сводная диаграмма по найденным данным за период.
  6. Собственно сами строки логов.

Еще есть удобный режим для просмотра Stacktrace.  Требуется включить Prettify JSON, Escape newlines:
 

В итоге большие длинные строки корректно отформатируются:
 

 

Также здесь довольно удобный язык запросов. В последних версиях Grafana добавился построитель выражений, чаще всего хватает его. Обычное использование - в grep стиле собирается цепочка фильтров и немного форматируется вывод. 

Примеры: 

  1. Интересно, что за ошибки происходили в пределах процесса: "pid":"5668+84"
    {job="rx/DEV1-AVP",level="Error"} |="5668+84"

     

  2. Можно собрать цепочку из уточняющих фильтров:

    {job="rx/DEV1-AVP"} |="durationMs" |="LogService"

     

  3. Можно обработать строку как JSON и использовать данные для вычислений:

    {job="rx/DEV1-AVP"} |="durationMs" |="LogService"| json duration="span.durationMs" | duration > 0

    1.    Парсим строку как JSON
    2.    В переменную duration помещаем значение из полученного результата
    3.    Полученную переменную используем в условии фильтрации

  4. Можно отформатировать строку, чтобы там были только нужные поля:

    {level="Debug"} |json | line_format "{{ .mt }}" |="AutoRegistration"

     

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

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

Подробнее по языку запросов можно посмотреть у авторов: https://grafana.com/docs/loki/latest/logql/log_queries/ 

Бонус: настраиваем автозапуск (после успешной проверки конфигов и работы)

NSSM обеспечивает автозапуск приложений как службы в Windows и логирование stdOut, stdErr в файлы.

Потребуется скачать nssm.exe в c:\LOKI\nssm.exe и в cmd.exe с правами администратора запустить создание трёх служб:

nssm install _GRAFANA c:\LOKI\Grafana\bin\grafana-server.exe
nssm install _LOKI c:\LOKI\loki-windows-amd64.exe --config.file=C:\LOKI\loki-config.yaml
nssm install _PROMTAIL c:\LOKI\promtail-windows-amd64.exe --config.file=C:\LOKI\promtail-config.yaml

 

Альтернативы

  1. Решение «Мониторинг для Directum RX» – построено на базе стека FileBeat / LogStach / Elasticsearch / Kibana + Grafana. Решение доступно партнёрам Директум и (прошу меня поправить, если я не прав) клиентам Директум с действующей подпиской. 
    Преимущества: команда, писавшая скрипты LogStash позволяет извлекать все необходимые факты, есть дашборды на все случаи жизни, а если зайти в Кибану на порт 5601 (для меня это было новостью), то можно писать любые поисковые запросы и получать любую статистику. Актуальные версии поднимаются в докере.
    Недостатки: ElasticSearch либо требует много оперативной памяти (немного лечится параметром ES_JAVA_OPTS=-Xms1g -Xmx1g в docker-compose.yml), либо работает не очень быстро. Плюс в последнее время приходится скачивать FileBeat через VPN.
  2. Directum LogViewer – специализированное решение именно для просмотра логов DirectumRX.
    Преимущества: самодостаточный бинарник на .Net, сам умеет следить за изменениями в каталоге с файлами логов, показывает системные уведомления в трэй о появлении ошибок. В последнее время использую в части анализа логов  вместо Notepad++.
    Недостатки: не выводит некоторые полезные поля, в случае больших файлов грузит их довольно медленно в память и смотреть можно данные только в пределах одного файла.
  3. Набор из Linux утилит - cat | tail | grep | sed | tee | awk | jq |sort | uniq | wc, который как отличный швейцарский нож облегчает жизнь абсолютно во всём. Об этом по соседству есть отдельная статья коллеги
    Преимущества: с его помощью можно получить абсолютно любую информацию из любого количества логов.
    Недостатки: не все любят и умеют пользоваться командной строкой, достаточно сложный анализ заставляет писать реально длинные команды.

Но у всего вышеперечисленного есть «фатальный недостаток» (с). Это делал не я :)

Итого

Получается довольно лёгкий и быстрый аналог большому и толстому ELK стеку. Для анализа гигабайтов логов служит лучше, чем linux консоль, поскольку умеет индексировать данные, позволяет сохранять запросы, можно легко переформатировать вывод и выводить только нужные поля по достаточно сложным условиям. 

Преимущества:

  • Экономный (кушает заметно меньше ресурсов).
  • Гибкий язык запросов.
  • Под капотом полноценная БД, так что запросы отрабатывают заметно быстрее, чем grep.

Недостатки:

  • Скудная документация.
  • Язык запросов довольно специфичен.
  • Иногда упираемся в ограничения Loki.
21
Авторизуйтесь, чтобы оценить материал.
2
Дмитрий Зайцев

На поодакшен пробовали использовать данный вариант? Насколько удобно в работе использовать данный инструмент?

Алексей Присяжный

Дмитрий, На проде обычно хватает места на полноценный ElasticSearch и сервер мониторинга. В моём случае скорей быстрая замена для grep с заранее сохранёнными запросами, для девстенда - чудесно.

Всё же магию, которую делает LogStash с логами - тут повторить крайне сложно

Авторизуйтесь, чтобы написать комментарий