slogДо версии 1.21 в Go не было единого подхода к логированию. Команды выбирали между сторонними библиотеками вроде
zap, logrus и zerolog, поэтому кодовая база разных проектов выглядела неодинаково. Стандартный пакет
log умел писать только обычные текстовые строки, которые тяжело парсить и собирать в системах вроде Loki или ELK. В Go 1.21 появился slog, который принёс структурное логирование прямо в стандартную библиотеку. Если из всего списка новинок вы захотите взять только одну, берите эту.Какую боль решает
Структурные логи это пары ключ значение, а не склеенная строка. Их легко фильтровать, искать по конкретным полям и отдавать в JSON прямо в систему сбора. Раньше ради этого приходилось тянуть внешнюю зависимость, теперь хватает стандартной библиотеки.
Старый способ выглядел так:
log.Printf("[ERROR] User %d login failed from IP %s", userID, ip)Здесь данные смешаны с текстом, и чтобы вытащить
userID, нужно писать регулярки.Современный способ:
import "log/slog"
slog.Error("Login failed", "userID", userID, "ip", ip)
Сообщение остаётся читаемым, а данные лежат в отдельных полях.
Что он делает
slog строится вокруг трёх частей. Logger принимает вызовы вроде Info и Error. Handler решает, куда и в каком формате писать. Attr это пара ключ значение. В комплекте идут два обработчика, TextHandler для человекочитаемого вывода и JSONHandler для машинного.Как настроить JSON вывод
Чтобы получать логи в JSON, достаточно подменить обработчик у глобального логгера:
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
slog.SetDefault(logger)
slog.Info("server started", "port", 8080)
На выходе получится строка JSON с полями time, level, msg и port. Её сразу можно отправлять в сборщик логов без дополнительной обработки.
Группировка и контекст
Часто к каждому запросу удобно прикреплять одни и те же поля. Метод
With создаёт логгер с заранее заданными атрибутами:reqLogger := slog.With("requestID", reqID, "userID", userID)
reqLogger.Info("processing request")
reqLogger.Warn("slow response", "ms", 320)Теперь
requestID и userID попадут в каждую запись без повторного перечисления.Переводить проект можно постепенно, начав с замены
log на slog в новых модулях. Старый код при этом продолжит работать, а новые записи сразу станут пригодными для машинного разбора.📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoToProduction