Для чего нужно логирование
Что проверяют
Понимаете ли вы логи как инструмент эксплуатации, а не как fmt.Println для отладки, и отличаете ли их от метрик и трейсов. Следом обычно спрашивают, чем вы логируете в Go и как не дать логам тормозить сервис.
Как отвечать
Логи отвечают на вопрос, что произошло с конкретным запросом. Отсюда задачи: разбор инцидентов на проде, где нет отладчика, аудит действий пользователей, диагностика сбоев интеграций. Для вопроса «сколько и как быстро» нужны метрики (Prometheus), для пути запроса через сервисы нужны трейсы (OpenTelemetry). Сильный ответ разводит эти три вещи.
Практика в Go:
log/slog: структурированный логгер в стандартной библиотеке с Go 1.21. УровниDebug,Info,Warn,Error, обработчикиslog.NewJSONHandlerиslog.NewTextHandler. Из сторонних живыzapиzerolog, когда критичны аллокации;- поля вместо строк:
logger.Info("order created", "order_id", id). Поля фильтруются в Loki или Elasticsearch, а склеенную строку придётся разбирать регулярками; - контекст запроса:
request_idиtrace_idв каждой записи, черезlogger.With(...)или обработчик, который достаёт их изcontext.Context; - куда писать: в stdout в JSON, дальше логи забирает агент (Vector, Fluent Bit, Grafana Alloy);
- уровень на лету:
slog.LevelVarвключаетDebugбез перезапуска; - секреты: токены и персональные данные в лог не попадают, для своего типа можно реализовать
slog.LogValuerи отдавать замаскированное значение.
Где спотыкаются
Логируют ошибку на каждом уровне и тут же возвращают её наверх. Один сбой превращается в пять записей. Правило: либо обработал и залогировал, либо обернул через fmt.Errorf("load: %w", err) и вернул.
Зовут log.Fatal в глубине кода. Он вызывает os.Exit(1), отложенные defer не выполняются, буферы и соединения не закрываются.
Считают RPS и латентность, вычитывая логи. Это дорого по хранению и медленно, для чисел есть счётчики и гистограммы.