Skip to content

Руководство по миграции

Если вы используете другую библиотеку логирования, это руководство поможет вам быстро мигрировать проект на DD.

Миграция со стандартной библиотеки log

Сравнение API

logDDОписание
log.Print(msg)dd.Info(msg)Уровень Info
log.Printf(format, args)dd.Infof(format, args)Форматированный
log.Println(msg)dd.Info(msg)Уровень Info
log.Fatal(msg)dd.Fatal(msg)Fatal (вызывает os.Exit)
log.Fatalf(format, args)dd.Fatalf(format, args)Форматированный Fatal
log.Panic(msg)dd.Error(msg) + panic()DD не имеет встроенного Panic
dd.InfoWith(msg, fields...)Структурированный лог (новое)

Базовая миграция

go
// До: log
log.Printf("Пользователь %s не смог войти: %v", username, err)

// После: DD
dd.Infof("Пользователь %s не смог войти: %v", username, err)

// Или использование структурированного лога
dd.ErrorWith("Ошибка входа пользователя",
    dd.String("username", username),
    dd.Err(err),
)

Замена глобального Logger

go
// До: log
log.SetOutput(file)
log.SetFlags(log.LstdFlags | log.Lshortfile)

// После: DD
logger, err := dd.New(dd.Config{
    Level:  dd.LevelInfo,
    Format: dd.FormatText,
    Targets: []dd.OutputTarget{
        dd.FileOutput("logs/app.log"),
    },
})
if err != nil {
    log.Fatal(err)
}
dd.SetDefault(logger)

Миграция с slog

Сравнение API

slogDDОписание
slog.Info(msg)dd.Info(msg)Уровень Info
slog.Info(msg, "key", value)dd.InfoWith(msg, dd.String("key", value))Структурированный
slog.Debug(msg)dd.Debug(msg)Уровень Debug
slog.Error(msg, "err", err)dd.ErrorWith(msg, dd.Err(err))Лог ошибки
slog.Warn(msg)dd.Warn(msg)Уровень Warn
slog.With("key", value)dd.WithFields(dd.String("key", value))Предустановленные поля
slog.New(handler)dd.New(cfg)Создание экземпляра
slog.SetDefault(logger)dd.SetDefault(logger)Установка глобального

Миграция структурированного логирования

go
// До: slog
slog.Info("request completed",
    "method", "GET",
    "status", 200,
    "duration", 150*time.Millisecond,
)

// После: DD
dd.InfoWith("Запрос завершён",
    dd.String("method", "GET"),
    dd.Int("status", 200),
    dd.Duration("duration", 150*time.Millisecond),
)

Типобезопасность

slog использует пары ключ-значение any, DD использует типизированные конструкторы полей. Ошибки типов обнаруживаются на этапе компиляции.

Миграция с zap

Сравнение API

zapDDОписание
zap.L().Info(msg, zap.Field...)dd.InfoWith(msg, dd.Field...)Структурированный
zap.String(key, val)dd.String(key, val)Строковое поле
zap.Int(key, val)dd.Int(key, val)Целочисленное поле
zap.Error(err)dd.Err(err)Поле ошибки
zap.Any(key, val)dd.Any(key, val)Произвольный тип
zap.Sugar().Infof(...)dd.Infof(...)Форматированный
logger.With(zap.Field...)logger.WithFields(dd.Field...)Предустановленные поля
zapcore.NewCore(...)dd.New(dd.Config{...})Создание экземпляра

Сравнение конфигурации

go
// До: zap
cfg := zap.Config{
    Level:       zap.NewAtomicLevelAt(zap.InfoLevel),
    Encoding:    "json",
    OutputPaths: []string{"stdout", "logs/app.log"},
}
logger, _ := cfg.Build()

// После: DD
logger, err := dd.New(dd.Config{
    Level:  dd.LevelInfo,
    Format: dd.FormatJSON,
    Targets: []dd.OutputTarget{
        dd.ConsoleOutput(),
        dd.FileOutput("logs/app.json"),
    },
})
if err != nil {
    log.Fatal(err)
}

Сравнение полей

go
// До: zap
logger.Info("request",
    zap.String("method", "GET"),
    zap.Int("status", 200),
    zap.Duration("elapsed", 150*time.Millisecond),
    zap.Error(err),
)

// После: DD
dd.InfoWith("request",
    dd.String("method", "GET"),
    dd.Int("status", 200),
    dd.Duration("elapsed", 150*time.Millisecond),
    dd.Err(err),
)

Миграция с logrus

Сравнение API

logrusDDОписание
logrus.Info(msg)dd.Info(msg)Уровень Info
logrus.WithField("k", v)dd.WithField("k", v)Одно поле
logrus.WithFields(logrus.Fields{...})dd.WithFields(dd.String(...), ...)Несколько полей
logrus.SetLevel(logrus.InfoLevel)dd.SetLevel(dd.LevelInfo)Установка уровня
logrus.SetFormatter(&logrus.JSONFormatter{})dd.New(dd.Config{Format: dd.FormatJSON})Формат JSON
logrus.SetOutput(file)dd.Config{Targets: ...}Цель вывода
logrus.Fatal(msg)dd.Fatal(msg)Fatal

Миграция полей

go
// До: logrus
logrus.WithFields(logrus.Fields{
    "method":  "GET",
    "status":  200,
    "elapsed": 150 * time.Millisecond,
}).Info("Request completed")

// После: DD
dd.WithFields(
    dd.String("method", "GET"),
    dd.Int("status", 200),
    dd.Duration("elapsed", 150*time.Millisecond),
).Info("Request completed")

Уникальные возможности DD

После миграции вы можете воспользоваться уникальными возможностями DD:

ВозможностьОписаниеДокументация
Фильтрация конфиденциальных данныхАвтоматическое маскирование паролей, API-ключей и т.д.Фильтрация конфиденциальных данных
Аудитные логиАсинхронная запись событий безопасностиАудитные логи
HMAC-подписиЗащита логов от подделкиПрактика HMAC-подписей
Отраслевое соответствиеПредустановки HIPAA/PCI-DSSКонфигурация отраслевого соответствия
Хуки жизненного цикла6 типов событий HookСистема хуков
LoggerRecorderУтилита тестированияПаттерны тестирования

Следующие шаги