You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

95 lines
2.7 KiB

package logger
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
"path"
"runtime"
)
var project string // project absolute path
var logger *logCore // singleton logger handle
// logChannel handle multiple writers with unified format.
type logChannel struct {
encoder zapcore.Encoder
writers []zapcore.WriteSyncer
}
// logCore manage log level, channels and other interfaces.
type logCore struct {
prefix string // custom output prefix
verbose bool // show verbose information
plain logChannel // log channel with plain text
colored logChannel // log channel with colored text
level *zap.AtomicLevel // zap log level pointer
entry *zap.SugaredLogger // zap sugared logger entry
}
func init() {
_, src, _, _ := runtime.Caller(0) // absolute path of current code
project = path.Join(path.Dir(src), "../")
zapLevel := zap.NewAtomicLevelAt(InfoLevel) // using info level in default
logger = &logCore{
verbose: false,
level: &zapLevel,
prefix: "[XProxy]",
plain: buildChannel(false),
colored: buildChannel(true),
}
logger.addColoredWrites(os.Stderr) // output into stderr in default
}
// buildChannel generate logChannel with `colored` option.
func buildChannel(colored bool) logChannel {
config := zapcore.EncoderConfig{
ConsoleSeparator: " ",
MessageKey: "msg",
LevelKey: "level",
TimeKey: "time",
CallerKey: "caller",
EncodeTime: timeEncoder,
EncodeLevel: levelEncoder,
EncodeCaller: callerEncoder,
}
if colored { // using colored version
config.EncodeTime = timeColoredEncoder
config.EncodeLevel = levelColoredEncoder
config.EncodeCaller = callerColoredEncoder
}
return logChannel{
encoder: zapcore.NewConsoleEncoder(config),
writers: []zapcore.WriteSyncer{}, // without any writer
}
}
// update refreshes the binding of the log core to the writers.
func (handle *logCore) update() {
buildCore := func(channel *logChannel) zapcore.Core { // build zap core from logChannel
return zapcore.NewCore(
channel.encoder,
zap.CombineWriteSyncers(channel.writers...),
handle.level,
)
}
handle.entry = zap.New(
zapcore.NewTee(buildCore(&handle.plain), buildCore(&handle.colored)),
zap.AddCaller(), zap.AddCallerSkip(1),
).Sugar()
}
// addPlainWrites adds plain text writers to the logCore.
func (handle *logCore) addPlainWrites(writers ...zapcore.WriteSyncer) {
handle.plain.writers = append(handle.plain.writers, writers...)
handle.update()
}
// addColoredWrites adds colored text writers to the logCore.
func (handle *logCore) addColoredWrites(writers ...zapcore.WriteSyncer) {
handle.colored.writers = append(handle.colored.writers, writers...)
handle.update()
}