From c1efa9a0ca2531e4d11cc688a593a846721432c9 Mon Sep 17 00:00:00 2001 From: Roi Feng <37480123+Rayzggz@users.noreply.github.com> Date: Mon, 28 Apr 2025 20:47:32 -0400 Subject: [PATCH] feat: Log tools --- go.mod | 3 + internal/utils/logx.go | 121 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 internal/utils/logx.go diff --git a/go.mod b/go.mod index 4a2a105..b7c019b 100644 --- a/go.mod +++ b/go.mod @@ -5,5 +5,8 @@ go 1.23.5 require ( github.com/cespare/xxhash/v2 v2.3.0 github.com/mssola/useragent v1.0.0 + go.uber.org/zap v1.27.0 gopkg.in/yaml.v3 v3.0.1 ) + +require go.uber.org/multierr v1.10.0 // indirect diff --git a/internal/utils/logx.go b/internal/utils/logx.go new file mode 100644 index 0000000..635015d --- /dev/null +++ b/internal/utils/logx.go @@ -0,0 +1,121 @@ +package utils + +import ( + "fmt" + "log" + "os" + "path/filepath" + "sync" + "time" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +type LogxManager struct { + basePath string + access *os.File + loggers map[string]*zap.Logger + mu sync.Mutex +} + +func NewManager(base string) *LogxManager { + m := &LogxManager{basePath: base, loggers: make(map[string]*zap.Logger)} + + if err := os.MkdirAll(m.basePath, 0744); err != nil { + log.Printf("failed to create base log dir %s: %v", m.basePath, err) + } + + accessPath := filepath.Join(m.basePath, "access.log") + f, err := os.OpenFile(accessPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + panic(fmt.Sprintf("failed to open access.log: %v", err)) + } + m.access = f + log.SetOutput(f) + return m +} + +func (m *LogxManager) getLogger(host string) *zap.Logger { + m.mu.Lock() + defer m.mu.Unlock() + if lg, ok := m.loggers[host]; ok { + return lg + } + + dir := filepath.Join(m.basePath, host) + if err := os.MkdirAll(dir, 0744); err != nil { + log.Printf("failed to create log dir %s: %v", dir, err) + } + + encCfg := zapcore.EncoderConfig{MessageKey: "msg", LineEnding: zapcore.DefaultLineEnding} + encoder := zapcore.NewConsoleEncoder(encCfg) + + infoOut := zapcore.AddSync(m.openLogFile(filepath.Join(dir, "info.log"))) + errorOut := zapcore.AddSync(m.openLogFile(filepath.Join(dir, "error.log"))) + dbgOut := zapcore.AddSync(m.openLogFile(filepath.Join(dir, "debug.log"))) + + infoLv := zap.LevelEnablerFunc(func(l zapcore.Level) bool { return l == zapcore.InfoLevel }) + errLv := zap.LevelEnablerFunc(func(l zapcore.Level) bool { return l >= zapcore.ErrorLevel }) + dbgLv := zap.LevelEnablerFunc(func(l zapcore.Level) bool { return l == zapcore.DebugLevel }) + + tee := zapcore.NewTee( + zapcore.NewCore(encoder, infoOut, infoLv), + zapcore.NewCore(encoder, errorOut, errLv), + zapcore.NewCore(encoder, dbgOut, dbgLv), + ) + lg := zap.New(tee) + m.loggers[host] = lg + return lg +} + +func (m *LogxManager) openLogFile(path string) *os.File { + f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Printf("failed to open log file %s: %v", path, err) + return os.Stdout + } + return f +} + +func (m *LogxManager) LogInfo(ip, host, uri, ua, msg, msg2 string) { + lg := m.getLogger(host) + line := fmt.Sprintf("%s - - [%s] %s %s %s %s %s", + ip, + time.Now().Format("02/Jan/2006:15:04:05 -0700"), + msg, + host, + uri, + ua, + msg2, + ) + lg.Info(line) +} + +func (m *LogxManager) LogError(ip, host, uri, ua, msg, msg2 string) { + lg := m.getLogger(host) + line := fmt.Sprintf("%s - - [%s] %s %s %s %s %s", + ip, + time.Now().Format("02/Jan/2006:15:04:05 -0700"), + msg, + host, + uri, + ua, + msg2, + ) + lg.Error(line) +} + +func (m *LogxManager) LogDebug(ip, host, uri, ua, msg, msg2 string) { + lg := m.getLogger(host) + line := fmt.Sprintf("%s - - [%s] %s %s %s %s %s", + ip, + time.Now().Format("02/Jan/2006:15:04:05 -0700"), + msg, + host, + uri, + ua, + msg2, + ) + lg.Debug(line) +}