@@ -93,6 +93,64 @@ func DefaultConfig() Config {
9393 }
9494}
9595
96+ type LoggerOptions func (* Config )
97+
98+ func NewConfig (options ... LoggerOptions ) Config {
99+ config := DefaultConfig ()
100+ for _ , option := range options {
101+ option (& config )
102+ }
103+ return config
104+ }
105+
106+ func WithLogLevel (level Level ) LoggerOptions {
107+ return func (c * Config ) {
108+ c .Level = level
109+ }
110+ }
111+
112+ func WithLogFormat (format Format ) LoggerOptions {
113+ return func (c * Config ) {
114+ c .Format = format
115+ }
116+ }
117+
118+ func WithColorize (colorize bool ) LoggerOptions {
119+ return func (c * Config ) {
120+ c .Colorize = colorize
121+ }
122+ }
123+
124+ func WithShowCaller (showCaller bool ) LoggerOptions {
125+ return func (c * Config ) {
126+ c .ShowCaller = showCaller
127+ }
128+ }
129+
130+ func WithTimeFormat (timeFormat string ) LoggerOptions {
131+ return func (c * Config ) {
132+ c .TimeFormat = timeFormat
133+ }
134+ }
135+
136+ func WithOutput (output io.Writer ) LoggerOptions {
137+ return func (c * Config ) {
138+ c .Output = output
139+ }
140+ }
141+
142+ func WithErrorOutput (errorOutput io.Writer ) LoggerOptions {
143+ return func (c * Config ) {
144+ c .ErrorOutput = errorOutput
145+ }
146+ }
147+
148+ func WithDefaultCallerSkip (callerSkip int ) LoggerOptions {
149+ return func (c * Config ) {
150+ c .CallerSkip = callerSkip
151+ }
152+ }
153+
96154// Logger is a structured, thread-safe logger
97155type Logger struct {
98156 mu sync.Mutex
@@ -123,13 +181,8 @@ func (l *Logger) WithFields(fields map[string]any) *Logger {
123181 l .mu .Lock ()
124182 defer l .mu .Unlock ()
125183
126- newFields := make (map [string ]any )
127- for k , v := range l .fields {
128- newFields [k ] = v
129- }
130- for k , v := range fields {
131- newFields [k ] = v
132- }
184+ newFields := maps .Clone (l .fields )
185+ maps .Copy (newFields , fields )
133186
134187 return & Logger {
135188 config : l .config ,
0 commit comments