package logging import ( "log/slog" "os" "github.com/go-kratos/kratos/contrib/otel/v3/tracing" kratoslog "github.com/go-kratos/kratos/v3/log" "go.uber.org/zap" "go.uber.org/zap/exp/zapslog" "go.uber.org/zap/zapcore" ) // NewZapLogger adapts a Zap core to the slog logger used by Kratos v3. // The file layout remains compatible with the administration log viewer. func NewZapLogger(root, filename string, attrs ...any) (*slog.Logger, func()) { file := NewDailyWriter(root, filename) encoder := zap.NewProductionEncoderConfig() encoder.EncodeTime = zapcore.ISO8601TimeEncoder encoder.EncodeLevel = zapcore.LowercaseLevelEncoder core := zapcore.NewCore( zapcore.NewJSONEncoder(encoder), zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(file)), zap.NewAtomicLevelAt(zap.InfoLevel), ) zapLogger := zap.New(core) handler := zapslog.NewHandler(zapLogger.Core(), zapslog.WithCaller(true), zapslog.AddStacktraceAt(slog.LevelError)) logger := kratoslog.NewLogger(handler, kratoslog.WithExtractor(tracing.TraceAttrs)).With(attrs...) cleanup := func() { _ = zapLogger.Sync() _ = file.Close() } return logger, cleanup }