Browse Source

feat: log module supports multiple outputs

dev
Dnomd343 1 year ago
parent
commit
29ad4e4b84
  1. 62
      next/logger/encoder.go
  2. 14
      next/logger/interface.go
  3. 63
      next/logger/logger.go
  4. 30
      next/main.go

62
next/logger/encoder.go

@ -1,46 +1,58 @@
package logger package logger
import ( import (
"github.com/fatih/color" "fmt"
"github.com/gookit/color"
"go.uber.org/zap/zapcore" "go.uber.org/zap/zapcore"
"time" "time"
) )
func encodeTime(t time.Time, enc zapcore.PrimitiveArrayEncoder) { // timeEncoder formats the time as a string.
func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006-01-02 15:04:05.000")) enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
} }
func encodeColoredTime(t time.Time, enc zapcore.PrimitiveArrayEncoder) { // timeColoredEncoder formats the time as a colored string
enc.AppendString(color.WhiteString(t.Format("2006-01-02 15:04:05.000"))) // with `[XProxy]` prefix.
func timeColoredEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(fmt.Sprintf(
"%s %s",
color.Cyan.Render("[XProxy]"),
color.Gray.Render(t.Format("2006-01-02 15:04:05.000")),
))
} }
func encodeCaller(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { // callerEncoder formats caller in square brackets.
func callerEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString("[" + caller.TrimmedPath() + "]") enc.AppendString("[" + caller.TrimmedPath() + "]")
} }
func encodeColoredCaller(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { // callerColoredEncoder formats caller in square brackets
enc.AppendString(color.MagentaString("[" + caller.TrimmedPath() + "]")) // with magenta color.
func callerColoredEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(color.Magenta.Render("[" + caller.TrimmedPath() + "]"))
} }
func encodeLevel(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { // levelEncoder formats log level using square brackets.
func levelEncoder(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString("[" + level.CapitalString() + "]") enc.AppendString("[" + level.CapitalString() + "]")
} }
func encodeColoredLevel(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { // levelColoredEncoder formats log level using square brackets
enc.AppendString(func(level zapcore.Level) func(string, ...interface{}) string { // and uses different colors.
switch level { func levelColoredEncoder(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
case zapcore.DebugLevel: levelStr := "[" + level.CapitalString() + "]"
return color.CyanString switch level {
case zapcore.InfoLevel: case zapcore.DebugLevel:
return color.GreenString levelStr = color.FgDefault.Render(levelStr)
case zapcore.WarnLevel: case zapcore.InfoLevel:
return color.YellowString levelStr = color.Green.Render(levelStr)
case zapcore.ErrorLevel: case zapcore.WarnLevel:
return color.RedString levelStr = color.Yellow.Render(levelStr)
case zapcore.PanicLevel: case zapcore.ErrorLevel:
return color.HiRedString levelStr = color.Red.Render(levelStr)
default: case zapcore.PanicLevel:
return color.WhiteString levelStr = color.LightRed.Render(levelStr)
} }
}(level)("[" + level.CapitalString() + "]")) enc.AppendString(levelStr)
} }

14
next/logger/interface.go

@ -1,6 +1,9 @@
package logger package logger
import "go.uber.org/zap/zapcore" import (
"go.uber.org/zap/zapcore"
"io"
)
const ( const (
DebugLevel = zapcore.DebugLevel DebugLevel = zapcore.DebugLevel
@ -37,3 +40,12 @@ func Errorf(template string, args ...interface{}) {
func Panicf(template string, args ...interface{}) { func Panicf(template string, args ...interface{}) {
handle.sugar.Panicf(template, args...) handle.sugar.Panicf(template, args...)
} }
// AddOutputs adds more plain log outputs.
func AddOutputs(outputs ...io.Writer) {
var writers []zapcore.WriteSyncer
for _, output := range outputs {
writers = append(writers, zapcore.AddSync(output))
}
addWrites(writers...)
}

63
next/logger/logger.go

@ -3,59 +3,66 @@ package logger
import ( import (
"go.uber.org/zap" "go.uber.org/zap"
"go.uber.org/zap/zapcore" "go.uber.org/zap/zapcore"
"os"
) )
type Logger struct { type Logger struct {
logger *zap.Logger logger *zap.Logger
level *zap.AtomicLevel level *zap.AtomicLevel
sugar *zap.SugaredLogger sugar *zap.SugaredLogger
writers []zapcore.WriteSyncer
stdCore zapcore.Core
} }
var handle Logger var handle Logger
func logConfig(level zap.AtomicLevel, colored bool) zapcore.EncoderConfig { // logConfig generates log config for XProxy.
func logConfig(colored bool) zapcore.EncoderConfig {
config := zapcore.EncoderConfig{ config := zapcore.EncoderConfig{
ConsoleSeparator: " ", ConsoleSeparator: " ",
MessageKey: "msg", MessageKey: "msg",
LevelKey: "level", LevelKey: "level",
TimeKey: "time", TimeKey: "time",
CallerKey: "caller", CallerKey: "caller",
EncodeTime: encodeTime, EncodeTime: timeEncoder,
EncodeLevel: encodeLevel, EncodeLevel: levelEncoder,
EncodeCaller: encodeCaller, EncodeCaller: callerEncoder,
} }
if colored { if colored {
config.EncodeTime = encodeColoredTime config.EncodeTime = timeColoredEncoder
config.EncodeLevel = encodeColoredLevel config.EncodeLevel = levelColoredEncoder
config.EncodeCaller = encodeColoredCaller config.EncodeCaller = callerColoredEncoder
} }
return config return config
} }
func init() { func init() {
level := zap.NewAtomicLevelAt(DebugLevel) level := zap.NewAtomicLevelAt(DebugLevel)
writer, _, _ := zap.Open("/dev/stderr", "/root/XProxy/next/lalala.log")
core := zapcore.NewCore( core := zapcore.NewCore(
zapcore.NewConsoleEncoder(logConfig(level, false)), zapcore.NewConsoleEncoder(logConfig(true)),
//zapcore.Lock(os.Stderr), zapcore.Lock(os.Stderr), level,
writer,
level,
) )
//zapcore.AddSync()
//zap.Open()
//return core
logger := zap.New(core, zap.AddCaller()) logger := zap.New(core, zap.AddCaller())
handle = Logger{ handle = Logger{
logger: logger, logger: logger,
level: &level, level: &level,
sugar: logger.Sugar(), sugar: logger.Sugar(),
writers: []zapcore.WriteSyncer{},
stdCore: core,
} }
}
// addWrites adds more plain log writers.
func addWrites(writers ...zapcore.WriteSyncer) {
handle.writers = append(handle.writers, writers...)
plainCore := zapcore.NewCore(
zapcore.NewConsoleEncoder(logConfig(false)),
zap.CombineWriteSyncers(handle.writers...),
handle.level,
)
handle.logger = zap.New(
zapcore.NewTee(handle.stdCore, plainCore),
zap.AddCaller(),
)
handle.sugar = handle.logger.Sugar()
} }

30
next/main.go

@ -1,13 +1,33 @@
package main package main
import "XProxy/next/logger" import (
"XProxy/next/logger"
"os"
)
func main() { func main() {
logger.Debugf("here is %s level", "debug") //logger.Debugf("here is %s level", "debug")
logger.Infof("here is %s level", "info") //logger.Infof("here is %s level", "info")
logger.Warnf("here is %s level", "warn") //logger.Warnf("here is %s level", "warn")
logger.Errorf("here is %s level", "error") //logger.Errorf("here is %s level", "error")
//logger.Panicf("here is %s level", "panic") //logger.Panicf("here is %s level", "panic")
fp1, _ := os.Create("demo_1.log")
fp2, _ := os.Create("demo_2.log")
fp3, _ := os.Create("demo_3.log")
logger.Debugf("output msg 1 at debug")
logger.Infof("output msg 1 at info")
logger.Warnf("output msg 1 at warn")
logger.AddOutputs(fp1, fp2)
logger.SetLevel(logger.InfoLevel)
logger.Debugf("output msg 2 at debug")
logger.Infof("output msg 2 at info")
logger.Warnf("output msg 2 at warn")
logger.SetLevel(logger.WarnLevel)
logger.AddOutputs(fp3)
logger.Debugf("output msg 3 at debug")
logger.Infof("output msg 3 at info")
logger.Warnf("output msg 3 at warn")
} }

Loading…
Cancel
Save