summaryrefslogtreecommitdiffstats
path: root/vendor/go.uber.org/zap/logger.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.uber.org/zap/logger.go')
-rw-r--r--vendor/go.uber.org/zap/logger.go41
1 files changed, 37 insertions, 4 deletions
diff --git a/vendor/go.uber.org/zap/logger.go b/vendor/go.uber.org/zap/logger.go
index cd6e1955..ea484aed 100644
--- a/vendor/go.uber.org/zap/logger.go
+++ b/vendor/go.uber.org/zap/logger.go
@@ -49,6 +49,7 @@ type Logger struct {
addStack zapcore.LevelEnabler
callerSkip int
+ onFatal zapcore.CheckWriteAction // default is WriteThenFatal
}
// New constructs a new Logger from the provided zapcore.Core and Options. If
@@ -280,7 +281,13 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry {
case zapcore.PanicLevel:
ce = ce.Should(ent, zapcore.WriteThenPanic)
case zapcore.FatalLevel:
- ce = ce.Should(ent, zapcore.WriteThenFatal)
+ onFatal := log.onFatal
+ // Noop is the default value for CheckWriteAction, and it leads to
+ // continued execution after a Fatal which is unexpected.
+ if onFatal == zapcore.WriteThenNoop {
+ onFatal = zapcore.WriteThenFatal
+ }
+ ce = ce.Should(ent, onFatal)
case zapcore.DPanicLevel:
if log.development {
ce = ce.Should(ent, zapcore.WriteThenPanic)
@@ -297,15 +304,41 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry {
// Thread the error output through to the CheckedEntry.
ce.ErrorOutput = log.errorOutput
if log.addCaller {
- ce.Entry.Caller = zapcore.NewEntryCaller(runtime.Caller(log.callerSkip + callerSkipOffset))
- if !ce.Entry.Caller.Defined {
+ frame, defined := getCallerFrame(log.callerSkip + callerSkipOffset)
+ if !defined {
fmt.Fprintf(log.errorOutput, "%v Logger.check error: failed to get caller\n", time.Now().UTC())
log.errorOutput.Sync()
}
+
+ ce.Entry.Caller = zapcore.EntryCaller{
+ Defined: defined,
+ PC: frame.PC,
+ File: frame.File,
+ Line: frame.Line,
+ Function: frame.Function,
+ }
}
if log.addStack.Enabled(ce.Entry.Level) {
- ce.Entry.Stack = Stack("").String
+ ce.Entry.Stack = StackSkip("", log.callerSkip+callerSkipOffset).String
}
return ce
}
+
+// getCallerFrame gets caller frame. The argument skip is the number of stack
+// frames to ascend, with 0 identifying the caller of getCallerFrame. The
+// boolean ok is false if it was not possible to recover the information.
+//
+// Note: This implementation is similar to runtime.Caller, but it returns the whole frame.
+func getCallerFrame(skip int) (frame runtime.Frame, ok bool) {
+ const skipOffset = 2 // skip getCallerFrame and Callers
+
+ pc := make([]uintptr, 1)
+ numFrames := runtime.Callers(skip+skipOffset, pc[:])
+ if numFrames < 1 {
+ return
+ }
+
+ frame, _ = runtime.CallersFrames(pc).Next()
+ return frame, frame.PC != 0
+}