Ответ
Логирование — это процесс записи информации о событиях, происходящих во время работы приложения. Это один из трех столпов наблюдаемости (Observability), наряду с метриками и трассировкой.
Основные цели логирования:
- Отладка (Debugging): Анализ логов помогает разработчикам понять, что пошло не так в коде.
- Мониторинг (Monitoring): Наблюдение за состоянием приложения в реальном времени, отслеживание ошибок и аномалий.
- Аудит (Auditing): Запись критически важных действий (например, кто и когда изменил данные) для безопасности и анализа.
Структурированное и неструктурированное логирование
- Неструктурированное: Простой текст, удобный для чтения человеком. Пример:
log.Printf("User %d failed to login", userID)
. - Структурированное: Запись логов в формате ключ-значение (чаще всего JSON), который легко парсить и анализировать машиной.
Преимущества структурированного логирования
- Машинная читаемость: Логи в формате JSON легко обрабатываются автоматизированными системами.
- Эффективный поиск и фильтрация: Можно быстро найти все логи с определенным
userID
,traceID
или уровнемERROR
. В системах вроде ELK Stack (Elasticsearch, Logstash, Kibana) или Grafana Loki это делается за секунды. - Богатый контекст: Легко добавлять к каждому сообщению полезные поля: ID запроса, имя пользователя, IP-адрес, длительность операции и т.д. Это бесценно при расследовании инцидентов.
- Аналитика и алертинг: На основе структурированных данных можно строить дашборды (например, график количества ошибок в минуту) и настраивать автоматические оповещения (алерты) при достижении пороговых значений.
Популярные библиотеки в Go
log/slog
(стандартная библиотека, с Go 1.21): Новый стандарт для структурированного логирования в Go.Zap
: Очень быстрая и производительная библиотека от Uber.Logrus
: Более гибкая в настройке, с поддержкой хуков, но медленнее Zap.
Пример структурированного лога с Zap
:
import "go.uber.org/zap"
// Инициализация логгера (обычно делается один раз при старте приложения)
logger, _ := zap.NewProduction()
defer logger.Sync() // очищает буфер перед выходом
// Пример записи лога
userID := 123
logger.Info("User successfully logged in",
zap.Int("userID", userID),
zap.String("ipAddress", "192.168.1.10"),
zap.String("traceID", "abc-123-xyz-789"),
)
// Вывод в JSON:
// {"level":"info","ts":1678886400.0,"caller":"main.go:15","msg":"User successfully logged in","userID":123,"ipAddress":"192.168.1.10","traceID":"abc-123-xyz-789"}