📝 log/slog: Хватит парсить логи глазами (и тащить Logrus в проект) Два часа ночи.
Два часа ночи. Прод лежит. Вы сидите в терминале и пытаетесь выцепить причину через grep "error" | grep "user_1234". Знакомая жиза?
Долгие годы стандартный пакет log в Go был... ну, скажем честно, спартанским. Он писал простой текст. А современные системы мониторинга (ELK, Datadog, Grafana Loki) любят структурированные данные (JSON или Key-Value), чтобы по ним можно было строить графики и алерты.
Поэтому каждый Go-разработчик тащил в проект сторонние комбайны: logrus (который официально в режиме maintenance с 2020 года), zerolog или uber-go/zap.
С выходом Go 1.21 праздник наступил и на нашей улице - в стандартную библиотеку завезли log/slog.
Почему slog - это круто?
Он быстрый, расширяемый и, главное, избавляет от сторонних зависимостей.
Как это выглядит:
import "log/slog"
func main() {
// Создаем JSON-хендлер (идеально для прода)
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
// Делаем его логгером по умолчанию для всего приложения
slog.SetDefault(logger)
// Пишем структурированно
slog.Info("user logged in",
slog.Int("user_id", 42),
slog.String("ip", "192.168.1.1"),
)
}
// Вывод:
// {"time":"2023-10-26T15:04:05Z", "level":"INFO", "msg":"user logged in", "user_id":42, "ip":"192.168.1.1"}
🔥 Нюанс для Senior-ов: Интерфейс LogValuer
Самая частая проблема логирования, случайно слить в логи пароль, токен или кредитную карту (PII данные), передав структуру целиком.
В slog есть гениальная вещь - интерфейс LogValuer. Если ваша структура его реализует, логгер вызовет его до сериализации.
type User struct {
ID int
Name string
Password string // СЕКРЕТ!
}
// Учим структуру безопасно логировать саму себя
func (u User) LogValue() slog.Value {
return slog.GroupValue(
slog.Int("id", u.ID),
slog.String("name", u.Name),
slog.String("password", "***REDACTED***"), // Скрыли!
)
}
func main() {
user := User{ID: 1, Name: "Ivan", Password: "super_secret_123"}
// Даже если джун случайно залогирует юзера целиком:
slog.Info("created user", slog.Any("user", user))
// В логах будет: "password": "***REDACTED***". Прод спасен.
}
Конечно, zap всё ещё чуть быстрее на экстремальных нагрузках благодаря жесткой кодогенерации, но для 95% микросервисов slog - это новый абсолютный стандарт.
#golang #logging #slog #bestpractices #observability
👉 @golang_lib