-
Notifications
You must be signed in to change notification settings - Fork 641
/
log.go
125 lines (100 loc) · 2.81 KB
/
log.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package logging
import (
"io"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
var _ Logger = &log{}
type log struct {
wrappedCores []WrappedCore
internalLogger *zap.Logger
}
type WrappedCore struct {
Core zapcore.Core
Writer io.WriteCloser
WriterDisabled bool
AtomicLevel zap.AtomicLevel
}
func NewWrappedCore(level Level, rw io.WriteCloser, encoder zapcore.Encoder) WrappedCore {
atomicLevel := zap.NewAtomicLevelAt(zapcore.Level(level))
core := zapcore.NewCore(encoder, zapcore.AddSync(rw), atomicLevel)
return WrappedCore{AtomicLevel: atomicLevel, Core: core, Writer: rw}
}
func newZapLogger(prefix string, wrappedCores ...WrappedCore) *zap.Logger {
cores := make([]zapcore.Core, len(wrappedCores))
for i, wc := range wrappedCores {
cores[i] = wc.Core
}
core := zapcore.NewTee(cores...)
logger := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(2))
if prefix != "" {
logger = logger.Named(prefix)
}
return logger
}
// New returns a new logger set up according to [config]
func NewLogger(prefix string, wrappedCores ...WrappedCore) Logger {
return &log{
internalLogger: newZapLogger(prefix, wrappedCores...),
wrappedCores: wrappedCores,
}
}
func (l *log) Write(p []byte) (int, error) {
for _, wc := range l.wrappedCores {
if wc.WriterDisabled {
continue
}
_, _ = wc.Writer.Write(p)
}
return len(p), nil
}
func (l *log) Stop() {
for _, wc := range l.wrappedCores {
wc.Writer.Close()
}
}
// Should only be called from [Level] functions.
func (l *log) log(level Level, msg string, fields ...zap.Field) {
if ce := l.internalLogger.Check(zapcore.Level(level), msg); ce != nil {
ce.Write(fields...)
}
}
func (l *log) Fatal(msg string, fields ...zap.Field) {
l.log(Fatal, msg, fields...)
}
func (l *log) Error(msg string, fields ...zap.Field) {
l.log(Error, msg, fields...)
}
func (l *log) Warn(msg string, fields ...zap.Field) {
l.log(Warn, msg, fields...)
}
func (l *log) Info(msg string, fields ...zap.Field) {
l.log(Info, msg, fields...)
}
func (l *log) Trace(msg string, fields ...zap.Field) {
l.log(Trace, msg, fields...)
}
func (l *log) Debug(msg string, fields ...zap.Field) {
l.log(Debug, msg, fields...)
}
func (l *log) Verbo(msg string, fields ...zap.Field) {
l.log(Verbo, msg, fields...)
}
func (l *log) StopOnPanic() {
if r := recover(); r != nil {
l.Fatal("panicking", zap.Any("reason", r), zap.Stack("from"))
l.Stop()
panic(r)
}
}
func (l *log) RecoverAndPanic(f func()) { defer l.StopOnPanic(); f() }
func (l *log) stopAndExit(exit func()) {
if r := recover(); r != nil {
l.Fatal("panicking", zap.Any("reason", r), zap.Stack("from"))
l.Stop()
exit()
}
}
func (l *log) RecoverAndExit(f, exit func()) { defer l.stopAndExit(exit); f() }