Русский
Русский
English
Статистика
Реклама

Logs

Перевод Вышел Loki 2.0

04.11.2020 12:10:51 | Автор: admin


Преобразовывайте свои журналы прямо во время запроса, настраивайте уведомления с Loki.


Прошел примерно год после выпуска Loki 1.0, мы за это время заметили большой всплеск внедрений в компаниях (например, Grofers и Paytm Insider), использующих как облачную версию Grafana, так и размещенную на своих мощностях. В то же время мы приложили много усилий для улучшения производительности, используя оптимизацию и распараллеливание запросов. В последнем выпуске 1.6.0 мы продолжили рефакторинг кода для достижения еще большей производительности, а также добавили небольшие новые функции к языку запросов, например, бинарные операции.


Эксплуатационные выгоды использования маленького индекса Loki были огромными. Любой, кто использовал Loki, быстро почувствовал эти дополнительные преимущества. Однако небольшой индекс и небольшой набор меток, критически важных для производительности Loki, накладывают ограничения на возможности запросов, а нам такое не нравится.


Это и есть причина, по которой мы решили значительно улучшить Loki, поэтому рады представить Loki 2.0. В этой версии мы добавили новейший набор функций языка запросов, позволяющий извлекать метки во время запроса, убирая старые ограничения.


Теперь у вас есть лучшее из обоих подходов: небольшой набор меток для индексирования журналов во время сбора, соединенный с комплексным языком запросов, позволяющим извлекать больше меток во время запроса и ограничивать способности запросов только вашим воображением!


Давайте посмотрим детальнее на новые функции!


Извлечение меток из строк журналов во время запроса


Давайте посмотрим на новые дополнения к языку запросов в версии 2.0!



С оранжевыми пунктами вы уже должны быть знакомы. Выборка содержимого журнала с помощью |= != |~ и !~, а также преобразование ваших журналов в параметры с использованием rate и count_over_time уже работали в Loki 1.x. Все остальное, выделенное белым цветом новое в версии 2.0, мне кажется, что будет лучше рассмотреть, как оно работает детальнее на примерах, так что погнали!


Разбор


Это начальная точка: мы извлекаем метки во время запроса. Например, у нас есть поставщик журнала:



Посмотрите, какие метки были возвращены:



Давайте немножко поменяем запрос и посмотрим на результат, возвращаемый по этому журналу:



Обратите внимание на метки...



Вот так вот просто каждая пара ключ=значение из logfmt стала меткой!


Не используете logfmt? Тогда мы идем к вам!


Регулярное выражение:



JSON:



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

Это покрывает первый этап, извлечение содержимого журнала в метки во время запроса. Давайте посмотрим, что это нам дает.


Выборка


В Loki 2.0 доступны более мощные возможности выборки. Используя расширенные существующие выражения для выборки, вы теперь можете отсеять данные, полученные на предыдущем этапе разбора. Давайте посмотрим на пример, показывающий только те строки журнала, где извлеченный параметр duration больше 1 секунды с помощью query_type=filter:



Обратите внимание на умную обработку Loki выходных типов в некоторых контекстах, в этом случае идет разбор duration в стиле Golang.


Выборка является важной частью обработки ошибок в новых функциях. Если что-то пошло не так с обработкой строки, Loki назначит новую метку __error__ с именем ошибки. Это можно использовать для выбора журналов и анализа причин:



В вышеприведенном случае такие строки не JSON, так что они не были обработаны как JSON на этапе json. Теперь, когда вы узнали причину, можно легко и непринужденно исключить такие строки:



Форматирование


Упростить работу всем, кто смотрит журналы, стало еще легче. Loki 2.0 может перезаписать ваши строки журнала так, как они показаны, а также с его помощью можно сделать так:



Превращаем в такое:



Метки label_format и line_format используют синтаксис шаблонов Golang, позволяя вам выбрать связанные строки журнала для отображения. С этим также связаны другие дополнительные возможности, например, способность вертикального выравнивания или обрезания содержимого журнала.


Графики


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


  • sum_over_time
  • avg_over_time
  • stddev_over_time
  • stdvar_over_time
  • max_over_time
  • min_over_time
  • quantile_over_time

Давайте рассмотрим пример использования, чтобы отобразить 99 перцентиль параметра request_time из журналов NGINX, сгруппированных по целевому серверу:



А теперь берем тот же запрос и группируем по клиентскому IP:



Как вы видите, появилось что-то новое и восхитительное: способность группировать данные с большой мощностью.


Еще пара примеров:




В последнем примере вы можете видеть такое: duration(duration). Так можно указать Loki разбирать значения duration в стиле Golang (там добавляются единицы, например s или ms). Скоро будет доступна поддержка и других дополнительных типов, например kb, mb и прочих.


Создание уведомлений из любого запроса


Все эти новые функции очень впечатляют, особенно, если они используются совместно с еще одним большим улучшением в 2.0: возможностью создания уведомлений прямиком из ваших журналов в Loki и их отправки в Prometheus Alertmanager.



Ранее для такого вам надо было настроить Loki в качестве источника данных для Prometheus, после чего указать Grafana использовать его для создания уведомлений. В Loki 2.0 мы внедрили распределенный механизм оценки правил, так что вы можете написать любой запрос и создать уведомление с использованием знакомого синтаксиса Prometheus. Эти уведомления потом отправляются в Prometheus Alertmanager, развернутый отдельно. Процесс создания и отправки уведомлений стал простым!



Удалено отдельное хранилище индексов


И последняя впечатляющая новость о Loki 2.0 удаление пометки "экспериментальный" с типа индекса boltdb-shipper!



В Loki 1.5 мы представили новый индекс boltdb-shipper. С новым индексом вы могли запустить Loki поверх любого объектного хранилища, а сейчас вам уже больше не нужно отдельное выделенное хранилище (DynamoDB, Bigtable, Cassandra и другие), а также все дополнительные, связанные с ним, затраты! В 2.0 эта функция готова к промышленному использованию. В Grafana Labs мы для себя уже переместили в этом направлении все наши кластера.


Дополнительная информация


Нет возможности запустить свой Loki, либо просто хотите попробовать все это в действии? Активируйте испытательный период в 30 дней в Grafana Cloud! В облаке вы получите экземпляр Loki, связанный с Grafana и Alertmanager с новым интерфейсом правил уведомлений, с которым вы легко запустите процесс сбора журналов и создания уведомлений за несколько минут!


Для начала работы обратитесь к странице выпуска, также есть исчерпывающее руководство для обновления вашего кластера Loki. Там есть несколько вещей, на которые стоит обратить внимание!


А еще у нас есть шикарнейшее видео от Ward Bekker с исследованием и обзором новых функций в 2.0.



От редакции: Подробнее о работе с Loki можно узнать на курсе Слёрма Мониторинг и логирование инфраструктуры в Kubernetes. Курс от основ до продвинутого уровня для быстрого ввода в эксплуатацию мониторинга и логирования инфраструктуры.

Подробнее..

Обновления в Chipmunk

01.09.2020 18:20:28 | Автор: admin
Рад представить Вашему вниманию некоторые обновления смотрелки для логов chipmunk. Где-то стало удобнее, где-то практичнее, но обо всем по порядку Под катом будет коротко, но интересно.



Это вообще о чем?
Это о программе chipmunk, позволяющей открывать файлы любых размеров и быстро по ним искать. Можно сохранять свои фильтры, можно стоить графики, мерить время и много чего другого, что не будет лишним при анализе логов. Здесь больше.


Мерить время стало удобнее. Теперь вы можете определить пару фильтров, первый из которых будет началом временного отрезка, а последний его окончанием. На основании этих данных chipmunk построит график продолжительности.

image

Вы можете и не ограничиваться определением точек начала и конца временного отрезка, но и определить промежуточные. В этом случае, как результат, вы получите stacked bar. Такие графики по умолчанию строятся в строгом режиме, то есть подразумевается, что определенный вами паттерн должен полностью совпасть (все вхождения должны быть в том порядке, в котором вы их определили, без пропусков), однако это можно отключить и тогда chipmunk будет проверять лишь начало и конец временного отрезка.

В целом менеджер поисковых запросов был переработан. Кроме всего прочего, появилась возможность отключить фильтр. Это весьма удобно, если вы не хотите удалять фильтр, но подсветку желали бы отключить.

image

Естественно, chipmunk запомнит, что именно было отключено (фильтр, определение для графика или же временной отрезок) и при восстановлении вернет, где лежало.

Была доработана и панель Time measurement. Из важного стоит отметить тот факт, что chipmunk будет помнить все успешно применённые форматы даты-времени, что позволит вам легко их добавить (восстановить), если формат не был определен автоматически.

image

И уже по традиции (а третий раз это почти традиция) прошу вас поддержать проект лишь кликнув на звездочку на github. Для вас это дело 2-4 секунд, а для нас важная и ценная обратная связь. OpenSource нуждается в вашей поддержке.

Скачать без СМС и регистрации можно здесь :)

Спасибо.
Подробнее..

Обновления в смотрелке логов

09.11.2020 04:11:53 | Автор: admin
Хотел бы поделиться с Вами рядом обновлений смотрелки для логов chipmunk. Описание займет не больше 2-х минут Вашего времени, но меж тем новые возможности могут оказаться весьма полезным подспорьем в Вашей повседневной работе.

Это вообще о чем?
Это о программе chipmunk, позволяющей открывать файлы любых размеров и быстро по ним искать. Можно сохранять свои фильтры, можно стоить графики, мерить время и много чего другого, что не будет лишним при анализе логов. Здесь больше.

Chipmunk наконец-то научился сохранять ваши сессии. Иными словами, все что Вы сделали с тем или иным файлом, будет автоматически восстановлено при его (файла) повторном открытии:

  • Фильтры;
  • Фильтры для графиков;
  • Фильтры для анализа времени;
  • Комментарии.

image

Chipmunk в том же месте, где расположен файл с логами создаст файл сессии с незатейливым разрешением .chip. Это дает Вам возможность полностью воспроизвести Ваш анализ логов на любом другом компьютере. Все что нужно скинуть .chip файл вместе с логами, например, Вашему коллеге.

Теперь Вы можете оставлять комментарии непосредственно в логах: выделяем фрагмент; вызываем контекстное меню; и добавляем комментарий.

image

Комментарии могут быть отнесены к той или иной категории. Дабы быть максимально нейтральными мы решили не использовать такие понятия как: error, warning etc., а просто группировать по цветам. Какой цвет и что будет означать дело исключительно Вашего вкуса.

Комментарии являются частью сессии, поэтому они будут сохраняться в файл .chip. И, как было сказано выше, поделившись данным файлом с Вашим коллегой, Вы поделитесь и своими комментариями к логам.

Очень надеюсь, Вы найдете данные обновления полезными. Я же в свою очередь обязуюсь и впредь держать Вас в курсе развития проекта, которое, к слову, невозможно без Вашей поддержки, особенно в это странное время. Поэтому Ваши звездочки на github невероятно ценны и дороги, а я же вновь Вас призываю поддержать проект одним лишь кликом.

Прикоснуться к open source можно тут

P.S.
Мы получили ряд feature requests, касающихся измерения времени. Что-то пришло в комментариях к предыдущим постам, что-то прилетело на github. Спешу Вас заверить, что ничто не остается без внимания, но в силу несколько ограниченных ресурсов, реализуется не сразу. В настоящее время мы активно работаем над существенной оптимизаций производительности.
Подробнее..

Легкие обновления

31.12.2020 14:09:18 | Автор: admin
Напоследок немного новостей о смотрелке для логов chipmunk. Ничего особенного, никаких кардинальных изменений или же заметных фитч, а скорее работа над ошибками, да и просто хочется сказать пару слов о прошедшем, настоящем и будущем.


Это вообще о чем?
Это о программе chipmunk, позволяющей открывать файлы любых размеров и быстро по ним искать. Можно сохранять свои фильтры, можно стоить графики, мерить время и много чего другого, что не будет лишним при анализе логов. Здесь больше.


Итак, вышел релиз 2.10.2, содержащий исправления ряда ошибок. Полный список исправлений есть на github, здесь же ограничусь наиболее весомым: починили возможность определения собственного формата даты-времени при совмещении нескольких файлов (речь о функции Merge).

image

В целом часть времени стараемся тратить на наведение порядка и вылов всевозможных багов, однако основные ресурсы направлены на переезд движка на rust рельсы (речь о всех IO операциях, поиске, вычислениях и всем прочим, что должно летать, а не ездить), а также на проработку сетевых функций.

В любом случае, этого всего не могло случится без Вас. Именно благодаря Вашему вниманию к этому инструменту; Вашим сообщениям об ошибках, что мне в личку, что на github; Вашим предложениям по новым функциям и доработкам существующих; благодаря этому всему мы и движемся; движемся, покуда есть Ваш отклик.

Конечно, не всегда получается реализовать всё то что задумано и как оно задумано было. Не всегда получается и оперативно отреагировать на Ваши пожелания, но мы стараемся и будем стараться и впредь. В то время как найти стоящие инструменты на бесплатной основнее становится сложнее, а тот же youtube смотреть уже просто невозможно с их вставками рекламы на каждые 3-5 минут, мы верим, что слова community и open source что-то да и значат. Такой путь мы выбрали и сворачивать не собираемся.

Спасибо! И с наступающим Новым Годом!

Скачать без SMS и регистрации :) можно тут


P.S.
Вся наша скромная команда будет рада Вашим поздравлениям в виде новогодних звёзд на github. Для Вас лишь, клик для нас обратная связь и энергия! По-моему это здорово, когда одним кликом, можно поддержать разработчиков и их усилия.
Подробнее..

Chipmunk обновления

09.04.2021 10:09:31 | Автор: admin

Короткий обзор очередных обновлений смотрелки логов chipmunk. Много исправлений, много корректировок и немного фишек, в том числе запрашиваемых сообществом.


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

О чём это вообще?

Это о программе chipmunk, позволяющей открывать файлы любых размеров и быстро по ним искать. Можно сохранять свои фильтры, можно стоить графики, мерить время и много чего другого, что не будет лишним при анализе логов. Здесь больше.

В деталях

Появилось новое приложение для боковой панели Shell. Фактически это простая запускалка консольных команд. Работает крайне просто вбиваем команду смотрим вывод. Таким образом вы можете проанализировать в chipmunk вывод от любой интересующей вас команды, будь то adb logcat, journalctl или tail.

Приложение боковой панели - ShellПриложение боковой панели - Shell

Кстати о последнем, мы получали от сообщества вопросы о поддержке обновления открытого файла и это будет реализовано в версии 3.0 вместе с миграцией всего ядра на rust. Однако, уже сейчас вы можете просто запустить команду tail -f name_of_live_logfile и получать живой вывод. Естественно, если при этом у вас будет активный поиск, то и результаты его будут обновляться автоматически.

Кроме того, Shell позволяет редактировать переменные окружения. Вы можете изменить или добавить переменные, сохранить всё в ваш профайл и после просто его выбрать. Может быть весьма удобно, если какая-то из ваших консольных программ берёт данные из окружения.

Блиц

  • DLT коннектор теперь понимает и UDP, и TCP, и IPv4 и IPv6. Последние не требуют каких-либо галочек и переключателей, тип адреса будет определён автоматически. Также можно подключиться к нескольким multicast точкам.

  • Исправили рендер графиков. Теперь все отрисовывается корректно и при изменении размеров окна, и при переключении между сессиями.

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

  • Научили chipmunk обновляться через прокси (соответствующие настройки можно найти в меню Settings/General/Network

  • Добавили поддержку копирования и экспорта результатов поиска.

Пожалуй это самое важное. Я не рискну сейчас анонсировать точные сроки по версии 3.0 с ядром на rust, скажу лишь то, что мы рассчитываем на этот год. И это будет легче достигнуть с Вашей поддержкой ведь каждая новая звёздочка на github это не только ценная обратная связь, но и наша ответственность перед Вами!

Скачать без рекламы и регистрации )

Спасибо. Тепла, добра и света!

Подробнее..

Провайдер логирования для Telegram (.NET 5 .NET Core)

27.01.2021 18:04:51 | Автор: admin

Не секрет, что Telegram является на данный момент одним из самых популярных мессенджеров. Особенно в среде ИТ-специалистов. Он удобен, в нем нет встроенной рекламы и работает весьма стабильно. Довольно большую часть времени я общаюсь как по работе, так и по личным вопросам именно в этом мессенджере. Поэтому в один прекрасный день я подумал о том, что было бы удобно, чтобы в этом же мессенджере я мог получать уведомления о работе некоторых своих сервисов. На тот момент я как раз активно работал над интеграцией проекта //devdigest и Telegram, поэтому используя тот же родной Telegram Bot SDK довольно быстро реализовал логгер.

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

Вот в таком виде приходят логи в телеграмм из одного из проектов, которыми я занимаюсьВот в таком виде приходят логи в телеграмм из одного из проектов, которыми я занимаюсь

Подготовка

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

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

Дале нужно получить идентификатор канала. Для публичных каналов все просто - в качестве идентификатора мы можем использовать имя канала. Для приватных каналов все чуть-чуть сложнее.

Получение идентификатора приватного канала.

Чтобы получить идентификатор приватного канала придется воспользоваться помощью еще одного бота @JsonDumpBot. Вам нужно будет любое сообщение из этого канала переслать в этот бот. В ответ вы получите сообщение примерно такого вида:

{  "update_id": 111001100,  "message": {    "message_id": 123456,    "from": {      "id": 12345678,      "is_bot": false,      "first_name": "FirstName",      "username": "username",      "language_code": "en"    },    "chat": {      "id": 123456,      "first_name": "FirstName",      "username": "username",      "type": "private"    },    "date": 1111111111,    "forward_from_chat": {      "id": -1123456789101,      "title": "torf.tv logs",      "type": "channel"    },    "forward_from_message_id": 1,    "forward_date": 1111111111,    "text": "test"  }}

Идентификатор канала находится в блоке forward_from_chat -> id

Теперь, имея идентификатор чата и токен бота мы можем перейти к настройке логгера.

Настройка логгера

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

  • AccessToken токен бота;

  • ChatId идентификатор канала (приватного, или публичного), или чата, куда бот будет отправлять сообщения;

  • LogLevel минимальный уровень сообщений, которые будут отправляться в канала. Обычно я в канал отправляю сообщения начиная с уровня Warning, или Error;

  • Source удобочитаемое название сервиса. Полезно, если в один канал приходят сообщения из нескольких сервисов;

Существует несколько вариантов конфигурации логгера непосредственно через код, или через файл кофигурации.

Настройка логгера в коде

Для начала нужно создать и инициализировать экземпляр класса TelegramLoggerOptions.

var options = new TelegramLoggerOptions{    AccessToken = "1234567890:AAAaaAAaa_AaAAaa-AAaAAAaAAaAaAaAAAA",    ChatId = "-0000000000000",    LogLevel = LogLevel.Information,    Source = "Human Readable Project Name"};

Зачем передать этот объект в метод-расширение AddTelegram():

builder  .ClearProviders()  .AddTelegram(options)  .AddConsole();

Пример такой конфигурации можно посмотреть здесь.

Настройка логгера через файл конфигурации appconfig.json

Также блоггер можно настраивать через файл конфигурации приложения, как это показано ниже:

{  "Logging": {    "LogLevel": {      "Default": "Information",      "Microsoft": "Warning",      "Microsoft.Hosting.Lifetime": "Information"    },    "Telegram": {      "LogLevel": "Warning",      "AccessToken": "1234567890:AAAaaAAaa_AaAAaa-AAaAAAaAAaAaAaAAAA",      "ChatId": "@channel_name",      "Source": "Human Readable Project Name"    }  },  "AllowedHosts": "*"}

Далее, в метод-расширение AddTelegram() необходимо передать экземпляр IConfiguration,

public static IHostBuilder CreateHostBuilder(string[] args) =>    Host.CreateDefaultBuilder(args)        .ConfigureLogging((context, builder) =>        {            if (context.Configuration != null)                builder                    .AddTelegram(context.Configuration)                    .AddConsole();        })        .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<startup>(); });

Пример находится здесь

Установка

Установить логгер можно из NuGet, или же интегрировать код прямо к себе в проект. Библиотека распространяется под лицензией MIT.

Подробнее..

Собираем логи с Loki

25.06.2020 16:23:50 | Автор: admin


Мы в Badoo постоянно мониторим свежие технологии и оцениваем, стоит ли использовать их в нашей системе. Одним из таких исследований и хотим поделиться с сообществом. Оно посвящено Loki системе агрегирования логов.


Loki это решение для хранения и просмотра логов, также этот стек предоставляет гибкую систему для их анализа и отправки данных в Prometheus. В мае вышло очередное обновление, которое активно продвигают создатели. Нас заинтересовало, что умеет Loki, какие возможности предоставляет и в какой степени может выступать в качестве альтернативы ELK стека, который мы используем сейчас.


Что такое Loki


Grafana Loki это набор компонентов для полноценной системы работы с логами. В отличие от других подобных систем Loki основан на идее индексировать только метаданные логов labels (так же, как и в Prometheus), a сами логи сжимать рядом в отдельные чанки.


Домашняя страница, GitHub


Прежде чем перейти к описанию того, что можно делать при помощи Loki, хочу пояснить, что подразумевается под идеей индексировать только метаданные. Сравним подход Loki и подход к индексированию в традиционных решениях, таких как Elasticsearch, на примере строки из лога nginx:


172.19.0.4 - - [01/Jun/2020:12:05:03 +0000] "GET /purchase?user_id=75146478&amp;item_id=34234 HTTP/1.1" 500 8102 "-" "Stub_Bot/3.0" "0.001"

Традиционные системы парсят строку целиком, включая поля с большим количеством уникальных значений user_id и item_id, и сохраняют всё в большие индексы. Преимуществом данного подхода является то, что можно выполнять сложные запросы быстро, так как почти все данные в индексе. Но за это приходится платить тем, что индекс становится большим, что выливается в требования к памяти. В итоге полнотекстовый индекс логов сопоставим по размеру с самими логами. Для того чтобы по нему быстро искать, индекс должен быть загружен в память. И чем больше логов, тем быстрее индекс увеличивается и тем больше памяти он потребляет.


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


Этот компромисс между большим быстрым индексом и маленьким индексом с параллельным полным перебором позволяет Loki контролировать стоимость системы. Её можно гибко настраивать и расширять в соответствии с потребностями.


Loki-стек состоит из трёх компонентов: Promtail, Loki, Grafana. Promtail собирает логи, обрабатывает их и отправляет в Loki. Loki их хранит. А Grafana умеет запрашивать данные из Loki и показывать их. Вообще Loki можно использовать не только для хранения логов и поиска по ним. Весь стек даёт большие возможности по обработке и анализу поступающих данных, используя Prometheus way.
Описание процесса установки можно найти здесь.


Поиск по логам


Искать по логам можно в специальном интерфейсе Grafana Explorer. Для запросов используется язык LogQL, очень похожий на PromQL, использующийся в Prometheus. В принципе, его можно рассматривать как распределённый grep.


Интерфейс поиска выглядит так:



Сам запрос состоит из двух частей: selector и filter. Selector это поиск по индексированным метаданным (лейблам), которые присвоены логам, а filter поисковая строка или регэксп, с помощью которого отфильтровываются записи, определённые селектором. В приведенном примере: В фигурных скобках селектор, все что после фильтр.


{image_name="nginx.promtail.test"} |= "index"

Из-за принципа работы Loki нельзя делать запросы без селектора, но лейблы можно делать сколь угодно общими.


Селектор это key-value значения в фигурных скобках. Можно комбинировать селекторы и задавать разные условия поиска, используя операторы =, != или регулярные выражения:


{instance=~"kafka-[23]",name!="kafka-dev"} // Найдёт логи с лейблом instance, имеющие значение kafka-2, kafka-3, и исключит dev 

Фильтр это текст или регэксп, который отфильтрует все данные, полученные селектором.


Есть возможность получения ad-hoc-графиков по полученным данным в режиме metrics. Например, можно узнать частоту появления в логах nginx записи, содержащей строку index:



Полное описание возможностей можно найти в документации LogQL.


Парсинг логов


Есть несколько способов собрать логи:


  • С помощью Promtail, стандартного компонента стека для сбора логов.
  • Напрямую с докер-контейнера при помощи Loki Docker Logging Driver.
  • Использовать Fluentd или Fluent Bit, которые умеют отправлять данные в Loki. В отличие от Promtail они имеют готовые парсеры практически для любого вида лога и справляются в том числе с multiline-логами.

Обычно для парсинга используют Promtail. Он делает три вещи:


  • Находит источники данных.
  • Прикрепляет к ним лейблы.
  • Отправляет данные в Loki.

В настоящий момент Promtail может читать логи с локальных файлов и с systemd journal. Он должен быть установлен на каждую машину, с которой собираются логи.


Есть интеграция с Kubernetes: Promtail автоматически через Kubernetes REST API узнаёт состояние кластера и собирает логи с ноды, сервиса или пода, сразу развешивая лейблы на основе метаданных из Kubernetes (имя пода, имя файла и т. д.).


Также можно развешивать лейблы на основе данных из лога при помощи Pipeline. Pipeline Promtail может состоять из четырёх типов стадий. Более подробно в официальной документации, тут же отмечу некоторые нюансы.


  1. Parsing stages. Это стадия RegEx и JSON. На этом этапе мы извлекаем данные из логов в так называемую extracted map. Извлекать можно из JSON, просто копируя нужные нам поля в extracted map, или через регулярные выражения (RegEx), где в extracted map мапятся named groups. Extracted map представляет собой key-value хранилище, где key имя поля, а value его значение из логов.
  2. Transform stages. У этой стадии есть две опции: transform, где мы задаем правила трансформации, и source источник данных для трансформации из extracted map. Если в extracted map такого поля нет, то оно будет создано. Таким образом, можно создавать лейблы, которые не основаны на extracted map. На этом этапе мы можем манипулировать данными в extracted map, используя достаточно мощный Golang Template. Кроме того, надо помнить, что extracted map целиком загружается при парсинге, что даёт возможность, например, проверять значение в ней: {{if .tag}tag value exists{end}}. Template поддерживает условия, циклы и некоторые строковые функции, такие как Replace и Trim.
  3. Action stages. На этом этапе можно сделать что-нибудь с извлечённым:
    • Создать лейбл из extracted data, который проиндексируется Loki.
    • Изменить или установить время события из лога.
    • Изменить данные (текст лога), которые уйдут в Loki.
    • Создать метрики.
  4. Filtering stages. Стадия match, на которой можно либо отправить в /dev/null записи, которые нам не нужны, либо направить их на дальнейшую обработку.

Покажу на примере обработки обычных nginx-логов, как можно парсить логи при помощи Promtail.


Для теста возьмём в качестве nginx-proxy модифицированный образ nginx jwilder/nginx-proxy:alpine и небольшой демон, который умеет спрашивать сам себя по HTTP. У демона задано несколько эндпоинтов, на которые он может давать ответы разного размера, с разными HTTP-статусами и с разной задержкой.


Собирать логи будем с докер-контейнеров, которые можно найти по пути /var/lib/docker/containers/<container_id>/<container_id>-json.log


В docker-compose.yml настраиваем Promtail и указываем путь до конфига:


promtail:  image: grafana/promtail:1.4.1 // ... volumes:   - /var/lib/docker/containers:/var/lib/docker/containers:ro   - promtail-data:/var/lib/promtail/positions   - ${PWD}/promtail/docker.yml:/etc/promtail/promtail.yml command:   - '-config.file=/etc/promtail/promtail.yml' // ...

Добавляем в promtail.yml путь до логов (в конфиге есть опция "docker", которая делает то же самое одной строчкой, но это было бы не так наглядно):


scrape_configs: - job_name: containers   static_configs:       labels:         job: containerlogs         __path__: /var/lib/docker/containers/*/*log  # for linux only

При включении такой конфигурации в Loki будут попадать логи со всех контейнеров. Чтобы этого избежать, меняем настройки тестового nginx в docker-compose.yml добавляем логирование поле tag:


proxy: image: nginx.test.v3// logging:   driver: "json-file"   options:     tag: "{{.ImageName}}|{{.Name}}"

Правим promtail.yml и настраиваем Pipeline. На вход попадают логи следующего вида:


{"log":"\u001b[0;33;1mnginx.1    | \u001b[0mnginx.test 172.28.0.3 - - [13/Jun/2020:23:25:50 +0000] \"GET /api/index HTTP/1.1\" 200 0 \"-\" \"Stub_Bot/0.1\" \"0.096\"\n","stream":"stdout","attrs":{"tag":"nginx.promtail.test|proxy.prober"},"time":"2020-06-13T23:25:50.66740443Z"}{"log":"\u001b[0;33;1mnginx.1    | \u001b[0mnginx.test 172.28.0.3 - - [13/Jun/2020:23:25:50 +0000] \"GET /200 HTTP/1.1\" 200 0 \"-\" \"Stub_Bot/0.1\" \"0.000\"\n","stream":"stdout","attrs":{"tag":"nginx.promtail.test|proxy.prober"},"time":"2020-06-13T23:25:50.702925272Z"}

Pipeline stage:


 - json:     expressions:       stream: stream       attrs: attrs       tag: attrs.tag

Извлекаем из входящего JSON поля stream, attrs, attrs.tag (если они есть) и кладём их в extracted map.


 - regex:     expression: ^(?P<image_name>([^|]+))\|(?P<container_name>([^|]+))$     source: "tag"

Если удалось положить поле tag в extracted map, то при помощи регэкспа извлекаем имена образа и контейнера.


 - labels:     image_name:     container_name:

Назначаем лейблы. Если в extracted data будут обнаружены ключи image_name и container_name, то их значения будут присвоены соотвестующим лейблам.


 - match:     selector: '{job="docker",container_name="",image_name=""}'     action: drop

Отбрасываем все логи, у которых не обнаружены установленные labels image_name и container_name.


  - match:     selector: '{image_name="nginx.promtail.test"}'     stages:       - json:           expressions:             row: log

Для всех логов, у которых image_name равен nginx.promtail.test, извлекаем из исходного лога поле log и кладём его в extracted map с ключом row.


  - regex:         # suppress forego colors         expression: .+nginx.+\|.+\[0m(?P<virtual_host>[a-z_\.-]+) +(?P<nginxlog>.+)         source: logrow

Очищаем входную строку регулярными выражениями и вытаскиваем nginx virtual host и строку лога nginx.


     - regex:         source: nginxlog         expression: ^(?P<ip>[\w\.]+) - (?P<user>[^ ]*) \[(?P<timestamp>[^ ]+).*\] "(?P<method>[^ ]*) (?P<request_url>[^ ]*) (?P<request_http_protocol>[^ ]*)" (?P<status>[\d]+) (?P<bytes_out>[\d]+) "(?P<http_referer>[^"]*)" "(?P<user_agent>[^"]*)"( "(?P<response_time>[\d\.]+)")?

Парсим nginx-лог регулярными выражениями.


    - regex:           source: request_url           expression: ^.+\.(?P<static_type>jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$     - regex:           source: request_url           expression: ^/photo/(?P<photo>[^/\?\.]+).*$       - regex:           source: request_url           expression: ^/api/(?P<api_request>[^/\?\.]+).*$

Разбираем request_url. С помощью регэкспа определяем назначение запроса: к статике, к фоткам, к API и устанавливаем в extracted map соответствующий ключ.


       - template:           source: request_type           template: "{{if .photo}}photo{{else if .static_type}}static{{else if .api_request}}api{{else}}other{{end}}"

При помощи условных операторов в Template проверяем установленные поля в extracted map и устанавливаем для поля request_type нужные значения: photo, static, API. Назначаем other, если не удалось. Теперь request_type содержит тип запроса.


       - labels:           api_request:           virtual_host:           request_type:           status:

Устанавливаем лейблы api_request, virtual_host, request_type и статус (HTTP status) на основании того, что удалось положить в extracted map.


       - output:           source: nginx_log_row

Меняем output. Теперь в Loki уходит очищенный nginx-лог из extracted map.



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


Нужно иметь в виду, что извлечение меток с большим количеством значений (cardinality) может существенно замедлить работу Loki. То есть не стоит помещать в индекс, например, user_id. Подробнее об этом читайте в статье How labels in Loki can make log queries faster and easier. Но это не значит, что нельзя искать по user_id без индексов. Нужно использовать фильтры при поиске (грепать по данным), а индекс здесь выступает как идентификатор потока.


Визуализация логов



Loki может выступать в роли источника данных для графиков Grafana, используя LogQL. Поддерживаются следующие функции:


  • rate количество записей в секунду;
  • count over time количество записей в заданном диапазоне.

Ещё присутствуют агрегирующие функции Sum, Avg и другие. Можно строить достаточно сложные графики, например график количества HTTP-ошибок:



Стандартный data source Loki несколько урезан по функциональности по сравнению с data source Prometheus (например, нельзя изменить легенду), но Loki можно подключить как источник с типом Prometheus. Я не уверен, что это документированное поведение, но, судя по ответу разработчиков How to configure Loki as Prometheus datasource? Issue #1222 grafana/loki, например, это вполне законно, и Loki полностью совместим с PromQL.


Добавляем Loki как data source с типом Prometheus и дописываем URL /loki:



И можно делать графики, как в том случае, если бы мы работали с метриками из Prometheus:



Я думаю, что расхождение в функциональности временное и разработчики в будущем это поправят.



Метрики


В Loki доступны возможность извлечения числовых метрик из логов и отправка их в Prometheus. Например, в логе nginx присутствует количество байтов на ответ, а также, при определённой модификации стандартного формата лога, и время в секундах, которое потребовалось на ответ. Эти данные можно извлечь и отправить в Prometheus.


Добавляем ещё одну секцию в promtail.yml:


- match:   selector: '{request_type="api"}'   stages:     - metrics:         http_nginx_response_time:           type: Histogram           description: "response time ms"           source: response_time           config:             buckets: [0.010,0.050,0.100,0.200,0.500,1.0]- match:   selector: '{request_type=~"static|photo"}'   stages:     - metrics:         http_nginx_response_bytes_sum:           type: Counter           description: "response bytes sum"           source: bytes_out           config:             action: add         http_nginx_response_bytes_count:           type: Counter           description: "response bytes count"           source: bytes_out           config:             action: inc

Опция позволяет определять и обновлять метрики на основе данных из extracted map. Эти метрики не отправляются в Loki они появляются в Promtail /metrics endpoint. Prometheus должен быть сконфигурирован таким образом, чтобы получить данные, полученные на этой стадии. В приведённом примере для request_type=api мы собираем метрику-гистограмму. С этим типом метрик удобно получать перцентили. Для статики и фото мы собираем сумму байтов и количество строк, в которых мы получили байты, чтобы вычислить среднее значение.


Более подробно о метриках читайте здесь.


Открываем порт на Promtail:


promtail:     image: grafana/promtail:1.4.1     container_name: monitoring.promtail     expose:       - 9080     ports:       - "9080:9080"

Убеждаемся, что метрики с префиксом promtail_custom появились:



Настраиваем Prometheus. Добавляем job promtail:


- job_name: 'promtail' scrape_interval: 10s static_configs:   - targets: ['promtail:9080']

И рисуем график:



Таким образом можно узнать, например, четыре самых медленных запроса. Также на данные метрики можно настроить мониторинг.


Масштабирование


Loki может быть как в одиночном режиме (single binary mode), так и в шардируемом (horizontally-scalable mode). Во втором случае он может сохранять данные в облако, причём чанки и индекс хранятся отдельно. В версии 1.5 реализована возможность хранения в одном месте, но пока не рекомендуется использовать её в продакшене.



Чанки можно хранить в S3-совместимом хранилище, для хранения индексов использовать горизонтально масштабируемые базы данных: Cassandra, BigTable или DynamoDB. Другие части Loki Distributors (для записи) и Querier (для запросов) stateless и также масштабируются горизонтально.


На конференции DevOpsDays Vancouver 2019 один из участников Callum Styan озвучил, что с Loki его проект имеет петабайты логов с индексом меньше 1% от общего размера: How Loki Correlates Metrics and Logs And Saves You Money.


Сравнение Loki и ELK


Размер индекса
Для тестирования получаемого размера индекса я взял логи с контейнера nginx, для которого настраивался Pipeline, приведённый выше. Файл с логами содержал 406 624 строки суммарным объёмом 109 Мб. Генерировались логи в течение часа, примерно по 100 записей в секунду.


Пример двух строк из лога:



При индексации ELK это дало размер индекса 30,3 Мб:



В случае с Loki это дало примерно 128 Кб индекса и примерно 3,8 Мб данных в чанках. Стоит отметить, что лог был искусственно сгенерирован и не отличался большим разнообразием данных. Простой gzip на исходном докеровском JSON-логе с данными давал компрессию 95,4%, а с учётом того, что в сам Loki посылался только очищенный nginx-лог, то сжатие до 4 Мб объяснимо. Суммарное количество уникальных значений для лейблов Loki было 35, что объясняет небольшой размер индекса. Для ELK лог также очищался. Таким образом, Loki сжал исходные данные на 96%, а ELK на 70%.


Потребление памяти



Если сравнивать весь стек Prometheus и ELK, то Loki ест в несколько раз меньше. Понятно, что сервис на Go потребляет меньше, чем сервис на Java, и сравнение размера JVM Heap Elasticsearch и выделенной памяти для Loki некорректно, но тем не менее стоит отметить, что Loki использует гораздо меньше памяти. Его преимущество по CPU не так очевидно, но также присутствует.


Скорость


Loki быстрее пожирает логи. Скорость зависит от многих факторов что за логи, как изощрённо мы их парсим, сеть, диск и т. д. но она однозначно выше, чем у ELK (в моём тесте примерно в два раза). Объясняется это тем, что Loki кладёт гораздо меньше данных в индекс и, соответственно, меньше времени тратит на индексирование. Со скоростью поиска при этом ситуация обратная: Loki ощутимо притормаживает на данных размером более нескольких гигабайтов, у ELK же скорость поиска от размера данных не зависит.


Поиск по логам


Loki существенно уступает ELK по возможностям поиска по логам. Grep с регулярными выражениями это сильная вещь, но он уступает взрослой базе данных. Отсутствие range-запросов, агрегация только по лейблам, невозможность искать без лейблов всё это ограничивает нас в поисках интересующей информации в Loki. Это не подразумевает, что с помощью Loki ничего нельзя найти, но определяет флоу работы с логами, когда вы сначала находите проблему на графиках Prometheus, а потом по этим лейблам ищете, что случилось в логах.


Интерфейс


Во-первых, это красиво (извините, не мог удержаться). Grafana имеет приятный глазу интерфейс, но Kibana гораздо более функциональна.


Плюсы и минусы Loki


Из плюсов можно отметить, что Loki интегрируется с Prometheus, соответственно, метрики и алертинг мы получаем из коробки. Он удобен для сбора логов и их хранения с Kubernetes Pods, так как имеет унаследованный от Prometheus service discovery и автоматически навешивает лейблы.


Из минусов слабая документация. Некоторые вещи, например особенности и возможности Promtail, я обнаружил только в процессе изучения кода, благо open-source. Ещё один минус слабые возможности парсинга. Например, Loki не умеет парсить multiline-логи. Также к недостаткам можно отнести то, что Loki относительно молодая технология (релиз 1.0 был в ноябре 2019 года).


Заключение


Loki на 100% интересная технология, которая подходит для небольших и средних проектов, позволяя решать множество задач агрегирования логов, поиска по логам, мониторинга и анализа логов.


Мы не используем Loki в Badoo, так как имеем ELK-стек, который нас устраивает и который за много лет оброс различными кастомными решениями. Для нас камнем преткновения является поиск по логам. Имея почти 100 Гб логов в день, нам важно уметь находить всё и чуть-чуть больше и делать это быстро. Для построения графиков и мониторинга мы используем другие решения, которые заточены под наши нужды и интегрированы между собой. У стека Loki есть ощутимые плюсы, но он не даст нам больше, чем у нас есть, и его преимущества точно не перекроют стоимость миграции.


И хотя после исследования стало понятно, что мы Loki использовать не можем, надеемся, что данный пост поможет вам в выборе.


Репозиторий с кодом, использованным в статье, находится тут.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru