Pull to refresh

Comments 19

У Go давно появился отличный логгер из коробки, а люди зачем-то продолжают использовать древние решения. И не просто древние решения, а обёртки над ними, преподнося это как киллер-фичу. Кажется было бы на много лучше написать реализацию подобного функционала представив её в виде `slog.Handler`тогда подключить ваше решение не составить никакого труда. А так, просто представьте, надо будет везде внедрять зависимость в виде `emitlog`, кто на такое пойдёт? А потом ещё выпиливать если вдруг что-то пойдёт не так. Ну уж нет.

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

go-путь подразумевает самостоятельное написание такой мелочи, как логгер, вместо добавления очередной зависимости.

Хм. Интересный подход. 1) А как в таком случае унифицировать формат вывода логов из вашего кода и из стороннего, который вы через депенденси подключили? 2) И как управлять какие логи вы хотите видеть, а какие убрать? 3) А если хотите дообогатить логи чем-то из контекста?

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

Как вы предлагаете управлять "всем" в сторонних библиотеках которые вы подключаете?

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

никто не мешает использовать подход который я предложил к slog, и никто не заставляет тянуть именно мою либу. можно просто скопировать код и использовать

slog вполне подходит для реализации концепции из статьи, в чем претензия?

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

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

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

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

логика такая: в контексет есть логгер и у него свой буфер, пока не будет вызван например log.Err все логи пишутся в буфер - а после уже в указанные врайтер. если буфер переполняется - логи тоже скидываются в финальный врайтер.

тут именно речь про логирование цепочки действия целиком - поэтому логгер прокидывется через контекст

поэтому можно получать логи целиком от одног контекста если в них были ошибки

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

так у меня и есть мидлвере с таким подходом

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

а почему вы считаете что я сделал штуку для всего на свете?

Да я без претензий, в вашей концепции есть неплохая, интересная идея... И я пытаюсь ее натянуть на разные сценарии.

Только вот я в логгировани пришел немного к другому подходу.

Я в одном проекте сделал так, что по сути выводится только уведомления о важных событиях и ошибки. Так вот понимая сложность сбора контекста ошибки у меня ошибка собирается с деталями по всему стеку вызова и вот с ее адекватным форматированием (с учетом ограничения на длину строки) пришлось повозится изрядно. Но в такой схеме debug вообще не нужен. Я там в ошибку выкидываю все, что нужно для того, что бы понять почему именно там произошла ошибка, где и с какими данными.

Один раз правда не хватило этого пришлось снимать трейсы, что бы понять, что там внезапно начинает выедать один CPU.

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

А что не так с телеметрией, в которой помимо всего есть и вложенные спаны дл отслеживания контекста?

Sign up to leave a comment.

Articles