This commit is contained in:
2025-06-25 00:01:48 +08:00
parent 3d53c9ec59
commit 53106465ed
30 changed files with 2108 additions and 6 deletions

View File

@@ -0,0 +1,23 @@
package log
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
var logLevelMap = map[string]zapcore.Level{
"panic": zap.DPanicLevel,
"fatal": zap.FatalLevel,
"error": zap.ErrorLevel,
"warn": zap.WarnLevel,
"info": zap.InfoLevel,
"debug": zap.DebugLevel,
}
// GetLogLevel get the logLevel from logLevelName
func GetLogLevel(logLevelName string) zapcore.Level {
if v, ok := logLevelMap[logLevelName]; ok {
return v
}
return zap.DebugLevel
}

66
Server/common/log/log.go Normal file
View File

@@ -0,0 +1,66 @@
package log
import "go.uber.org/zap"
var globalLogger *zap.SugaredLogger
// SetLogger 设置日志记录器
func SetLogger(logger *zap.SugaredLogger) {
if logger == nil {
return
}
globalLogger = logger
}
func GetLogger() *zap.SugaredLogger {
return globalLogger
}
// Debugf 打印调试模板日志
func Debugf(format string, a ...interface{}) {
if globalLogger != nil {
globalLogger.Debugf(format, a...)
}
}
// Infof 打印信息模板日志
func Infof(format string, a ...interface{}) {
if globalLogger != nil {
globalLogger.Infof(format, a...)
}
}
// Warnf 打印警告模板日志
func Warnf(format string, a ...interface{}) {
if globalLogger != nil {
globalLogger.Warnf(format, a...)
}
}
// Errorf 打印错误模板日志
func Errorf(format string, a ...interface{}) {
if globalLogger != nil {
globalLogger.Errorf(format, a...)
}
}
// Panicf 打印Panic模板日志
func Panicf(format string, a ...interface{}) {
if globalLogger != nil {
globalLogger.Panicf(format, a...)
}
}
// Fatalf 打印致命错误模板日志
func Fatalf(format string, a ...interface{}) {
if globalLogger != nil {
globalLogger.Fatalf(format, a...)
}
}
// Close 关闭日志
func Close() {
if globalLogger != nil {
_ = globalLogger.Sync()
}
}

View File

@@ -0,0 +1,62 @@
package log
import (
commonConfig "common/config"
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
)
func Init(cfg *commonConfig.LoggerConfig) {
// 格式配置
jsonConfig := zapcore.EncoderConfig{
MessageKey: "M",
LevelKey: "L",
TimeKey: "T",
NameKey: "N",
CallerKey: "C",
FunctionKey: zapcore.OmitKey,
StacktraceKey: "S",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.CapitalLevelEncoder,
EncodeTime: zapcore.TimeEncoderOfLayout("01-02 15:04:05.000"),
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
EncodeName: nil,
ConsoleSeparator: " ",
}
// 日志输出到控制台和文件
writeSyncer := []zapcore.WriteSyncer{zapcore.AddSync(os.Stdout)}
if !cfg.Debug {
writeSyncer = append(writeSyncer, zapcore.AddSync(&lumberjack.Logger{
Filename: "./logs/log.log", // 日志文件位置
MaxSize: cfg.MaxSize, // 最大文件大小MB
MaxBackups: cfg.MaxBackUp, // 保留旧文件的最大个数
MaxAge: cfg.MaxAge, // 保留旧文件的最大天数
Compress: false, // 是否压缩/归档旧文件
LocalTime: true,
}))
}
var encoder zapcore.Encoder
if cfg.Debug {
encoder = zapcore.NewConsoleEncoder(jsonConfig)
} else {
encoder = zapcore.NewJSONEncoder(jsonConfig)
}
logger := zap.New(zapcore.NewCore(
encoder,
zapcore.NewMultiWriteSyncer(writeSyncer...),
zap.NewAtomicLevelAt(GetLogLevel(cfg.Level)),
))
if cfg.Debug {
logger = logger.WithOptions(
zap.AddCaller(),
zap.AddCallerSkip(1),
zap.AddStacktrace(zapcore.WarnLevel),
)
}
SetLogger(logger.Sugar())
}

135
Server/common/log/sentry.go Normal file
View File

@@ -0,0 +1,135 @@
package log
import (
"go.uber.org/zap/zapcore"
"time"
)
import "github.com/getsentry/sentry-go"
type SentryCoreConfig struct {
Tags map[string]string
AttachStacktrace bool
Level zapcore.Level
FlushTimeout time.Duration
Hub *sentry.Hub
Platform string
}
type sentryCore struct {
zapcore.LevelEnabler
client sentry.Client
cfg SentryCoreConfig
flushTimeout time.Duration
fields map[string]interface{}
}
func (c *sentryCore) with(fs []zapcore.Field) *sentryCore {
m := make(map[string]interface{}, len(c.fields))
for k, v := range c.fields {
m[k] = v
}
enc := zapcore.NewMapObjectEncoder()
for _, f := range fs {
f.AddTo(enc)
}
for k, v := range enc.Fields {
m[k] = v
}
return &sentryCore{
client: c.client,
cfg: c.cfg,
fields: m,
LevelEnabler: c.LevelEnabler,
}
}
func (c *sentryCore) With(fs []zapcore.Field) zapcore.Core {
return c.with(fs)
}
func (c *sentryCore) Check(ent zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry {
if c.cfg.Level.Enabled(ent.Level) {
return ce.AddCore(ent, c)
}
return ce
}
func (c *sentryCore) Write(ent zapcore.Entry, fs []zapcore.Field) error {
clone := c.with(fs)
event := sentry.NewEvent()
event.Message = ent.Message
event.Timestamp = ent.Time
event.Level = sentryLevel(ent.Level)
event.Platform = c.cfg.Platform
event.Extra = clone.fields
event.Tags = c.cfg.Tags
if c.cfg.AttachStacktrace {
trace := sentry.NewStacktrace()
if trace != nil {
event.Exception = []sentry.Exception{
{
Type: ent.Message,
Value: ent.Caller.TrimmedPath(),
Stacktrace: trace,
},
}
}
}
hub := c.cfg.Hub
if hub == nil {
hub = sentry.CurrentHub()
}
_ = c.client.CaptureEvent(event, nil, hub.Scope())
if ent.Level > zapcore.ErrorLevel {
c.client.Flush(c.flushTimeout)
}
return nil
}
func (c *sentryCore) Sync() error {
c.client.Flush(c.flushTimeout)
return nil
}
func NewSentryCore(cfg SentryCoreConfig, sentryClient *sentry.Client) zapcore.Core {
core := sentryCore{
client: *sentryClient,
cfg: cfg,
LevelEnabler: cfg.Level,
flushTimeout: 3 * time.Second,
fields: make(map[string]interface{}),
}
if cfg.FlushTimeout > 0 {
core.flushTimeout = cfg.FlushTimeout
}
return &core
}
func sentryLevel(lvl zapcore.Level) sentry.Level {
switch lvl {
case zapcore.DebugLevel:
return sentry.LevelDebug
case zapcore.InfoLevel:
return sentry.LevelInfo
case zapcore.WarnLevel:
return sentry.LevelWarning
case zapcore.ErrorLevel:
return sentry.LevelError
case zapcore.DPanicLevel:
return sentry.LevelFatal
case zapcore.PanicLevel:
return sentry.LevelFatal
case zapcore.FatalLevel:
return sentry.LevelFatal
default:
return sentry.LevelFatal
}
}