Ответ
Структурированное логирование — это подход к записи логов не в виде простого текста, а в формате с четкой структурой (чаще всего JSON или logfmt), где каждое сообщение представляет собой набор пар «ключ-значение».
Плюсы:
- Машиночитаемость: Структурированные логи легко парсятся и индексируются автоматизированными системами (ELK, Grafana Loki, Splunk, Datadog). Это упрощает поиск, фильтрацию и агрегацию данных.
- Контекстуальность: Позволяет добавлять к сообщению произвольные контекстные поля (
user_id
,request_id
,duration_ms
), что делает логи гораздо более информативными для отладки и анализа. - Надежный поиск: Вместо поиска по подстроке в текстовых логах можно выполнять точные запросы по полям, например,
level=error AND user_id=123
.
Минусы:
- Повышенный объем: JSON и другие форматы обычно занимают больше места, чем простой текст, что увеличивает затраты на хранение.
- Сложнее для быстрого чтения человеком: Необработанные JSON-логи могут быть менее читаемыми в консоли по сравнению с простым текстом. Однако многие инструменты предоставляют "красивый" вывод для разработки.
- Накладные расходы на производительность: Сериализация данных в JSON или другой формат требует дополнительных ресурсов CPU по сравнению с простой записью строки.
Примеры в Go:
Начиная с Go 1.21, в стандартной библиотеке появился пакет slog
для структурированного логирования, который является предпочтительным выбором.
Пример с slog
(стандартная библиотека):
import (
"log/slog"
"os"
)
func main() {
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.Info("Пользователь вошел в систему",
slog.String("username", "admin"),
slog.String("ip_address", "127.0.0.1"),
)
}
Вывод slog
:
{"time":"2023-10-26T15:00:00.123Z","level":"INFO","msg":"Пользователь вошел в систему","username":"admin","ip_address":"127.0.0.1"}
Пример с logrus
(популярная библиотека):
Примечание: logrus
находится в режиме поддержки, новым проектам рекомендуется использовать slog
или zerolog
.
import "github.com/sirupsen/logrus"
func main() {
log := logrus.New()
log.SetFormatter(&logrus.JSONFormatter{})
log.WithFields(logrus.Fields{
"user": "admin",
"ip": "127.0.0.1",
}).Info("User logged in")
}