Files
go-trustlog/api/logger/adapter.go
ryan d313449c5c refactor: 重构trustlog-sdk目录结构到trustlog/go-trustlog
- 将所有trustlog-sdk文件移动到trustlog/go-trustlog/目录
- 更新README中所有import路径从trustlog-sdk改为go-trustlog
- 更新cookiecutter配置文件中的项目名称
- 更新根目录.lefthook.yml以引用新位置的配置
- 添加go.sum文件到版本控制
- 删除过时的示例文件

这次重构与trustlog-server保持一致的目录结构,
为未来支持多语言SDK(Python、Java等)预留空间。
2025-12-22 13:37:57 +08:00

184 lines
5.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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...)...)
}
}