-
Notifications
You must be signed in to change notification settings - Fork 385
/
logutil.go
161 lines (143 loc) · 4.4 KB
/
logutil.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package logutil
import (
"fmt"
"strings"
ipfs_log "github.com/ipfs/go-log/v2"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"moul.io/u"
"moul.io/zapfilter"
"berty.tech/berty/v2/go/pkg/errcode"
)
const (
consoleEncoding = "console"
jsonEncoding = "json"
)
func NewLogger(streams ...Stream) (*zap.Logger, func(), error) {
cores := []zapcore.Core{}
cleanup := func() {}
withIPFS := false
for _, opts := range streams {
if opts.filters == "" {
continue
}
var core zapcore.Core
// configure zap
var config zap.Config
switch strings.ToLower(opts.format) {
case "":
config = zap.NewDevelopmentConfig()
case "json":
config = zap.NewProductionConfig()
config.Development = true
config.Encoding = jsonEncoding
case "light-json":
config = zap.NewProductionConfig()
config.Encoding = jsonEncoding
config.EncoderConfig.TimeKey = ""
config.EncoderConfig.EncodeLevel = stableWidthCapitalLevelEncoder
config.Development = false
config.DisableStacktrace = true
config.Sampling = &zap.SamplingConfig{Initial: 100, Thereafter: 100}
case "light-console":
config = zap.NewDevelopmentConfig()
config.Encoding = consoleEncoding
config.EncoderConfig.TimeKey = ""
config.EncoderConfig.EncodeLevel = stableWidthCapitalLevelEncoder
config.DisableStacktrace = true
config.EncoderConfig.EncodeName = stableWidthNameEncoder
config.Development = false
config.Sampling = &zap.SamplingConfig{Initial: 100, Thereafter: 100}
case "light-color":
config = zap.NewDevelopmentConfig()
config.Encoding = consoleEncoding
config.EncoderConfig.TimeKey = ""
config.EncoderConfig.EncodeLevel = stableWidthCapitalColorLevelEncoder
config.DisableStacktrace = true
config.EncoderConfig.EncodeName = stableWidthNameEncoder
config.Development = false
config.Sampling = &zap.SamplingConfig{Initial: 100, Thereafter: 100}
case "console":
config = zap.NewDevelopmentConfig()
config.Encoding = consoleEncoding
config.EncoderConfig.EncodeTime = zapcore.RFC3339TimeEncoder
config.EncoderConfig.EncodeLevel = stableWidthCapitalLevelEncoder
config.DisableStacktrace = true
config.EncoderConfig.EncodeName = stableWidthNameEncoder
config.Development = true
case "color":
config = zap.NewDevelopmentConfig()
config.Encoding = consoleEncoding
config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
config.EncoderConfig.EncodeDuration = zapcore.StringDurationEncoder
config.EncoderConfig.EncodeLevel = stableWidthCapitalColorLevelEncoder
config.DisableStacktrace = true
config.EncoderConfig.EncodeName = stableWidthNameEncoder
config.Development = true
default:
return nil, nil, fmt.Errorf("unknown log format: %q", opts.format)
}
config.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
var enc zapcore.Encoder
switch config.Encoding {
case consoleEncoding:
enc = zapcore.NewConsoleEncoder(config.EncoderConfig)
case jsonEncoding:
enc = zapcore.NewJSONEncoder(config.EncoderConfig)
}
switch opts.kind {
case typeStd:
switch opts.path {
case "":
case "stdout", "stderr":
config.OutputPaths = []string{opts.path}
default:
config.OutputPaths = []string{opts.path}
}
logger, err := config.Build()
if err != nil {
return nil, nil, err
}
core = logger.Core()
case typeRing:
ring := opts.ring.SetEncoder(enc)
core = ring
case typeFile:
writer, err := newFileWriteCloser(opts.path, opts.sessionKind)
if err != nil {
return nil, nil, errcode.TODO.Wrap(err)
}
w := zapcore.AddSync(writer)
core = zapcore.NewCore(enc, w, config.Level)
cleanup = u.CombineFuncs(cleanup, func() { _ = writer.Close() })
case typeCustom:
core = opts.baseLogger.Core()
default:
return nil, nil, fmt.Errorf("unknown logger type: %q", opts.kind)
}
filter, err := zapfilter.ParseRules(opts.filters)
if err != nil {
return nil, nil, err
}
filtered := zapfilter.NewFilteringCore(core, filter)
if !withIPFS && zapfilter.CheckAnyLevel(zap.New(filtered).Named("ipfs")) {
withIPFS = true
}
cores = append(cores, filtered)
}
if len(cores) == 0 {
return zap.NewNop(), cleanup, nil
}
// combine cores
tee := zap.New(
zapcore.NewTee(cores...),
zap.AddCaller(),
)
if withIPFS {
ipfs_log.SetPrimaryCore(tee.Core())
} else {
ipfs_log.SetPrimaryCore(zapcore.NewNopCore())
}
cleanup = u.CombineFuncs(cleanup, func() { _ = tee.Sync() })
return tee.Named("bty"), cleanup, nil
}