184 lines
5.6 KiB
Go
184 lines
5.6 KiB
Go
|
|
package logger
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"context"
|
|||
|
|
"sync"
|
|||
|
|
|
|||
|
|
"github.com/go-logr/logr"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// Logger 定义项目的日志接口,基于logr但提供更清晰的抽象.
|
|||
|
|
// 支持结构化日志和上下文感知的日志记录.
|
|||
|
|
type Logger interface {
|
|||
|
|
// Context-aware structured logging methods (推荐使用)
|
|||
|
|
DebugContext(ctx context.Context, msg string, args ...any)
|
|||
|
|
InfoContext(ctx context.Context, msg string, args ...any)
|
|||
|
|
WarnContext(ctx context.Context, msg string, args ...any)
|
|||
|
|
ErrorContext(ctx context.Context, msg string, args ...any)
|
|||
|
|
|
|||
|
|
// Non-context structured logging methods (用于适配器和内部组件)
|
|||
|
|
Debug(msg string, args ...any)
|
|||
|
|
Info(msg string, args ...any)
|
|||
|
|
Warn(msg string, args ...any)
|
|||
|
|
Error(msg string, args ...any)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// NewLogger 创建一个基于logr的Logger实现.
|
|||
|
|
func NewLogger(logger logr.Logger) Logger {
|
|||
|
|
return &logrAdapter{
|
|||
|
|
logger: logger,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// NewDefaultLogger 创建一个默认的Logger实现.
|
|||
|
|
// 注意:logr需要显式提供一个LogSink实现,这里返回一个discard logger.
|
|||
|
|
func NewDefaultLogger() Logger {
|
|||
|
|
return &logrAdapter{
|
|||
|
|
logger: logr.Discard(),
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// NopLogger 空操作日志器实现,所有日志方法都不执行任何操作.
|
|||
|
|
// 适用于不需要日志输出的场景,如测试或性能敏感的场景.
|
|||
|
|
type NopLogger struct{}
|
|||
|
|
|
|||
|
|
// NewNopLogger 创建新的空操作日志器.
|
|||
|
|
func NewNopLogger() *NopLogger {
|
|||
|
|
return &NopLogger{}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (n *NopLogger) DebugContext(_ context.Context, _ string, _ ...any) {}
|
|||
|
|
func (n *NopLogger) InfoContext(_ context.Context, _ string, _ ...any) {}
|
|||
|
|
func (n *NopLogger) WarnContext(_ context.Context, _ string, _ ...any) {}
|
|||
|
|
func (n *NopLogger) ErrorContext(_ context.Context, _ string, _ ...any) {}
|
|||
|
|
func (n *NopLogger) Debug(_ string, _ ...any) {}
|
|||
|
|
func (n *NopLogger) Info(_ string, _ ...any) {}
|
|||
|
|
func (n *NopLogger) Warn(_ string, _ ...any) {}
|
|||
|
|
func (n *NopLogger) Error(_ string, _ ...any) {}
|
|||
|
|
|
|||
|
|
// 全局日志器相关变量.
|
|||
|
|
//
|
|||
|
|
//nolint:gochecknoglobals // 全局日志器是必要的,用于提供便捷的日志访问接口
|
|||
|
|
var (
|
|||
|
|
globalLogger Logger = NewNopLogger() // 默认使用 NopLogger
|
|||
|
|
globalLoggerLock sync.RWMutex
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// SetGlobalLogger 设置全局日志器.
|
|||
|
|
// 线程安全,可以在程序启动时调用以设置全局日志器.
|
|||
|
|
func SetGlobalLogger(logger Logger) {
|
|||
|
|
if logger == nil {
|
|||
|
|
logger = NewNopLogger()
|
|||
|
|
}
|
|||
|
|
globalLoggerLock.Lock()
|
|||
|
|
defer globalLoggerLock.Unlock()
|
|||
|
|
globalLogger = logger
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetGlobalLogger 获取全局日志器.
|
|||
|
|
// 线程安全,返回当前设置的全局日志器,如果未设置则返回 NopLogger.
|
|||
|
|
func GetGlobalLogger() Logger {
|
|||
|
|
globalLoggerLock.RLock()
|
|||
|
|
defer globalLoggerLock.RUnlock()
|
|||
|
|
return globalLogger
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// logrAdapter 是Logger接口的logr实现.
|
|||
|
|
type logrAdapter struct {
|
|||
|
|
logger logr.Logger
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// convertArgs 将args转换为logr的key-value对格式.
|
|||
|
|
// logr要求key-value成对出现,如果args是奇数个,最后一个会作为单独的value.
|
|||
|
|
func convertArgs(args ...any) []any {
|
|||
|
|
// 如果args已经是成对的key-value格式,直接返回
|
|||
|
|
if len(args)%2 == 0 {
|
|||
|
|
return args
|
|||
|
|
}
|
|||
|
|
// 如果不是成对的,可能需要特殊处理
|
|||
|
|
// 这里我们假设调用者传入的是key-value对
|
|||
|
|
return args
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (l *logrAdapter) DebugContext(ctx context.Context, msg string, args ...any) {
|
|||
|
|
_ = ctx // 保持接口兼容性,logr目前不支持context
|
|||
|
|
l.logger.V(1).Info(msg, convertArgs(args...)...)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (l *logrAdapter) InfoContext(ctx context.Context, msg string, args ...any) {
|
|||
|
|
_ = ctx // 保持接口兼容性,logr目前不支持context
|
|||
|
|
l.logger.Info(msg, convertArgs(args...)...)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (l *logrAdapter) WarnContext(ctx context.Context, msg string, args ...any) {
|
|||
|
|
_ = ctx // 保持接口兼容性,logr目前不支持context
|
|||
|
|
// logr没有Warn级别,使用Info但标记为warning
|
|||
|
|
kv := convertArgs(args...)
|
|||
|
|
kv = append(kv, "level", "warning")
|
|||
|
|
l.logger.Info(msg, kv...)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (l *logrAdapter) ErrorContext(ctx context.Context, msg string, args ...any) {
|
|||
|
|
_ = ctx // 保持接口兼容性,logr目前不支持context
|
|||
|
|
// 尝试从args中提取error
|
|||
|
|
var err error
|
|||
|
|
kvArgs := make([]any, 0, len(args))
|
|||
|
|
for i := 0; i < len(args); i++ {
|
|||
|
|
if i+1 < len(args) && args[i] == "error" {
|
|||
|
|
if e, ok := args[i+1].(error); ok {
|
|||
|
|
err = e
|
|||
|
|
i++ // 跳过error值
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
kvArgs = append(kvArgs, args[i])
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if err != nil {
|
|||
|
|
l.logger.Error(err, msg, convertArgs(kvArgs...)...)
|
|||
|
|
} else {
|
|||
|
|
// 如果没有error,使用Info但标记为error级别
|
|||
|
|
kvArgs = append(kvArgs, "level", "error")
|
|||
|
|
l.logger.Info(msg, convertArgs(kvArgs...)...)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (l *logrAdapter) Debug(msg string, args ...any) {
|
|||
|
|
l.logger.V(1).Info(msg, convertArgs(args...)...)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (l *logrAdapter) Info(msg string, args ...any) {
|
|||
|
|
l.logger.Info(msg, convertArgs(args...)...)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (l *logrAdapter) Warn(msg string, args ...any) {
|
|||
|
|
// logr没有Warn级别,使用Info但标记为warning
|
|||
|
|
kv := convertArgs(args...)
|
|||
|
|
kv = append(kv, "level", "warning")
|
|||
|
|
l.logger.Info(msg, kv...)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (l *logrAdapter) Error(msg string, args ...any) {
|
|||
|
|
// 尝试从args中提取error
|
|||
|
|
var err error
|
|||
|
|
kvArgs := make([]any, 0, len(args))
|
|||
|
|
for i := 0; i < len(args); i++ {
|
|||
|
|
if i+1 < len(args) && args[i] == "error" {
|
|||
|
|
if e, ok := args[i+1].(error); ok {
|
|||
|
|
err = e
|
|||
|
|
i++ // 跳过error值
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
kvArgs = append(kvArgs, args[i])
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if err != nil {
|
|||
|
|
l.logger.Error(err, msg, convertArgs(kvArgs...)...)
|
|||
|
|
} else {
|
|||
|
|
// 如果没有error,使用Info但标记为error级别
|
|||
|
|
kvArgs = append(kvArgs, "level", "error")
|
|||
|
|
l.logger.Info(msg, convertArgs(kvArgs...)...)
|
|||
|
|
}
|
|||
|
|
}
|