Skip to content

Go日志管理策略 - Golang企业级日志系统设计

日志管理是生产环境中不可或缺的重要组件,良好的日志系统能够帮助开发者快速定位问题、监控系统状态、进行性能分析和安全审计。

📋 重点面试题

面试题 1:Go应用的企业级日志管理系统设计

难度级别:⭐⭐⭐⭐⭐
考察范围:系统设计/日志架构
技术标签logging system design observability log aggregation

详细解答

1. 日志系统架构设计

点击查看完整代码实现
点击查看完整代码实现
go
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "io"
    "log"
    "os"
    "runtime"
    "strings"
    "sync"
    "time"
)

func demonstrateLoggingManagement() {
    fmt.Println("=== Go日志管理策略 ===")
    
    /*
    日志管理核心要素:
    
    1. 日志级别管理:
       - DEBUG: 详细的调试信息
       - INFO: 一般信息记录
       - WARN: 警告信息
       - ERROR: 错误信息
       - FATAL: 致命错误
    
    2. 结构化日志:
       - JSON格式输出
       - 字段标准化
       - 上下文信息
       - 链路追踪ID
    
    3. 日志输出管理:
       - 多目标输出
       - 异步写入
       - 缓冲机制
       - 轮转策略
    
    4. 性能优化:
       - 惰性求值
       - 批量写入
       - 压缩存储
       - 采样机制
    */
    
    demonstrateStructuredLogging()
    demonstrateLogLevels()
    demonstrateAsyncLogging()
    demonstrateLogAggregation()
}

func demonstrateStructuredLogging() {
    fmt.Println("\n--- 结构化日志设计 ---")
    
    /*
    结构化日志要点:
    
    1. 标准字段:时间戳、级别、消息、调用者信息
    2. 上下文字段:请求ID、用户ID、会话ID
    3. 业务字段:订单ID、产品ID等业务相关信息
    4. 元数据:服务名、版本号、环境信息
    */
    
    // 日志级别定义
    type LogLevel int
    
    const (
        DEBUG LogLevel = iota
        INFO
        WARN
        ERROR
        FATAL
    )
    
    func (l LogLevel) String() string {
        switch l {
        case DEBUG:
            return "DEBUG"
        case INFO:
            return "INFO"
        case WARN:
            return "WARN"
        case ERROR:
            return "ERROR"
        case FATAL:
            return "FATAL"
        default:
            return "UNKNOWN"
        }
    }
    
    // 日志条目结构
    type LogEntry struct {
        Timestamp   time.Time              `json:"timestamp"`
        Level       string                 `json:"level"`
        Message     string                 `json:"message"`
        Service     string                 `json:"service"`
        Version     string                 `json:"version"`
        Environment string                 `json:"environment"`
        RequestID   string                 `json:"request_id,omitempty"`
        UserID      string                 `json:"user_id,omitempty"`
        SessionID   string                 `json:"session_id,omitempty"`
        Caller      CallerInfo             `json:"caller"`
        Fields      map[string]interface{} `json:"fields,omitempty"`
        Error       *ErrorInfo             `json:"error,omitempty"`
    }
    
    type CallerInfo struct {
        File     string `json:"file"`
        Line     int    `json:"line"`
        Function string `json:"function"`
    }
    
    type ErrorInfo struct {
        Type       string `json:"type"`
        Message    string `json:"message"`
        StackTrace string `json:"stack_trace,omitempty"`
    }
    
    // 结构化日志器
    type StructuredLogger struct {
        service     string
        version     string
        environment string
        minLevel    LogLevel
        outputs     []io.Writer
        fields      map[string]interface{}
        mutex       sync.RWMutex
    }
    
    func NewStructuredLogger(service, version, environment string) *StructuredLogger {
        return &StructuredLogger{
            service:     service,
            version:     version,
            environment: environment,
            minLevel:    INFO,
            outputs:     []io.Writer{os.Stdout},
            fields:      make(map[string]interface{}),
        }
    }
    
    func (sl *StructuredLogger) SetLevel(level LogLevel) {
        sl.mutex.Lock()
        defer sl.mutex.Unlock()
        sl.minLevel = level
    }
    
    func (sl *StructuredLogger) AddOutput(output io.Writer) {
        sl.mutex.Lock()
        defer sl.mutex.Unlock()
        sl.outputs = append(sl.outputs, output)
    }
    
    func (sl *StructuredLogger) WithField(key string, value interface{}) *StructuredLogger {
        sl.mutex.RLock()
        fields := make(map[string]interface{})
        for k, v := range sl.fields {
            fields[k] = v
        }
        sl.mutex.RUnlock()
        
        fields[key] = value
        
        return &StructuredLogger{
            service:     sl.service,
            version:     sl.version,
            environment: sl.environment,
            minLevel:    sl.minLevel,
            outputs:     sl.outputs,
            fields:      fields,
        }
    }
    
    func (sl *StructuredLogger) WithFields(fields map[string]interface{}) *StructuredLogger {
        sl.mutex.RLock()
        newFields := make(map[string]interface{})
        for k, v := range sl.fields {
            newFields[k] = v
        }
        sl.mutex.RUnlock()
        
        for k, v := range fields {
            newFields[k] = v
        }
        
        return &StructuredLogger{
            service:     sl.service,
            version:     sl.version,
            environment: sl.environment,
            minLevel:    sl.minLevel,
            outputs:     sl.outputs,
            fields:      newFields,
        }
    }
    
    func (sl *StructuredLogger) log(level LogLevel, message string, err error) {
        sl.mutex.RLock()
        if level < sl.minLevel {
            sl.mutex.RUnlock()
            return
        }
        
        outputs := make([]io.Writer, len(sl.outputs))
        copy(outputs, sl.outputs)
        sl.mutex.RUnlock()
        
        // 获取调用者信息
        caller := sl.getCaller()
        
        // 构建日志条目
        entry := LogEntry{
            Timestamp:   time.Now(),
            Level:       level.String(),
            Message:     message,
            Service:     sl.service,
            Version:     sl.version,
            Environment: sl.environment,
            Caller:      caller,
        }
        
        // 添加上下文字段
        if len(sl.fields) > 0 {
            entry.Fields = make(map[string]interface{})
            for k, v := range sl.fields {
                entry.Fields[k] = v
            }
        }
        
        // 添加错误信息
        if err != nil {
            entry.Error = &ErrorInfo{
                Type:    fmt.Sprintf("%T", err),
                Message: err.Error(),
            }
        }
        
        // 序列化为JSON
        data, marshalErr := json.Marshal(entry)
        if marshalErr != nil {
            // 降级处理
            fallbackLog := fmt.Sprintf(`{"timestamp":"%s","level":"%s","message":"JSON marshal error: %v","service":"%s"}`,
                entry.Timestamp.Format(time.RFC3339),
                entry.Level,
                marshalErr,
                entry.Service)
            data = []byte(fallbackLog)
        }
        
        data = append(data, '\n')
        
        // 写入所有输出
        for _, output := range outputs {
            output.Write(data)
        }
    }
    
    func (sl *StructuredLogger) getCaller() CallerInfo {
        // 跳过当前函数和log函数
        pc, file, line, ok := runtime.Caller(3)
        if !ok {
            return CallerInfo{}
        }
        
        // 获取函数名
        fn := runtime.FuncForPC(pc)
        funcName := "unknown"
        if fn != nil {
            funcName = fn.Name()
            // 简化函数名
            if idx := strings.LastIndex(funcName, "/"); idx != -1 {
                funcName = funcName[idx+1:]
            }
        }
        
        // 简化文件路径
        if idx := strings.LastIndex(file, "/"); idx != -1 {
            file = file[idx+1:]
        }
        
        return CallerInfo{
            File:     file,
            Line:     line,
            Function: funcName,
        }
    }
    
    func (sl *StructuredLogger) Debug(message string) {
        sl.log(DEBUG, message, nil)
    }
    
    func (sl *StructuredLogger) Info(message string) {
        sl.log(INFO, message, nil)
    }
    
    func (sl *StructuredLogger) Warn(message string) {
        sl.log(WARN, message, nil)
    }
    
    func (sl *StructuredLogger) Error(message string, err error) {
        sl.log(ERROR, message, err)
    }
    
    func (sl *StructuredLogger) Fatal(message string, err error) {
        sl.log(FATAL, message, err)
        os.Exit(1)
    }
    
    // 演示结构化日志
    fmt.Printf("结构化日志演示:\n")
    
    logger := NewStructuredLogger("user-service", "v1.2.3", "production")
    logger.SetLevel(DEBUG)
    
    // 基础日志
    logger.Info("服务启动成功")
    logger.Debug("数据库连接池初始化")
    
    // 带字段的日志
    userLogger := logger.WithFields(map[string]interface{}{
        "request_id": "req-12345",
        "user_id":    "user-67890",
        "session_id": "sess-abcdef",
    })
    
    userLogger.Info("用户登录成功")
    
    // 带错误的日志
    err := fmt.Errorf("数据库连接超时")
    userLogger.Error("用户查询失败", err)
    
    // 业务操作日志
    orderLogger := userLogger.WithFields(map[string]interface{}{
        "order_id":    "order-123",
        "product_id":  "prod-456",
        "amount":      99.99,
        "currency":    "USD",
    })
    
    orderLogger.Info("订单创建成功")
    
    // 性能日志
    performanceLogger := logger.WithFields(map[string]interface{}{
        "operation":   "database_query",
        "duration_ms": 150,
        "rows":        42,
    })
    
    performanceLogger.Warn("数据库查询耗时较长")
}

func demonstrateLogLevels() {
    fmt.Println("\n--- 日志级别管理 ---")
    
    /*
    日志级别管理要点:
    
    1. 动态级别调整:运行时调整日志级别
    2. 模块级别控制:不同模块设置不同级别
    3. 环境相关配置:开发、测试、生产环境
    4. 采样和限流:高频日志的控制机制
    */
    
    // 日志级别管理器
    type LogLevelManager struct {
        globalLevel  LogLevel
        moduleLevel  map[string]LogLevel
        sampling     map[LogLevel]int // 采样率:1表示记录所有,10表示每10条记录1条
        counters     map[string]int64 // 计数器
        mutex        sync.RWMutex
    }
    
    func NewLogLevelManager() *LogLevelManager {
        return &LogLevelManager{
            globalLevel: INFO,
            moduleLevel: make(map[string]LogLevel),
            sampling: map[LogLevel]int{
                DEBUG: 1,
                INFO:  1,
                WARN:  1,
                ERROR: 1,
                FATAL: 1,
            },
            counters: make(map[string]int64),
        }
    }
    
    func (llm *LogLevelManager) SetGlobalLevel(level LogLevel) {
        llm.mutex.Lock()
        defer llm.mutex.Unlock()
        llm.globalLevel = level
    }
    
    func (llm *LogLevelManager) SetModuleLevel(module string, level LogLevel) {
        llm.mutex.Lock()
        defer llm.mutex.Unlock()
        llm.moduleLevel[module] = level
    }
    
    func (llm *LogLevelManager) SetSampling(level LogLevel, rate int) {
        llm.mutex.Lock()
        defer llm.mutex.Unlock()
        if rate > 0 {
            llm.sampling[level] = rate
        }
    }
    
    func (llm *LogLevelManager) ShouldLog(module string, level LogLevel) bool {
        llm.mutex.RLock()
        defer llm.mutex.RUnlock()
        
        // 检查模块级别
        if moduleLevel, exists := llm.moduleLevel[module]; exists {
            if level < moduleLevel {
                return false
            }
        } else if level < llm.globalLevel {
            return false
        }
        
        // 检查采样率
        if samplingRate, exists := llm.sampling[level]; exists && samplingRate > 1 {
            counterKey := fmt.Sprintf("%s_%s", module, level.String())
            llm.counters[counterKey]++
            return llm.counters[counterKey]%int64(samplingRate) == 0
        }
        
        return true
    }
    
    func (llm *LogLevelManager) GetStats() map[string]interface{} {
        llm.mutex.RLock()
        defer llm.mutex.RUnlock()
        
        stats := map[string]interface{}{
            "global_level": llm.globalLevel.String(),
            "module_levels": make(map[string]string),
            "sampling_rates": make(map[string]int),
            "counters": make(map[string]int64),
        }
        
        for module, level := range llm.moduleLevel {
            stats["module_levels"].(map[string]string)[module] = level.String()
        }
        
        for level, rate := range llm.sampling {
            stats["sampling_rates"].(map[string]int)[level.String()] = rate
        }
        
        for key, count := range llm.counters {
            stats["counters"].(map[string]int64)[key] = count
        }
        
        return stats
    }
    
    // 支持级别管理的日志器
    type LevelManagedLogger struct {
        module      string
        levelMgr    *LogLevelManager
        baseLogger  *StructuredLogger
    }
    
    func NewLevelManagedLogger(module string, levelMgr *LogLevelManager, baseLogger *StructuredLogger) *LevelManagedLogger {
        return &LevelManagedLogger{
            module:     module,
            levelMgr:   levelMgr,
            baseLogger: baseLogger,
        }
    }
    
    func (lml *LevelManagedLogger) log(level LogLevel, message string, err error) {
        if !lml.levelMgr.ShouldLog(lml.module, level) {
            return
        }
        
        // 添加模块信息
        logger := lml.baseLogger.WithField("module", lml.module)
        
        switch level {
        case DEBUG:
            logger.Debug(message)
        case INFO:
            logger.Info(message)
        case WARN:
            logger.Warn(message)
        case ERROR:
            logger.Error(message, err)
        case FATAL:
            logger.Fatal(message, err)
        }
    }
    
    func (lml *LevelManagedLogger) Debug(message string) {
        lml.log(DEBUG, message, nil)
    }
    
    func (lml *LevelManagedLogger) Info(message string) {
        lml.log(INFO, message, nil)
    }
    
    func (lml *LevelManagedLogger) Warn(message string) {
        lml.log(WARN, message, nil)
    }
    
    func (lml *LevelManagedLogger) Error(message string, err error) {
        lml.log(ERROR, message, err)
    }
    
    // 演示日志级别管理
    fmt.Printf("日志级别管理演示:\n")
    
    levelManager := NewLogLevelManager()
    baseLogger := NewStructuredLogger("demo-service", "v1.0.0", "development")
    
    // 创建不同模块的日志器
    authLogger := NewLevelManagedLogger("auth", levelManager, baseLogger)
    dbLogger := NewLevelManagedLogger("database", levelManager, baseLogger)
    apiLogger := NewLevelManagedLogger("api", levelManager, baseLogger)
    
    fmt.Printf("  📊 默认配置测试:\n")
    
    // 默认级别测试(INFO级别)
    authLogger.Debug("认证模块调试信息") // 不会输出
    authLogger.Info("用户认证成功")      // 会输出
    dbLogger.Info("数据库连接建立")      // 会输出
    
    fmt.Printf("\n  🔧 动态级别调整:\n")
    
    // 调整全局级别为DEBUG
    levelManager.SetGlobalLevel(DEBUG)
    authLogger.Debug("现在可以看到调试信息了")
    
    // 设置特定模块级别
    levelManager.SetModuleLevel("database", WARN)
    dbLogger.Info("数据库信息日志")   // 不会输出(级别不够)
    dbLogger.Warn("数据库连接缓慢") // 会输出
    
    fmt.Printf("\n  📉 日志采样测试:\n")
    
    // 设置DEBUG级别采样(每5条记录1条)
    levelManager.SetSampling(DEBUG, 5)
    
    fmt.Printf("    发送10条DEBUG日志(应该只记录2条):\n")
    for i := 1; i <= 10; i++ {
        authLogger.Debug(fmt.Sprintf("调试信息 #%d", i))
    }
    
    // 显示统计信息
    fmt.Printf("\n  📈 日志统计信息:\n")
    stats := levelManager.GetStats()
    for key, value := range stats {
        switch v := value.(type) {
        case map[string]string:
            fmt.Printf("    %s:\n", key)
            for k, val := range v {
                fmt.Printf("      %s: %s\n", k, val)
            }
        case map[string]int:
            fmt.Printf("    %s:\n", key)
            for k, val := range v {
                fmt.Printf("      %s: %d\n", k, val)
            }
        case map[string]int64:
            fmt.Printf("    %s:\n", key)
            for k, val := range v {
                fmt.Printf("      %s: %d\n", k, val)
            }
        default:
            fmt.Printf("    %s: %v\n", key, v)
        }
    }
}

func demonstrateAsyncLogging() {
    fmt.Println("\n--- 异步日志处理 ---")
    
    /*
    异步日志要点:
    
    1. 缓冲机制:批量写入提高性能
    2. 背压处理:缓冲区满时的策略
    3. 优雅关闭:确保所有日志都被写入
    4. 错误处理:异步写入失败的处理
    */
    
    // 异步日志条目
    type AsyncLogEntry struct {
        Data      []byte
        Timestamp time.Time
        Retry     int
    }
    
    // 异步日志器
    type AsyncLogger struct {
        buffer     chan AsyncLogEntry
        writers    []io.Writer
        batchSize  int
        flushInterval time.Duration
        maxRetries int
        stopCh     chan struct{}
        doneCh     chan struct{}
        errorCh    chan error
        stats      *AsyncLoggerStats
        mutex      sync.RWMutex
    }
    
    type AsyncLoggerStats struct {
        TotalLogs    int64
        DroppedLogs  int64
        FailedWrites int64
        BatchWrites  int64
    }
    
    func NewAsyncLogger(bufferSize, batchSize int, flushInterval time.Duration) *AsyncLogger {
        return &AsyncLogger{
            buffer:        make(chan AsyncLogEntry, bufferSize),
            batchSize:     batchSize,
            flushInterval: flushInterval,
            maxRetries:    3,
            stopCh:        make(chan struct{}),
            doneCh:        make(chan struct{}),
            errorCh:       make(chan error, 100),
            stats:         &AsyncLoggerStats{},
        }
    }
    
    func (al *AsyncLogger) AddWriter(writer io.Writer) {
        al.mutex.Lock()
        defer al.mutex.Unlock()
        al.writers = append(al.writers, writer)
    }
    
    func (al *AsyncLogger) Start() {
        go al.processLoop()
    }
    
    func (al *AsyncLogger) Stop() error {
        close(al.stopCh)
        
        // 等待处理完成
        select {
        case <-al.doneCh:
            return nil
        case <-time.After(5 * time.Second):
            return fmt.Errorf("异步日志器关闭超时")
        }
    }
    
    func (al *AsyncLogger) Log(data []byte) error {
        entry := AsyncLogEntry{
            Data:      data,
            Timestamp: time.Now(),
            Retry:     0,
        }
        
        select {
        case al.buffer <- entry:
            al.stats.TotalLogs++
            return nil
        default:
            // 缓冲区满,丢弃日志
            al.stats.DroppedLogs++
            return fmt.Errorf("日志缓冲区已满")
        }
    }
    
    func (al *AsyncLogger) processLoop() {
        defer close(al.doneCh)
        
        ticker := time.NewTicker(al.flushInterval)
        defer ticker.Stop()
        
        batch := make([]AsyncLogEntry, 0, al.batchSize)
        
        for {
            select {
            case <-al.stopCh:
                // 处理剩余的日志
                al.flushRemaining()
                return
                
            case entry := <-al.buffer:
                batch = append(batch, entry)
                if len(batch) >= al.batchSize {
                    al.writeBatch(batch)
                    batch = batch[:0] // 重置批次
                }
                
            case <-ticker.C:
                if len(batch) > 0 {
                    al.writeBatch(batch)
                    batch = batch[:0]
                }
            }
        }
    }
    
    func (al *AsyncLogger) writeBatch(batch []AsyncLogEntry) {
        if len(batch) == 0 {
            return
        }
        
        al.mutex.RLock()
        writers := make([]io.Writer, len(al.writers))
        copy(writers, al.writers)
        al.mutex.RUnlock()
        
        // 合并批次数据
        var combinedData []byte
        for _, entry := range batch {
            combinedData = append(combinedData, entry.Data...)
        }
        
        // 写入所有目标
        hasError := false
        for _, writer := range writers {
            if _, err := writer.Write(combinedData); err != nil {
                al.errorCh <- fmt.Errorf("写入失败: %v", err)
                al.stats.FailedWrites++
                hasError = true
            }
        }
        
        if !hasError {
            al.stats.BatchWrites++
        }
    }
    
    func (al *AsyncLogger) flushRemaining() {
        // 处理缓冲区中剩余的所有日志
        remaining := make([]AsyncLogEntry, 0)
        
        for {
            select {
            case entry := <-al.buffer:
                remaining = append(remaining, entry)
            default:
                if len(remaining) > 0 {
                    al.writeBatch(remaining)
                }
                return
            }
        }
    }
    
    func (al *AsyncLogger) GetStats() AsyncLoggerStats {
        return *al.stats
    }
    
    func (al *AsyncLogger) GetErrors() []error {
        var errors []error
        for {
            select {
            case err := <-al.errorCh:
                errors = append(errors, err)
            default:
                return errors
            }
        }
    }
    
    // 演示异步日志
    fmt.Printf("异步日志处理演示:\n")
    
    // 创建异步日志器
    asyncLogger := NewAsyncLogger(1000, 10, 100*time.Millisecond)
    
    // 添加输出目标
    asyncLogger.AddWriter(os.Stdout)
    
    // 启动异步处理
    asyncLogger.Start()
    
    fmt.Printf("  📝 发送异步日志:\n")
    
    // 发送大量日志测试性能
    start := time.Now()
    for i := 1; i <= 50; i++ {
        logData := fmt.Sprintf(`{"timestamp":"%s","level":"INFO","message":"异步日志消息 #%d","service":"test"}%s`,
            time.Now().Format(time.RFC3339), i, "\n")
        
        if err := asyncLogger.Log([]byte(logData)); err != nil {
            fmt.Printf("    ❌ 日志发送失败: %v\n", err)
        }
        
        // 模拟一些处理时间
        if i%10 == 0 {
            time.Sleep(10 * time.Millisecond)
        }
    }
    
    duration := time.Since(start)
    
    // 等待一段时间让异步处理完成
    time.Sleep(500 * time.Millisecond)
    
    // 停止异步日志器
    if err := asyncLogger.Stop(); err != nil {
        fmt.Printf("  ❌ 异步日志器停止失败: %v\n", err)
    }
    
    // 显示统计信息
    stats := asyncLogger.GetStats()
    fmt.Printf("\n  📊 异步日志统计:\n")
    fmt.Printf("    发送耗时: %v\n", duration)
    fmt.Printf("    总日志数: %d\n", stats.TotalLogs)
    fmt.Printf("    丢弃日志数: %d\n", stats.DroppedLogs)
    fmt.Printf("    批次写入数: %d\n", stats.BatchWrites)
    fmt.Printf("    写入失败数: %d\n", stats.FailedWrites)
    
    // 检查错误
    errors := asyncLogger.GetErrors()
    if len(errors) > 0 {
        fmt.Printf("    错误数: %d\n", len(errors))
        for i, err := range errors {
            if i < 3 { // 只显示前3个错误
                fmt.Printf("      %d: %v\n", i+1, err)
            }
        }
    }
    
    fmt.Printf("  ✅ 异步日志处理完成\n")
}

func demonstrateLogAggregation() {
    fmt.Println("\n--- 日志聚合和分析 ---")
    
    /*
    日志聚合要点:
    
    1. 日志收集:从多个源收集日志
    2. 格式标准化:统一日志格式
    3. 索引和搜索:支持快速查询
    4. 监控和告警:基于日志的监控
    */
    
    // 日志聚合器
    type LogAggregator struct {
        entries    []LogEntry
        indices    map[string][]int // 字段索引
        stats      map[string]int64 // 统计信息
        mutex      sync.RWMutex
    }
    
    func NewLogAggregator() *LogAggregator {
        return &LogAggregator{
            entries: make([]LogEntry, 0),
            indices: make(map[string][]int),
            stats:   make(map[string]int64),
        }
    }
    
    func (la *LogAggregator) AddEntry(entry LogEntry) {
        la.mutex.Lock()
        defer la.mutex.Unlock()
        
        index := len(la.entries)
        la.entries = append(la.entries, entry)
        
        // 更新索引
        la.updateIndex("level", entry.Level, index)
        la.updateIndex("service", entry.Service, index)
        la.updateIndex("environment", entry.Environment, index)
        
        if entry.RequestID != "" {
            la.updateIndex("request_id", entry.RequestID, index)
        }
        
        if entry.UserID != "" {
            la.updateIndex("user_id", entry.UserID, index)
        }
        
        // 更新统计信息
        la.stats["total"]++
        la.stats["level_"+entry.Level]++
        la.stats["service_"+entry.Service]++
    }
    
    func (la *LogAggregator) updateIndex(field, value string, index int) {
        key := field + ":" + value
        if _, exists := la.indices[key]; !exists {
            la.indices[key] = make([]int, 0)
        }
        la.indices[key] = append(la.indices[key], index)
    }
    
    func (la *LogAggregator) Search(field, value string) []LogEntry {
        la.mutex.RLock()
        defer la.mutex.RUnlock()
        
        key := field + ":" + value
        indices, exists := la.indices[key]
        if !exists {
            return nil
        }
        
        results := make([]LogEntry, 0, len(indices))
        for _, index := range indices {
            if index < len(la.entries) {
                results = append(results, la.entries[index])
            }
        }
        
        return results
    }
    
    func (la *LogAggregator) GetTimeRange(start, end time.Time) []LogEntry {
        la.mutex.RLock()
        defer la.mutex.RUnlock()
        
        var results []LogEntry
        for _, entry := range la.entries {
            if (entry.Timestamp.Equal(start) || entry.Timestamp.After(start)) &&
               (entry.Timestamp.Equal(end) || entry.Timestamp.Before(end)) {
                results = append(results, entry)
            }
        }
        
        return results
    }
    
    func (la *LogAggregator) GetStats() map[string]int64 {
        la.mutex.RLock()
        defer la.mutex.RUnlock()
        
        stats := make(map[string]int64)
        for k, v := range la.stats {
            stats[k] = v
        }
        
        return stats
    }
    
    func (la *LogAggregator) AnalyzeErrorPatterns() map[string]int {
        la.mutex.RLock()
        defer la.mutex.RUnlock()
        
        patterns := make(map[string]int)
        
        for _, entry := range la.entries {
            if entry.Level == "ERROR" && entry.Error != nil {
                patterns[entry.Error.Type]++
            }
        }
        
        return patterns
    }
    
    func (la *LogAggregator) GetTopUsers(limit int) []struct {
        UserID string
        Count  int
    } {
        la.mutex.RLock()
        defer la.mutex.RUnlock()
        
        userCounts := make(map[string]int)
        
        for _, entry := range la.entries {
            if entry.UserID != "" {
                userCounts[entry.UserID]++
            }
        }
        
        // 简单排序(实际应用中应使用更高效的排序)
        type userCount struct {
            UserID string
            Count  int
        }
        
        var users []userCount
        for userID, count := range userCounts {
            users = append(users, userCount{UserID: userID, Count: count})
        }
        
        // 简单冒泡排序(仅用于演示)
        for i := 0; i < len(users)-1; i++ {
            for j := 0; j < len(users)-i-1; j++ {
                if users[j].Count < users[j+1].Count {
                    users[j], users[j+1] = users[j+1], users[j]
                }
            }
        }
        
        result := make([]struct {
            UserID string
            Count  int
        }, 0, limit)
        
        for i := 0; i < len(users) && i < limit; i++ {
            result = append(result, struct {
                UserID string
                Count  int
            }{UserID: users[i].UserID, Count: users[i].Count})
        }
        
        return result
    }
    
    // 演示日志聚合
    fmt.Printf("日志聚合和分析演示:\n")
    
    aggregator := NewLogAggregator()
    
    // 模拟添加各种日志
    baseTime := time.Now().Add(-time.Hour)
    
    logEntries := []LogEntry{
        {
            Timestamp: baseTime,
            Level:     "INFO",
            Message:   "用户登录成功",
            Service:   "auth-service",
            Environment: "production",
            RequestID: "req-001",
            UserID:    "user-123",
        },
        {
            Timestamp: baseTime.Add(5 * time.Minute),
            Level:     "ERROR",
            Message:   "数据库连接失败",
            Service:   "user-service",
            Environment: "production",
            RequestID: "req-002",
            Error: &ErrorInfo{
                Type:    "DatabaseError",
                Message: "connection timeout",
            },
        },
        {
            Timestamp: baseTime.Add(10 * time.Minute),
            Level:     "WARN",
            Message:   "API请求频率过高",
            Service:   "api-gateway",
            Environment: "production",
            RequestID: "req-003",
            UserID:    "user-123",
        },
        {
            Timestamp: baseTime.Add(15 * time.Minute),
            Level:     "INFO",
            Message:   "订单创建成功",
            Service:   "order-service",
            Environment: "production",
            RequestID: "req-004",
            UserID:    "user-456",
        },
        {
            Timestamp: baseTime.Add(20 * time.Minute),
            Level:     "ERROR",
            Message:   "支付处理失败",
            Service:   "payment-service",
            Environment: "production",
            RequestID: "req-005",
            UserID:    "user-789",
            Error: &ErrorInfo{
                Type:    "PaymentError",
                Message: "insufficient funds",
            },
        },
    }
    
    // 添加日志条目
    fmt.Printf("  📥 添加日志条目:\n")
    for _, entry := range logEntries {
        aggregator.AddEntry(entry)
        fmt.Printf("    添加: %s [%s] %s\n", entry.Timestamp.Format("15:04:05"), entry.Level, entry.Message)
    }
    
    // 搜索测试
    fmt.Printf("\n  🔍 搜索测试:\n")
    
    // 按级别搜索
    errorLogs := aggregator.Search("level", "ERROR")
    fmt.Printf("    ERROR级别日志: %d\n", len(errorLogs))
    for _, log := range errorLogs {
        fmt.Printf("      - %s: %s\n", log.Service, log.Message)
    }
    
    // 按用户搜索
    userLogs := aggregator.Search("user_id", "user-123")
    fmt.Printf("    用户user-123的日志: %d\n", len(userLogs))
    
    // 按服务搜索
    serviceLogs := aggregator.Search("service", "user-service")
    fmt.Printf("    user-service的日志: %d\n", len(serviceLogs))
    
    // 时间范围搜索
    fmt.Printf("\n  ⏰ 时间范围搜索:\n")
    recentLogs := aggregator.GetTimeRange(baseTime.Add(10*time.Minute), baseTime.Add(25*time.Minute))
    fmt.Printf("    最近15分钟的日志: %d\n", len(recentLogs))
    
    // 统计分析
    fmt.Printf("\n  📊 统计分析:\n")
    stats := aggregator.GetStats()
    for key, value := range stats {
        fmt.Printf("    %s: %d\n", key, value)
    }
    
    // 错误模式分析
    fmt.Printf("\n  🚨 错误模式分析:\n")
    errorPatterns := aggregator.AnalyzeErrorPatterns()
    for errorType, count := range errorPatterns {
        fmt.Printf("    %s: %d\n", errorType, count)
    }
    
    // 活跃用户分析
    fmt.Printf("\n  👥 活跃用户分析:\n")
    topUsers := aggregator.GetTopUsers(3)
    for i, user := range topUsers {
        fmt.Printf("    %d. %s: %d次活动\n", i+1, user.UserID, user.Count)
    }
    
    fmt.Printf("\n  📋 日志聚合最佳实践:\n")
    fmt.Printf("    1. 建立统一的日志格式和字段标准\n")
    fmt.Printf("    2. 实现高效的索引和搜索机制\n")
    fmt.Printf("    3. 提供丰富的查询和分析功能\n")
    fmt.Printf("    4. 建立基于日志的监控和告警\n")
    fmt.Printf("    5. 考虑日志的存储和归档策略\n")
}

func main() {
    demonstrateLoggingManagement()
}

:::

🎯 核心知识点总结

结构化日志要点

  1. 标准格式: 使用JSON等结构化格式便于解析和搜索
  2. 上下文信息: 包含请求ID、用户ID等追踪信息
  3. 调用者信息: 记录文件名、行号、函数名等定位信息
  4. 错误处理: 统一的错误信息格式和堆栈追踪

日志级别管理要点

  1. 动态调整: 支持运行时调整日志级别
  2. 模块控制: 不同模块可设置不同的日志级别
  3. 采样机制: 高频日志的采样和限流控制
  4. 环境配置: 根据环境(开发/测试/生产)设置合适级别

异步日志要点

  1. 缓冲机制: 使用缓冲区提高写入性能
  2. 批量处理: 批量写入减少I/O开销
  3. 背压处理: 缓冲区满时的丢弃或阻塞策略
  4. 优雅关闭: 确保关闭时所有日志都被写入

日志聚合要点

  1. 索引建立: 为关键字段建立索引提高查询效率
  2. 统计分析: 提供各种维度的统计和分析功能
  3. 模式识别: 自动识别错误模式和异常行为
  4. 实时监控: 基于日志实现实时监控和告警

🔍 面试准备建议

  1. 系统设计: 理解企业级日志系统的架构设计
  2. 性能优化: 掌握日志系统的性能优化技巧
  3. 运维经验: 了解生产环境日志管理的实际挑战
  4. 工具生态: 熟悉ELK、Fluentd等日志处理工具
  5. 监控集成: 理解日志与监控、告警系统的集成

正在精进