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
// Before: log
log.Printf("사용자 %s 로그인 실패: %v", username, err)

// After: DD
dd.Infof("사용자 %s 로그인 실패: %v", username, err)

// 또는 구조화 로그 사용
dd.ErrorWith("사용자 로그인 실패",
    dd.String("username", username),
    dd.Err(err),
)

글로벌 Logger 교체

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

// After: 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
// Before: slog
slog.Info("request completed",
    "method", "GET",
    "status", 200,
    "duration", 150*time.Millisecond,
)

// After: 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
// Before: zap
cfg := zap.Config{
    Level:       zap.NewAtomicLevelAt(zap.InfoLevel),
    Encoding:    "json",
    OutputPaths: []string{"stdout", "logs/app.log"},
}
logger, _ := cfg.Build()

// After: 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
// Before: zap
logger.Info("request",
    zap.String("method", "GET"),
    zap.Int("status", 200),
    zap.Duration("elapsed", 150*time.Millisecond),
    zap.Error(err),
)

// After: 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
// Before: logrus
logrus.WithFields(logrus.Fields{
    "method":  "GET",
    "status":  200,
    "elapsed": 150 * time.Millisecond,
}).Info("Request completed")

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

DD 전유 기능

마이그레이션 후 DD 의 독특한 기능을 활용할 수 있습니다.

기능설명문서
민감 데이터 필터비밀번호, API Key 등 자동 마스킹민감 데이터 필터링
감사 로그비동기 보안 이벤트 기록감사 로그
HMAC 서명로그 변조 방지HMAC 서명 실전
산업 규정 준수HIPAA/PCI-DSS 사전 설정산업 규정 준수 구성
라이프사이클 훅6 가지 Hook 이벤트훅 시스템
LoggerRecorder테스트 보조테스트 패턴

다음 단계