Skip to content

Commit 3248e4c

Browse files
logging: Add zap.Option support (#5944)
1 parent da7d8cb commit 3248e4c

File tree

2 files changed

+88
-27
lines changed

2 files changed

+88
-27
lines changed

logging.go

Lines changed: 87 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,18 @@ func (logging *Logging) setupNewDefault(ctx Context) error {
150150
logging.Logs[DefaultLoggerName] = newDefault.CustomLog
151151
}
152152

153+
// options for the default logger
154+
options, err := newDefault.CustomLog.buildOptions()
155+
if err != nil {
156+
return fmt.Errorf("setting up default log: %v", err)
157+
}
158+
153159
// set up this new log
154-
err := newDefault.CustomLog.provision(ctx, logging)
160+
err = newDefault.CustomLog.provision(ctx, logging)
155161
if err != nil {
156162
return fmt.Errorf("setting up default log: %v", err)
157163
}
158-
newDefault.logger = zap.New(newDefault.CustomLog.core)
164+
newDefault.logger = zap.New(newDefault.CustomLog.core, options...)
159165

160166
// redirect the default caddy logs
161167
defaultLoggerMu.Lock()
@@ -201,6 +207,7 @@ func (logging *Logging) closeLogs() error {
201207
func (logging *Logging) Logger(mod Module) *zap.Logger {
202208
modID := string(mod.CaddyModule().ID)
203209
var cores []zapcore.Core
210+
var options []zap.Option
204211

205212
if logging != nil {
206213
for _, l := range logging.Logs {
@@ -209,14 +216,21 @@ func (logging *Logging) Logger(mod Module) *zap.Logger {
209216
cores = append(cores, l.core)
210217
continue
211218
}
219+
if len(options) == 0 {
220+
newOptions, err := l.buildOptions()
221+
if err != nil {
222+
Log().Error("building options for logger", zap.String("module", modID), zap.Error(err))
223+
}
224+
options = newOptions
225+
}
212226
cores = append(cores, &filteringCore{Core: l.core, cl: l})
213227
}
214228
}
215229
}
216230

217231
multiCore := zapcore.NewTee(cores...)
218232

219-
return zap.New(multiCore).Named(modID)
233+
return zap.New(multiCore, options...).Named(modID)
220234
}
221235

222236
// openWriter opens a writer using opener, and returns true if
@@ -277,6 +291,20 @@ type BaseLog struct {
277291
// servers.
278292
Sampling *LogSampling `json:"sampling,omitempty"`
279293

294+
// If true, the log entry will include the caller's
295+
// file name and line number. Default off.
296+
WithCaller bool `json:"with_caller,omitempty"`
297+
298+
// If non-zero, and `with_caller` is true, this many
299+
// stack frames will be skipped when determining the
300+
// caller. Default 0.
301+
WithCallerSkip int `json:"with_caller_skip,omitempty"`
302+
303+
// If not empty, the log entry will include a stack trace
304+
// for all logs at the given level or higher. See `level`
305+
// for possible values. Default off.
306+
WithStacktrace string `json:"with_stacktrace,omitempty"`
307+
280308
writerOpener WriterOpener
281309
writer io.WriteCloser
282310
encoder zapcore.Encoder
@@ -301,29 +329,10 @@ func (cl *BaseLog) provisionCommon(ctx Context, logging *Logging) error {
301329
return fmt.Errorf("opening log writer using %#v: %v", cl.writerOpener, err)
302330
}
303331

304-
repl := NewReplacer()
305-
level, err := repl.ReplaceOrErr(cl.Level, true, true)
306-
if err != nil {
307-
return fmt.Errorf("invalid log level: %v", err)
308-
}
309-
level = strings.ToLower(level)
310-
311332
// set up the log level
312-
switch level {
313-
case "debug":
314-
cl.levelEnabler = zapcore.DebugLevel
315-
case "", "info":
316-
cl.levelEnabler = zapcore.InfoLevel
317-
case "warn":
318-
cl.levelEnabler = zapcore.WarnLevel
319-
case "error":
320-
cl.levelEnabler = zapcore.ErrorLevel
321-
case "panic":
322-
cl.levelEnabler = zapcore.PanicLevel
323-
case "fatal":
324-
cl.levelEnabler = zapcore.FatalLevel
325-
default:
326-
return fmt.Errorf("unrecognized log level: %s", cl.Level)
333+
cl.levelEnabler, err = parseLevel(cl.Level)
334+
if err != nil {
335+
return err
327336
}
328337

329338
if cl.EncoderRaw != nil {
@@ -376,6 +385,24 @@ func (cl *BaseLog) buildCore() {
376385
cl.core = c
377386
}
378387

388+
func (cl *BaseLog) buildOptions() ([]zap.Option, error) {
389+
var options []zap.Option
390+
if cl.WithCaller {
391+
options = append(options, zap.AddCaller())
392+
if cl.WithCallerSkip != 0 {
393+
options = append(options, zap.AddCallerSkip(cl.WithCallerSkip))
394+
}
395+
}
396+
if cl.WithStacktrace != "" {
397+
levelEnabler, err := parseLevel(cl.WithStacktrace)
398+
if err != nil {
399+
return options, fmt.Errorf("setting up default Caddy log: %v", err)
400+
}
401+
options = append(options, zap.AddStacktrace(levelEnabler))
402+
}
403+
return options, nil
404+
}
405+
379406
// SinkLog configures the default Go standard library
380407
// global logger in the log package. This is necessary because
381408
// module dependencies which are not built specifically for
@@ -389,7 +416,14 @@ func (sll *SinkLog) provision(ctx Context, logging *Logging) error {
389416
if err := sll.provisionCommon(ctx, logging); err != nil {
390417
return err
391418
}
392-
ctx.cleanupFuncs = append(ctx.cleanupFuncs, zap.RedirectStdLog(zap.New(sll.core)))
419+
420+
options, err := sll.buildOptions()
421+
if err != nil {
422+
return err
423+
}
424+
425+
logger := zap.New(sll.core, options...)
426+
ctx.cleanupFuncs = append(ctx.cleanupFuncs, zap.RedirectStdLog(logger))
393427
return nil
394428
}
395429

@@ -678,6 +712,33 @@ func newDefaultProductionLogEncoder(colorize bool) zapcore.Encoder {
678712
return zapcore.NewJSONEncoder(encCfg)
679713
}
680714

715+
func parseLevel(levelInput string) (zapcore.LevelEnabler, error) {
716+
repl := NewReplacer()
717+
level, err := repl.ReplaceOrErr(levelInput, true, true)
718+
if err != nil {
719+
return nil, fmt.Errorf("invalid log level: %v", err)
720+
}
721+
level = strings.ToLower(level)
722+
723+
// set up the log level
724+
switch level {
725+
case "debug":
726+
return zapcore.DebugLevel, nil
727+
case "", "info":
728+
return zapcore.InfoLevel, nil
729+
case "warn":
730+
return zapcore.WarnLevel, nil
731+
case "error":
732+
return zapcore.ErrorLevel, nil
733+
case "panic":
734+
return zapcore.PanicLevel, nil
735+
case "fatal":
736+
return zapcore.FatalLevel, nil
737+
default:
738+
return nil, fmt.Errorf("unrecognized log level: %s", level)
739+
}
740+
}
741+
681742
// Log returns the current default logger.
682743
func Log() *zap.Logger {
683744
defaultLoggerMu.RLock()

modules/caddyhttp/reverseproxy/streaming.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func (h *Handler) handleUpgradeResponse(logger *zap.Logger, rw http.ResponseWrit
6868
//nolint:bodyclose
6969
conn, brw, hijackErr := http.NewResponseController(rw).Hijack()
7070
if errors.Is(hijackErr, http.ErrNotSupported) {
71-
h.logger.Sugar().Errorf("can't switch protocols using non-Hijacker ResponseWriter type %T", rw)
71+
h.logger.Error("can't switch protocols using non-Hijacker ResponseWriter", zap.String("type", fmt.Sprintf("%T", rw)))
7272
return
7373
}
7474

0 commit comments

Comments
 (0)