Работа без логов, это как вождение автомобиля вслепую. Ехать можно, но недолго и не туда.

Почти в каждом проекте логи нужны. И нужны инструменты, которые умеют с ними работать. А с этим исторически у нас была проблема.

В облаке Amvera, проекты пользователей, в большинстве своём, небольшие. А инструменты на рынке, такие как Elasticsearch очень требовательны к выделяемым ресурсам и сложны в настройке.

Странно поднимать телеграм-бота, который потребляет 100 мб. оперативной памяти и ставить для его логов Elastic на 16 Гб.

Логичным решением является создание мультиарендной системы. Когда мы собираем логи в какой-то большой базе данных, и каждому пользователю даём доступ только к его логам. Звучит замечательно, но на практике реализовать это не так легко. На создание приемлемого решения у нас ушло несколько итераций. И мы хотим поделиться опытом, чтобы другие не наступали на наши грабли и могли сделать сразу хорошо.

Итерации

В первой попытке мы написали свой log collector, который просто доставал последние логи и отправлял их на фронт. Но это было плохое решение. Работало оно медленно, не поддерживало стрим, и главное, не предусматривало долгосрочное хранение. Помимо этого, оно постоянно отваливалось по разным причинам.

Достаточно быстро мы поняли, что это не вариант и надо сделать лучше. Для этого решили рассмотреть специализированные, и не только, базы данных. Начали с Opensearch, но столкнулись с нестабильной работой и отвалами, решили продолжить поиски. В результате, в качестве базы данных была выбрана MongoDB. Одним из преимуществ было то, что MongoDB практически бесконечно масштабируется, логи можно рассматривать как объекты, поэтому они неплохо хранятся в этой базе данных, и Monga поддерживала режим стрима, что для нас было важно.

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

Но были и недостатки.

– Невозможность реализовать быстрый поиск по логам.

– Запросы на выдачу логов выполнялись не быстро и сильно нагружали узел с MongoDB, а использование функции tail для стриминга ограничивало возможность добавления дополнительных реплик.

– На момент интеграции MongoDB не было готовых решений по сбору логов из Kubernetes и их отправки в Mongo.Нам пришлось писать свой коллектор логов, и здесь мы столкнулись с нетривиальной проблемой про которую расскажем ниже. Стоит отметить, что в дальнейшем такие инструенты как fluentBit получили поддержку отправки в MongoDB.

Как известно,  Kubernetes пишет логи контейнеров  в файл. Согласно политике ротации логов, при достижении определнного объема фала, создается новый. Мы упустили данный аспект в документации и в первоначальном варианте. Наш транспорт логов продолжал слушать архивный файл. Из-за чего появлялись обращения, когда у пользователя логи исправно работали несколько недель, или даже месяцев, но неожиданно переставали идти. И исправить это можно было только перезагрузкой проекта, что не всегда приемлемо.

Когда мы это поняли, была добавлена функция, отслеживающая появление новых файлов. Это решило 90% проблемы, но всё равно, иногда возникали ситуации с отвалом логов.

Да и невозможность семантического поиска никто не отменял.

И тогда мы решили ещё раз «подойти к снаряду». Тем более, за тот год, что использовали MongoDB, технологии не стояли на месте. Появились такие решения как Grafana Loki и совсем свежий Victorialogs.

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

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

Но плюсов гораздо больше. 

Это

– Стабильная работа.

– Возможность семантического поиска по словам, встречающимся в логе.

– Возможность фильтрации по времени.

– Нам, как провайдеру, особенно полезной оказалась возможность использовать параметр ‘extra_filters’, который позволяет отделить пользователей по их меткам, не нагружая поле запроса и гарантирующий дополнительную безопасность.

– Стоит отметить что как и victoria metrics, Vlogs поддерживает мультитенантность.

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

– Подсказки в интерфейсе по частым ошибкам.

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

В итоге мы получили следующее решение.

Интерфейс работы с логами
Интерфейс работы с логами

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

И главное, это бесплатно, не требуется поднимать и настраивать отдельный сервис. И не требует никакой настройки, всё работает из коробки для всех проектов, которые вы запускаете в Amvera Cloud.

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


  1. nik_the_spirit
    18.06.2025 11:46

    Из скриншота видно, что вы отображаете логи как строки. А что на счёт структурированных логов? Могу ли я добавить какую-то метаинформацию и потом удобно искать по ней? Например, отдельное поле request_id.


    1. kirillkosolapov Автор
      18.06.2025 11:46

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