From: Sergey Matveev Date: Fri, 11 Jul 2025 13:34:05 +0000 (+0300) Subject: Структурированные логи X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=03e4174716e5ad7e53d359b90e9534e23aecf05d;p=stargrave-blog.git Структурированные логи https://datatracker.ietf.org/doc/html/rfc5424 https://page.hyoo.ru/#!=8i7ao7_xfyxah https://habr.com/ru/articles/503240/ https://hackernoon.com/tree-ast-which-crushes-json-xml-yaml-toml-etc https://www.gnu.org/software/recutils/ http://www.git.cypherpunks.su/?p=recmultilog.git;a=summary С моей подачи в ivi когда-то появились структурированные логи в RFC 5424 формате. Затем на текущем месте работы мы это применяли в ряде проектов. Но как бы не то чтобы они прям удобны и хороши. Парсить -- не самое тривиальное. Читать человеку длинные строчки -- тоже так себе идея, хотя и лучше чем JSON. Но многострочные тексты не засунуть, если только не кодировать/экранировать. Traceback не засунешь. JSON -- ужас по производительности и недружелюбности к пользователю. Использовать можно только с дополнительным инструментарием. В комментарии к моей статье (0f3b3d1cd63008298fec7a4d1fefcb7740eccf9c) про KEKS упомянули Tree формат. В целом он мне очень даже понравился: более чем читабельный для человека, вроде бы достаточно прост для парсинга компьютером, многострочный текст переносит без проблем. Занялся я реализацией его декодера на Python (для прототипа). Encoder вообще малёхонький. А вот на декодер я потратил постыдно много времени и строк кода. Или я совсем тупой, или подобного рода формат всё равно парсить отнюдь не тривиально. Не, я даже с тестами реализовал всё, и поддержку списков словарей (в них всё засовываю), и указание нескольких "узлов" в одной строчке, но мне это не показалось простой задачей. TLV-кодеки просто дуболомны по своей простоте. Bencode, поддерживающий куда больше типов данных, занимал экран кода, тогда как Tree декодер даже больше. Возможно коллеги смогут показать где я обосрался и насколько просто можно Tree распарсить, но пока я отбросил идею его использования. И выбор формата для логов пал на recutils/recformat. Я его уже даже использовал в проектах для логов. Но его недостаток: там только один уровень вложенности ключей/значений. Можно сэмулировать словарь в словаре просто вставив сериализованное представление одного в виде текста в ключ другого. Но это хак, некрасиво. Зато есть понятие чёткого конца/разделителя записей, есть комментарии. На Go я реализовывал recformat парсер и это почти тривиальная задача. Ещё не проверял на практике, но кажется что просто эмуляция вложенных структур через "линеаризацию" и объединение ключей через "_" -- вполне себе приемлемо. И довольно дёшево и читается человеком и должно быть не сложно обратно восстанавливать (если, конечно же, человек не будет штатно использовать "_" в ключах -- а вот нефиг). Причём этот подход сами recutils используют во время join-а записей. А сам подход с объединением ключей (линеаризация) и в других форматах/логах встречается. Написание multilog-like демона, который вместо строчек ожидает recformat записи -- заняло у меня меньше времени чем возня с Tree. Но да, ok, сам парсер recformat у меня уже был. Ключом "t" он может добавлять в записи и timestamp. А "c" в конце может приписывать XXH3-128 контрольную сумму всей записи. Ну какая же у меня программа возможна без вызова хэша? Поддерживает ротацию логов, вызов внешних обработчиков. ---