TLDR: Мне хочется хранить в чем то именно свои логи, кастомные, а не собирать всё подряд в одну кучу. Текущее решение с хранением в MySql не устраивает
Уже существует несколько сервисов на Laravel/Lumen, где есть некоторые внутренние логи (действия пользователей, денежные операции, обработка вебхуков и тд). Сейчас эти логи хранятся по таблицамв мускуле, каждому типу логов своя таблица: например таблица http логов входящие и исходящие, таблица входящих вебхуков и тд. Эти таблицы очень быстро заполняются, запросы по ним тяжелые, полнотекстовый поиск такая себе идея.
Эти логи используются по большей части разработчиками для поиска и отладки багов: посмотреть какой запрос куда ушел/пришел, какое то логирование выполнения крон команд (не только сам факт запуска/остановки скрипта, но и какие то промежуточные действия, например логируется процесс выполнения)
Читал про такие системы как ELK/EFK, PLG. Сложилось впечатление что ими собирают в основном логи nginx (все входящие запросы). Либо второй вариант: пишут в коде нечто вроде echo *log*, и при этом перенапрявляют весь вывод в stdout, а дальше докер это всё прокидывает куда то там (не разбирался).
Первый вариант меня не устраивает (или я не понимаю как это организовать), тем что все логи будут храниться как то в куче, их нужно будет уже на стороне того же PLG как то группировать на основе какого нибудь id, который пришел скажем в заголовке.
Пример: залогировать переход юзера на страницу, а в запросе будет только его кука (условно) для идентификации. Не подходит
Второй вариант вроде более детальный, можно самому формировать строку лога, но тогда надо строить какую то свой формат вывода, чтобы например отличать что этот лог от юзеров, этот лог от фин. операций и тд. Хотя в первом пункте такое тоже нужно....
В начале читал даже про ClickHouse, но понял что он вроде как не для этого.
Подскажите как организовывают хранение логов в больших проектах? Где можно прочитать про лучшие практики?
P.S. можно конечно и дальше возиться с таблицей в бд, к ней прикрутить Elasticsearch и индексировать эти логи, настраивать какую то ротацию. Но мне кажется это не верный вариант
P.S. можно конечно и дальше возиться с таблицей в бд, к ней прикрутить Elasticsearch и индексировать эти логи
Так эти системы и используют Эластик.
Логи в эластик можно конечно кидать текстом, или по пути хотя бы немного парсить по тегам. А можно кидать сразу структурированные JSON, с тегами по приложению, хосту, типу сообщения и потом строить запросы или графики в кибане
например таблица http логов входящие и исходящие, таблица входящих вебхуков и тд. Эти таблицы очень быстро заполняются, запросы по ним тяжелые, полнотекстовый поиск такая себе идея.
бедный ваш сервер. На каждый хит лишний скл запрос. Время отклика наверное больше сотни милисекунд ?
Такое впечатление, что цену своего логирования вы за ноль принимаете.
Это уже больше на audit log похоже - их обычно в той же базе хранят, что и обычные данные, если речь о действиях над какими-то объектами, а не о том что пользователь куда-то кликнул - такое можно и в кликхаус сливать - для этого он и создавался
Альтернатива БД, если лог именно и только для разработчика.
class Logger
{
private $logfile;
private function __construct()
{}
public function __destruct()
{
$this->log('');
fclose($this->logfile);
}
public function log($string)
{
fwrite($this->logfile, $string . "\n");
fflush($this->logfile);
}
static public function getCommon($tag)
{
$logDir = base_path() . '/../logs/' . $tag; // это в Ларавели, без нее $_SERVER['DOCUMENT_ROOT'] или абсолютный путь (если должно работать в консоли/кроне)
if(!file_exists($logDir)) {
mkdir($logDir);
}
$logger = new Logger();
$logger->logfile = fopen($logDir . '/' . date('Y-m-d') . '.log', 'at');
$logger->log(date('Y-m-d H:i:s') . "\n");
return $logger;
}
}
Выше корня проекта - папка logs, в ней по подпапкам (определяется в конструкторе логгера) разложены логи того, что происходит. Имя файла сегодняшнего лога - текущая дата, так что легко настраивается чистка по крону и элементарно ищется информация за нужный день.
Да, это колхоз, нестандарт и животноводство. Но пользоваться этим удобно. Во всяком случае, мне.
Это прописано в общем коде для классов работы с API маркетплейсов.
Так, у меня все, что запрошено и получено, скажем, от Wildberries за сегодня, лежит в logs/wb/сегодняшняя_дата.log, перед каждым блоком проставлено время запроса.
Простым поиском по таким файлам я выяснил, например, что их кривой API теряет IncomeID у заказов по FBO - в платежах номер поставки есть, а в заказах 0...
Не удобно индексировать, например по полю datetime. Хотя я уже и сделал бинарный поиск с помощью хранимой процедуры (первый раз в жизни встретил вариант где она действительно нужна), но это всё не то. Хочется централизованно. И чтобы потом можно было какую то аналитику проводить