mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2024-12-30 02:37:01 +00:00
Refactor(log): use go.uber.org/zap (#389)
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
// Package log is a thin wrapper based on "go.uber.org/zap".
|
||||
package log
|
||||
+16
-13
@@ -1,7 +1,6 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"io"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -9,26 +8,30 @@ import (
|
||||
glog "gvisor.dev/gvisor/pkg/log"
|
||||
)
|
||||
|
||||
var _globalE = &emitter{}
|
||||
|
||||
func init() {
|
||||
EnableStackLog(true)
|
||||
glog.SetTarget(_globalE)
|
||||
}
|
||||
|
||||
func EnableStackLog(v bool) {
|
||||
if v {
|
||||
glog.SetTarget(&emitter{}) // built-in logger
|
||||
} else {
|
||||
glog.SetTarget(&glog.Writer{Next: io.Discard})
|
||||
}
|
||||
type emitter struct {
|
||||
logger *SugaredLogger
|
||||
}
|
||||
|
||||
type emitter struct{}
|
||||
func (e *emitter) setLogger(logger *SugaredLogger) {
|
||||
e.logger = logger.WithOptions(pkgCallerSkip)
|
||||
}
|
||||
|
||||
func (emitter) Emit(depth int, level glog.Level, _ time.Time, format string, args ...any) {
|
||||
func (e *emitter) logf(level glog.Level, format string, args ...any) {
|
||||
e.logger.Logf(1-Level(level), "[STACK] "+format, args...)
|
||||
}
|
||||
|
||||
func (e *emitter) Emit(depth int, level glog.Level, _ time.Time, format string, args ...any) {
|
||||
if _, file, line, ok := runtime.Caller(depth + 1); ok {
|
||||
// Ignore (*gonet.TCPConn).RemoteAddr() warning: `ep.GetRemoteAddress() failed`.
|
||||
if line == 457 && strings.HasSuffix(file, "/pkg/tcpip/adapters/gonet/gonet.go") {
|
||||
// Ignore: gvisor.dev/gvisor/pkg/tcpip/adapters/gonet/gonet.go:457
|
||||
if line == 457 && strings.HasSuffix(file, "gonet/gonet.go") {
|
||||
return
|
||||
}
|
||||
}
|
||||
logf(Level(level)+2, "[STACK] "+format, args...)
|
||||
e.logf(level, format, args...)
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/xjasonlyu/tun2socks/v2/common/observable"
|
||||
)
|
||||
|
||||
var (
|
||||
_logCh = make(chan any)
|
||||
_source = observable.NewObservable(_logCh)
|
||||
)
|
||||
|
||||
type Event struct {
|
||||
Level Level `json:"level"`
|
||||
Message string `json:"msg"`
|
||||
Time time.Time `json:"time"`
|
||||
}
|
||||
|
||||
func newEvent(level Level, format string, args ...any) *Event {
|
||||
event := &Event{
|
||||
Level: level,
|
||||
Time: time.Now(),
|
||||
Message: fmt.Sprintf(format, args...),
|
||||
}
|
||||
_logCh <- event /* send all events to logCh */
|
||||
|
||||
return event
|
||||
}
|
||||
|
||||
func Subscribe() observable.Subscription {
|
||||
sub, _ := _source.Subscribe()
|
||||
return sub
|
||||
}
|
||||
|
||||
func UnSubscribe(sub observable.Subscription) {
|
||||
_source.UnSubscribe(sub)
|
||||
}
|
||||
+18
-59
@@ -1,72 +1,31 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
type Level uint32
|
||||
// Level is an alias for zapcore.Level.
|
||||
type Level = zapcore.Level
|
||||
|
||||
// Levels are aliases for Level.
|
||||
const (
|
||||
SilentLevel Level = iota
|
||||
ErrorLevel
|
||||
WarnLevel
|
||||
InfoLevel
|
||||
DebugLevel
|
||||
DebugLevel = zapcore.DebugLevel
|
||||
InfoLevel = zapcore.InfoLevel
|
||||
WarnLevel = zapcore.WarnLevel
|
||||
ErrorLevel = zapcore.ErrorLevel
|
||||
DPanicLevel = zapcore.DPanicLevel
|
||||
PanicLevel = zapcore.PanicLevel
|
||||
FatalLevel = zapcore.FatalLevel
|
||||
InvalidLevel = zapcore.InvalidLevel
|
||||
SilentLevel = InvalidLevel + 1
|
||||
)
|
||||
|
||||
// UnmarshalJSON deserialize Level with json
|
||||
func (level *Level) UnmarshalJSON(data []byte) error {
|
||||
var lvl string
|
||||
if err := json.Unmarshal(data, &lvl); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l, err := ParseLevel(lvl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*level = l
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON serialize Level with json
|
||||
func (level Level) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(level.String())
|
||||
}
|
||||
|
||||
func (level Level) String() string {
|
||||
switch level {
|
||||
case DebugLevel:
|
||||
return "debug"
|
||||
case InfoLevel:
|
||||
return "info"
|
||||
case WarnLevel:
|
||||
return "warning"
|
||||
case ErrorLevel:
|
||||
return "error"
|
||||
case SilentLevel:
|
||||
return "silent"
|
||||
default:
|
||||
return fmt.Sprintf("not a valid level %d", level)
|
||||
}
|
||||
}
|
||||
|
||||
func ParseLevel(lvl string) (Level, error) {
|
||||
switch strings.ToLower(lvl) {
|
||||
case "silent":
|
||||
// ParseLevel is a thin wrapper for zapcore.ParseLevel.
|
||||
func ParseLevel(text string) (Level, error) {
|
||||
switch text {
|
||||
case "silent", "SILENT":
|
||||
return SilentLevel, nil
|
||||
case "error":
|
||||
return ErrorLevel, nil
|
||||
case "warning":
|
||||
return WarnLevel, nil
|
||||
case "info":
|
||||
return InfoLevel, nil
|
||||
case "debug":
|
||||
return DebugLevel, nil
|
||||
default:
|
||||
return Level(0), fmt.Errorf("not a valid logrus Level: %q", lvl)
|
||||
return zapcore.ParseLevel(text)
|
||||
}
|
||||
}
|
||||
|
||||
+58
-50
@@ -1,63 +1,71 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.uber.org/atomic"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// _defaultLevel is package default logging level.
|
||||
var _defaultLevel = atomic.NewUint32(uint32(InfoLevel))
|
||||
// global Logger and SugaredLogger.
|
||||
var (
|
||||
_globalMu sync.RWMutex
|
||||
_globalL *Logger
|
||||
_globalS *SugaredLogger
|
||||
)
|
||||
|
||||
func init() {
|
||||
logrus.SetOutput(os.Stdout)
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
SetLogger(zap.Must(zap.NewProduction()))
|
||||
}
|
||||
|
||||
func SetOutput(out io.Writer) {
|
||||
logrus.SetOutput(out)
|
||||
}
|
||||
|
||||
func SetLevel(level Level) {
|
||||
_defaultLevel.Store(uint32(level))
|
||||
}
|
||||
|
||||
func Debugf(format string, args ...any) {
|
||||
logf(DebugLevel, format, args...)
|
||||
}
|
||||
|
||||
func Infof(format string, args ...any) {
|
||||
logf(InfoLevel, format, args...)
|
||||
}
|
||||
|
||||
func Warnf(format string, args ...any) {
|
||||
logf(WarnLevel, format, args...)
|
||||
}
|
||||
|
||||
func Errorf(format string, args ...any) {
|
||||
logf(ErrorLevel, format, args...)
|
||||
}
|
||||
|
||||
func Fatalf(format string, args ...any) {
|
||||
logrus.Fatalf(format, args...)
|
||||
}
|
||||
|
||||
func logf(level Level, format string, args ...any) {
|
||||
event := newEvent(level, format, args...)
|
||||
if uint32(event.Level) > _defaultLevel.Load() {
|
||||
return
|
||||
}
|
||||
|
||||
switch level {
|
||||
func NewLeveled(l Level, options ...Option) (*Logger, error) {
|
||||
switch l {
|
||||
case SilentLevel:
|
||||
return zap.NewNop(), nil
|
||||
case DebugLevel:
|
||||
logrus.WithTime(event.Time).Debugln(event.Message)
|
||||
case InfoLevel:
|
||||
logrus.WithTime(event.Time).Infoln(event.Message)
|
||||
case WarnLevel:
|
||||
logrus.WithTime(event.Time).Warnln(event.Message)
|
||||
case ErrorLevel:
|
||||
logrus.WithTime(event.Time).Errorln(event.Message)
|
||||
return zap.NewDevelopment(options...)
|
||||
case InfoLevel, WarnLevel, ErrorLevel, DPanicLevel, PanicLevel, FatalLevel:
|
||||
cfg := zap.NewProductionConfig()
|
||||
cfg.Level.SetLevel(l)
|
||||
return cfg.Build(options...)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid level: %s", l)
|
||||
}
|
||||
}
|
||||
|
||||
// SetLogger sets the global Logger and SugaredLogger.
|
||||
func SetLogger(logger *Logger) {
|
||||
_globalMu.Lock()
|
||||
defer _globalMu.Unlock()
|
||||
// apply pkgCallerSkip to global loggers.
|
||||
_globalL = logger.WithOptions(pkgCallerSkip)
|
||||
_globalS = _globalL.Sugar()
|
||||
_globalE.setLogger(_globalS)
|
||||
}
|
||||
|
||||
func logf(lvl Level, template string, args ...any) {
|
||||
_globalMu.RLock()
|
||||
s := _globalS
|
||||
_globalMu.RUnlock()
|
||||
s.Logf(lvl, template, args...)
|
||||
}
|
||||
|
||||
func Debugf(template string, args ...any) {
|
||||
logf(DebugLevel, template, args...)
|
||||
}
|
||||
|
||||
func Infof(template string, args ...any) {
|
||||
logf(InfoLevel, template, args...)
|
||||
}
|
||||
|
||||
func Warnf(template string, args ...any) {
|
||||
logf(WarnLevel, template, args...)
|
||||
}
|
||||
|
||||
func Errorf(template string, args ...any) {
|
||||
logf(ErrorLevel, template, args...)
|
||||
}
|
||||
|
||||
func Fatalf(template string, args ...any) {
|
||||
logf(FatalLevel, template, args...)
|
||||
}
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Must is an alias for zap.Must.
|
||||
var Must = zap.Must
|
||||
|
||||
// logger aliases for zap.Logger and zap.SugaredLogger.
|
||||
type (
|
||||
Logger = zap.Logger
|
||||
SugaredLogger = zap.SugaredLogger
|
||||
)
|
||||
|
||||
type (
|
||||
// Option is an alias for zap.Option.
|
||||
Option = zap.Option
|
||||
)
|
||||
|
||||
// pkgCallerSkip skips the pkg wrapper code as the caller.
|
||||
var pkgCallerSkip = zap.AddCallerSkip(2)
|
||||
Reference in New Issue
Block a user