This commit is contained in:
2025-08-27 22:19:19 +08:00
parent 4031277a91
commit 5051aea55c
93 changed files with 2025 additions and 1168 deletions

View File

@@ -19,6 +19,9 @@ type ExternalServiceLoggingConfig struct {
UseDaily bool `yaml:"use_daily"`
EnableLevelSeparation bool `yaml:"enable_level_separation"`
LevelConfigs map[string]ExternalServiceLevelFileConfig `yaml:"level_configs"`
// 新增:请求和响应日志的独立配置
RequestLogConfig ExternalServiceLevelFileConfig `yaml:"request_log_config"`
ResponseLogConfig ExternalServiceLevelFileConfig `yaml:"response_log_config"`
}
// ExternalServiceLevelFileConfig 外部服务级别文件配置
@@ -34,6 +37,9 @@ type ExternalServiceLogger struct {
logger *zap.Logger
config ExternalServiceLoggingConfig
serviceName string
// 新增:用于区分请求和响应日志的字段
requestLogger *zap.Logger
responseLogger *zap.Logger
}
// NewExternalServiceLogger 创建外部服务日志器
@@ -64,6 +70,21 @@ func NewExternalServiceLogger(config ExternalServiceLoggingConfig) (*ExternalSer
return nil, fmt.Errorf("创建基础logger失败: %w", err)
}
// 创建请求和响应日志器
requestLogger, err := createRequestLogger(serviceLogDir, config)
if err != nil {
// 如果创建失败使用基础logger作为备选
requestLogger = baseLogger
fmt.Printf("创建请求日志器失败使用基础logger: %v\n", err)
}
responseLogger, err := createResponseLogger(serviceLogDir, config)
if err != nil {
// 如果创建失败使用基础logger作为备选
responseLogger = baseLogger
fmt.Printf("创建响应日志器失败使用基础logger: %v\n", err)
}
// 如果启用级别分离,创建文件输出
if config.EnableLevelSeparation {
core := createSeparatedCore(serviceLogDir, config)
@@ -72,9 +93,11 @@ func NewExternalServiceLogger(config ExternalServiceLoggingConfig) (*ExternalSer
// 创建日志器实例
logger := &ExternalServiceLogger{
logger: baseLogger,
config: config,
serviceName: config.ServiceName,
logger: baseLogger,
config: config,
serviceName: config.ServiceName,
requestLogger: requestLogger,
responseLogger: responseLogger,
}
// 如果启用按天分隔,启动定时清理任务
@@ -85,6 +108,72 @@ func NewExternalServiceLogger(config ExternalServiceLoggingConfig) (*ExternalSer
return logger, nil
}
// createRequestLogger 创建请求日志器
func createRequestLogger(logDir string, config ExternalServiceLoggingConfig) (*zap.Logger, error) {
// 创建编码器
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.TimeKey = "timestamp"
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
// 使用默认配置如果未指定
requestConfig := config.RequestLogConfig
if requestConfig.MaxSize == 0 {
requestConfig.MaxSize = 100
}
if requestConfig.MaxBackups == 0 {
requestConfig.MaxBackups = 5
}
if requestConfig.MaxAge == 0 {
requestConfig.MaxAge = 30
}
// 创建请求日志文件写入器
requestWriter := createFileWriter(logDir, "request", requestConfig, config.ServiceName, config.UseDaily)
// 创建请求日志核心
requestCore := zapcore.NewCore(
zapcore.NewJSONEncoder(encoderConfig),
zapcore.AddSync(requestWriter),
zapcore.InfoLevel,
)
return zap.New(requestCore), nil
}
// createResponseLogger 创建响应日志器
func createResponseLogger(logDir string, config ExternalServiceLoggingConfig) (*zap.Logger, error) {
// 创建编码器
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.TimeKey = "timestamp"
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
// 使用默认配置如果未指定
responseConfig := config.ResponseLogConfig
if responseConfig.MaxSize == 0 {
responseConfig.MaxSize = 100
}
if responseConfig.MaxBackups == 0 {
responseConfig.MaxBackups = 5
}
if responseConfig.MaxAge == 0 {
responseConfig.MaxAge = 30
}
// 创建响应日志文件写入器
responseWriter := createFileWriter(logDir, "response", responseConfig, config.ServiceName, config.UseDaily)
// 创建响应日志核心
responseCore := zapcore.NewCore(
zapcore.NewJSONEncoder(encoderConfig),
zapcore.AddSync(responseWriter),
zapcore.InfoLevel,
)
return zap.New(responseCore), nil
}
// createSeparatedCore 创建分离的日志核心
func createSeparatedCore(logDir string, config ExternalServiceLoggingConfig) zapcore.Core {
// 创建编码器
@@ -97,6 +186,10 @@ func createSeparatedCore(logDir string, config ExternalServiceLoggingConfig) zap
infoWriter := createFileWriter(logDir, "info", config.LevelConfigs["info"], config.ServiceName, config.UseDaily)
errorWriter := createFileWriter(logDir, "error", config.LevelConfigs["error"], config.ServiceName, config.UseDaily)
warnWriter := createFileWriter(logDir, "warn", config.LevelConfigs["warn"], config.ServiceName, config.UseDaily)
// 新增:请求和响应日志的独立文件输出
requestWriter := createFileWriter(logDir, "request", config.RequestLogConfig, config.ServiceName, config.UseDaily)
responseWriter := createFileWriter(logDir, "response", config.ResponseLogConfig, config.ServiceName, config.UseDaily)
// 修复:创建真正的级别分离核心
// 使用自定义的LevelEnabler来确保每个Core只处理特定级别的日志
@@ -118,8 +211,21 @@ func createSeparatedCore(logDir string, config ExternalServiceLoggingConfig) zap
&levelEnabler{minLevel: zapcore.WarnLevel, maxLevel: zapcore.WarnLevel}, // 只接受WARN级别
)
// 使用 zapcore.NewTee 合并核心,现在每个核心只会处理自己级别的日志
return zapcore.NewTee(infoCore, errorCore, warnCore)
// 新增:请求和响应日志核心
requestCore := zapcore.NewCore(
zapcore.NewJSONEncoder(encoderConfig),
zapcore.AddSync(requestWriter),
&requestResponseEnabler{logType: "request"}, // 只接受请求日志
)
responseCore := zapcore.NewCore(
zapcore.NewJSONEncoder(encoderConfig),
zapcore.AddSync(responseWriter),
&requestResponseEnabler{logType: "response"}, // 只接受响应日志
)
// 使用 zapcore.NewTee 合并核心,现在每个核心只会处理自己类型的日志
return zapcore.NewTee(infoCore, errorCore, warnCore, requestCore, responseCore)
}
// levelEnabler 自定义级别过滤器,确保只接受指定级别的日志
@@ -133,6 +239,17 @@ func (l *levelEnabler) Enabled(level zapcore.Level) bool {
return level >= l.minLevel && level <= l.maxLevel
}
// requestResponseEnabler 自定义日志类型过滤器,确保只接受特定类型的日志
type requestResponseEnabler struct {
logType string
}
// Enabled 实现 zapcore.LevelEnabler 接口
func (r *requestResponseEnabler) Enabled(level zapcore.Level) bool {
// 请求和响应日志通常是INFO级别
return level == zapcore.InfoLevel
}
// createFileWriter 创建文件写入器
func createFileWriter(logDir, level string, config ExternalServiceLevelFileConfig, serviceName string, useDaily bool) *lumberjack.Logger {
// 使用默认配置如果未指定
@@ -176,7 +293,7 @@ func createFileWriter(logDir, level string, config ExternalServiceLevelFileConfi
// LogRequest 记录请求日志
func (e *ExternalServiceLogger) LogRequest(requestID, transactionID, apiCode string, url interface{}, params interface{}) {
e.logger.Info(fmt.Sprintf("%s API请求", e.serviceName),
e.requestLogger.Info(fmt.Sprintf("%s API请求", e.serviceName),
zap.String("service", e.serviceName),
zap.String("request_id", requestID),
zap.String("transaction_id", transactionID),
@@ -189,7 +306,7 @@ func (e *ExternalServiceLogger) LogRequest(requestID, transactionID, apiCode str
// LogResponse 记录响应日志
func (e *ExternalServiceLogger) LogResponse(requestID, transactionID, apiCode string, statusCode int, response []byte, duration time.Duration) {
e.logger.Info(fmt.Sprintf("%s API响应", e.serviceName),
e.responseLogger.Info(fmt.Sprintf("%s API响应", e.serviceName),
zap.String("service", e.serviceName),
zap.String("request_id", requestID),
zap.String("transaction_id", transactionID),
@@ -203,7 +320,7 @@ func (e *ExternalServiceLogger) LogResponse(requestID, transactionID, apiCode st
// LogResponseWithID 记录包含响应ID的响应日志
func (e *ExternalServiceLogger) LogResponseWithID(requestID, transactionID, apiCode string, statusCode int, response []byte, duration time.Duration, responseID string) {
e.logger.Info(fmt.Sprintf("%s API响应", e.serviceName),
e.responseLogger.Info(fmt.Sprintf("%s API响应", e.serviceName),
zap.String("service", e.serviceName),
zap.String("request_id", requestID),
zap.String("transaction_id", transactionID),