Files
ant-black 70132417ad publish: 1.2.0 snapshot (f3d7ec5)
channel: master

version: 1.2.0

source-ref: D:\code\open_source\ant-chrome master

source-commit: f3d7ec5

merged-public-base: 3d264eb
2026-05-05 18:08:10 +08:00

204 lines
5.1 KiB
Go

package logger
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"time"
)
// Init 初始化全局日志(简单版本,仅控制台输出)
func Init(ctx context.Context, levelStr string) {
InitWithConfig(ctx, LoggerConfig{
Level: levelStr,
FileEnabled: false,
Format: "text",
})
}
// InitWithConfig 使用配置初始化全局日志
func InitWithConfig(ctx context.Context, config LoggerConfig) {
globalMu.Lock()
defer globalMu.Unlock()
// 解析日志级别,无效级别使用默认 INFO
level := ParseLevel(config.Level)
if config.Level != "" && level == INFO && strings.ToLower(config.Level) != "info" {
// 无效级别,记录警告(使用 fmt 因为 logger 还未初始化)
fmt.Printf("[WARN] Invalid log level '%s', using default 'INFO'\n", config.Level)
}
// 创建格式化器
var formatter Formatter
switch strings.ToLower(config.Format) {
case "json":
formatter = NewJSONFormatter()
default:
formatter = NewTextFormatter()
}
// 创建控制台写入器
consoleWriter := NewConsoleWriter(formatter)
logger := &Logger{
level: level,
ctx: ctx,
writers: []Writer{consoleWriter, globalMemoryWriter},
consoleWriter: consoleWriter,
}
// 如果启用文件日志,创建文件写入器
if config.FileEnabled && config.FilePath != "" {
fileWriter, rotationManager, err := createFileWriterWithRotation(config, formatter)
if err != nil {
// 文件写入器创建失败,回退到仅控制台输出
fmt.Printf("[WARN] Failed to create file writer: %v, falling back to console only\n", err)
logger.fileWriteFailed = true
} else {
logger.fileWriter = fileWriter
logger.rotationManager = rotationManager
logger.writers = append(logger.writers, fileWriter)
}
}
globalLogger = logger
}
// createFileWriterWithRotation 创建带分片功能的文件写入器
func createFileWriterWithRotation(config LoggerConfig, formatter Formatter) (*FileWriter, *RotationManager, error) {
// 确保目录存在
dir := filepath.Dir(config.FilePath)
if dir != "" && dir != "." {
if err := os.MkdirAll(dir, 0755); err != nil {
return nil, nil, fmt.Errorf("failed to create log directory: %w", err)
}
}
// 计算缓冲区大小(KB -> 字节)
bufferSize := config.BufferSize * 1024
if bufferSize <= 0 {
bufferSize = 4 * 1024 // 默认 4KB
}
// 计算刷新间隔
flushInterval := time.Duration(config.FlushIntervalMs) * time.Millisecond
if flushInterval <= 0 {
flushInterval = time.Second
}
// 异步队列大小
asyncQueueSize := config.AsyncQueueSize
if asyncQueueSize <= 0 {
asyncQueueSize = 1000
}
fileConfig := FileWriterConfig{
FilePath: config.FilePath,
BufferSize: bufferSize,
FlushInterval: flushInterval,
AsyncQueueSize: asyncQueueSize,
}
// 使用异步文件写入器
fileWriter, err := NewAsyncFileWriter(fileConfig, formatter)
if err != nil {
return nil, nil, err
}
// 创建分片管理器(如果启用)
var rotationManager *RotationManager
if config.Rotation.Enabled {
rotationPolicy := createRotationPolicy(config.Rotation)
rotationManager = NewRotationManager(RotationManagerConfig{
BasePath: config.FilePath,
MaxBackups: config.Rotation.MaxBackups,
MaxAge: config.Rotation.MaxAge,
Policy: rotationPolicy,
})
}
return fileWriter, rotationManager, nil
}
// createRotationPolicy 根据配置创建分片策略
func createRotationPolicy(config RotationConfig) RotationPolicy {
var policies []RotationPolicy
// 时间分片策略
if config.TimeInterval != "" {
var interval TimeInterval
switch strings.ToLower(config.TimeInterval) {
case "hourly":
interval = Hourly
default:
interval = Daily
}
policies = append(policies, NewTimeRotationPolicy(interval))
}
// 大小分片策略
if config.MaxSizeMB > 0 {
policies = append(policies, NewSizeRotationPolicyMB(config.MaxSizeMB))
}
// 如果有多个策略,使用组合策略
if len(policies) > 1 {
return NewCompositeRotationPolicy(policies...)
} else if len(policies) == 1 {
return policies[0]
}
// 默认按天分片
return NewTimeRotationPolicy(Daily)
}
// Close 关闭全局日志
func Close() error {
globalMu.Lock()
defer globalMu.Unlock()
if globalLogger == nil {
return nil
}
var lastErr error
for _, writer := range globalLogger.writers {
if err := writer.Close(); err != nil {
lastErr = err
}
}
globalLogger = nil
return lastErr
}
// New 创建新的日志记录器
func New(component string) *Logger {
globalMu.RLock()
defer globalMu.RUnlock()
if globalLogger == nil {
// 如果全局日志未初始化,创建一个默认的
consoleWriter := NewConsoleWriter(NewTextFormatter())
return &Logger{
level: INFO,
component: component,
writers: []Writer{consoleWriter},
consoleWriter: consoleWriter,
}
}
return &Logger{
level: globalLogger.level,
component: component,
ctx: globalLogger.ctx,
writers: globalLogger.writers,
consoleWriter: globalLogger.consoleWriter,
fileWriter: globalLogger.fileWriter,
rotationManager: globalLogger.rotationManager,
fileWriteFailed: globalLogger.fileWriteFailed,
}
}