// Package zapslog provides a [zapcore.Core] implementation that forwards logs // to [slog.Handler].
package zapslog import ( ) const ( // loggerNameKey is the key used by the [Core] for the [zap.Entry]’s // LoggerName field. loggerNameKey = "logger_name" // stackKey is the key used by the [Core] for the [zap.Entry]’s // Stack field. stackKey = "stack" ) // Core implements zapcore.Core and forwards log records to slog.Handler. type Core struct { ctx context.Context handler slog.Handler fields []zapcore.Field } // New creates a [Core] backed by the provided context and [slog.Handler]. func ( context.Context, slog.Handler) *Core { return &Core{ ctx: , handler: , } } func ( *Core) ( []zapcore.Field) []zapcore.Field { := if := len(.fields); != 0 { = make([]zapcore.Field, 0, +len()) = append(, .fields...) = append(, ...) } return } // Enabled implements the [zapcore.Core] interface. func ( *Core) ( zapcore.Level) bool { return .handler.Enabled(.ctx, convertLogLevel()) } // With implements the [zapcore.Core] interface. func ( *Core) ( []zapcore.Field) zapcore.Core { := * .fields = .appendFields() return & } // Check implements the [zapcore.Core] interface. func ( *Core) ( zapcore.Entry, *zapcore.CheckedEntry) *zapcore.CheckedEntry { if .Enabled(.Level) { return .AddCore(, ) } return } // Write implements the [zapcore.Core] interface. func ( *Core) ( zapcore.Entry, []zapcore.Field) error { := slog.NewRecord( .Time, convertLogLevel(.Level), .Message, .Caller.PC, ) if .LoggerName != "" { .AddAttrs(slog.String(loggerNameKey, .LoggerName)) } .AddAttrs(encodeFields(.appendFields())...) if .Stack != "" { .AddAttrs(slog.String(stackKey, .Stack)) } return .handler.Handle(.ctx, ) } // Sync implements the [zapcore.Core] interface. func ( *Core) () error { return nil }