Browse Source

feat: log module supports multiple outputs

dev
Dnomd343 10 months 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
import (
"github.com/fatih/color"
"fmt"
"github.com/gookit/color"
"go.uber.org/zap/zapcore"
"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"))
}
func encodeColoredTime(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(color.WhiteString(t.Format("2006-01-02 15:04:05.000")))
// timeColoredEncoder formats the time as a colored string
// 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() + "]")
}
func encodeColoredCaller(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(color.MagentaString("[" + caller.TrimmedPath() + "]"))
// callerColoredEncoder formats caller in square brackets
// 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() + "]")
}
func encodeColoredLevel(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(func(level zapcore.Level) func(string, ...interface{}) string {
switch level {
case zapcore.DebugLevel:
return color.CyanString
case zapcore.InfoLevel:
return color.GreenString
case zapcore.WarnLevel:
return color.YellowString
case zapcore.ErrorLevel:
return color.RedString
case zapcore.PanicLevel:
return color.HiRedString
default:
return color.WhiteString
}
}(level)("[" + level.CapitalString() + "]"))
// levelColoredEncoder formats log level using square brackets
// and uses different colors.
func levelColoredEncoder(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
levelStr := "[" + level.CapitalString() + "]"
switch level {
case zapcore.DebugLevel:
levelStr = color.FgDefault.Render(levelStr)
case zapcore.InfoLevel:
levelStr = color.Green.Render(levelStr)
case zapcore.WarnLevel:
levelStr = color.Yellow.Render(levelStr)
case zapcore.ErrorLevel:
levelStr = color.Red.Render(levelStr)
case zapcore.PanicLevel:
levelStr = color.LightRed.Render(levelStr)
}
enc.AppendString(levelStr)
}

14
next/logger/interface.go

@ -1,6 +1,9 @@
package logger
import "go.uber.org/zap/zapcore"
import (
"go.uber.org/zap/zapcore"
"io"
)
const (
DebugLevel = zapcore.DebugLevel
@ -37,3 +40,12 @@ func Errorf(template string, args ...interface{}) {
func Panicf(template string, args ...interface{}) {
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 (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
)
type Logger struct {
logger *zap.Logger
level *zap.AtomicLevel
sugar *zap.SugaredLogger
logger *zap.Logger
level *zap.AtomicLevel
sugar *zap.SugaredLogger
writers []zapcore.WriteSyncer
stdCore zapcore.Core
}
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{
ConsoleSeparator: " ",
MessageKey: "msg",
LevelKey: "level",
TimeKey: "time",
CallerKey: "caller",
EncodeTime: encodeTime,
EncodeLevel: encodeLevel,
EncodeCaller: encodeCaller,
EncodeTime: timeEncoder,
EncodeLevel: levelEncoder,
EncodeCaller: callerEncoder,
}
if colored {
config.EncodeTime = encodeColoredTime
config.EncodeLevel = encodeColoredLevel
config.EncodeCaller = encodeColoredCaller
config.EncodeTime = timeColoredEncoder
config.EncodeLevel = levelColoredEncoder
config.EncodeCaller = callerColoredEncoder
}
return config
}
func init() {
level := zap.NewAtomicLevelAt(DebugLevel)
writer, _, _ := zap.Open("/dev/stderr", "/root/XProxy/next/lalala.log")
core := zapcore.NewCore(
zapcore.NewConsoleEncoder(logConfig(level, false)),
//zapcore.Lock(os.Stderr),
writer,
level,
zapcore.NewConsoleEncoder(logConfig(true)),
zapcore.Lock(os.Stderr), level,
)
//zapcore.AddSync()
//zap.Open()
//return core
logger := zap.New(core, zap.AddCaller())
handle = Logger{
logger: logger,
level: &level,
sugar: logger.Sugar(),
logger: logger,
level: &level,
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
import "XProxy/next/logger"
import (
"XProxy/next/logger"
"os"
)
func main() {
logger.Debugf("here is %s level", "debug")
logger.Infof("here is %s level", "info")
logger.Warnf("here is %s level", "warn")
logger.Errorf("here is %s level", "error")
//logger.Debugf("here is %s level", "debug")
//logger.Infof("here is %s level", "info")
//logger.Warnf("here is %s level", "warn")
//logger.Errorf("here is %s level", "error")
//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