Files
go-common/docs/logger.md

8.3 KiB
Raw Blame History

日志工具文档

概述

日志工具提供了统一的日志记录功能使用Go标准库实现无需第三方依赖。

功能特性

  • 支持多种日志级别debug, info, warn, error
  • 支持多种输出方式stdout, stderr, file, both
  • 支持日志文件自动创建
  • 支持日志前缀
  • 支持禁用时间戳
  • 支持带字段的日志记录
  • 支持异步/同步日志模式(默认同步)
  • 使用配置工具统一管理配置

使用方法

1. 从配置创建日志记录器(推荐)

import (
    "git.toowon.com/jimmy/go-common/config"
    "git.toowon.com/jimmy/go-common/factory"
)

// 加载配置
cfg, err := config.LoadFromFile("./config.json")
if err != nil {
    log.Fatal(err)
}

// 使用工厂创建日志记录器(已初始化,可直接使用)
fac := factory.NewFactory(cfg)
logger, err := fac.GetLogger()
if err != nil {
    log.Fatal(err)
}

// 直接使用
logger.Info("Application started")
logger.Error("Failed to connect: %v", err)

2. 直接创建日志记录器

import (
    "git.toowon.com/jimmy/go-common/config"
    "git.toowon.com/jimmy/go-common/logger"
)

// 从配置获取日志配置
cfg, _ := config.LoadFromFile("./config.json")
loggerConfig := cfg.GetLogger()

// 创建日志记录器
logger, err := logger.NewLogger(loggerConfig)
if err != nil {
    log.Fatal(err)
}

// 使用默认配置如果loggerConfig为nil
logger, err := logger.NewLogger(nil)

3. 基本日志记录

// 记录不同级别的日志
logger.Debug("Debug message: %s", "debug info")
logger.Info("Info message: %s", "info")
logger.Warn("Warning message: %s", "warning")
logger.Error("Error message: %s", "error")

// 致命错误(会退出程序)
logger.Fatal("Fatal error: %s", "fatal")

// 恐慌错误会触发panic
logger.Panic("Panic error: %s", "panic")

4. 带字段的日志记录

// 记录带字段的日志
fields := map[string]interface{}{
    "user_id": 123,
    "action": "login",
}
logger.Infof(fields, "User logged in")
logger.Errorf(fields, "Failed to process request")

5. 异步/同步模式

同步模式(默认)

// 配置中不设置async或设置为false使用同步模式
// 同步模式:日志直接写入,会阻塞调用方直到写入完成
logger.Info("This is a synchronous log")

异步模式

// 配置中设置async为true使用异步模式
// 异步模式日志写入通过channel异步处理不阻塞调用方
// 配置文件示例:
// {
//   "logger": {
//     "async": true,
//     "bufferSize": 1000
//   }
// }

// 使用异步模式时程序退出前需要调用Close()确保所有日志写入完成
defer logger.Close()

logger.Info("This is an asynchronous log")

注意:

  • FatalPanic 方法始终使用同步模式,确保日志写入后再退出/panic
  • 异步模式下,程序退出前应调用 Close() 方法,确保所有日志写入完成
  • 如果channel已满会自动降级为同步写入避免丢失日志

API 参考

NewLogger(cfg *config.LoggerConfig) (*Logger, error)

创建日志记录器。

参数:

  • cfg: 日志配置对象如果为nil使用默认配置

返回: 日志记录器实例和错误信息

(l *Logger) Debug(format string, v ...interface{})

记录调试日志。

(l *Logger) Info(format string, v ...interface{})

记录信息日志。

(l *Logger) Warn(format string, v ...interface{})

记录警告日志。

(l *Logger) Error(format string, v ...interface{})

记录错误日志。

(l *Logger) Fatal(format string, v ...interface{})

记录致命错误日志并退出程序。

(l *Logger) Panic(format string, v ...interface{})

记录恐慌日志并触发panic。

(l *Logger) Debugf(fields map[string]interface{}, format string, v ...interface{})

记录调试日志(带字段)。

(l *Logger) Infof(fields map[string]interface{}, format string, v ...interface{})

记录信息日志(带字段)。

(l *Logger) Warnf(fields map[string]interface{}, format string, v ...interface{})

记录警告日志(带字段)。

(l *Logger) Errorf(fields map[string]interface{}, format string, v ...interface{})

记录错误日志(带字段)。

(l *Logger) Close() error

优雅关闭logger仅异步模式需要

说明:

  • 等待所有日志写入完成后再返回
  • 同步模式下调用此方法会立即返回,无需等待
  • 程序退出前应调用此方法,确保所有日志写入完成

配置说明

日志配置通过 config.LoggerConfig 提供:

字段 类型 说明 默认值
Level string 日志级别: debug, info, warn, error info
Output string 输出方式: stdout, stderr, file, both stdout
FilePath string 日志文件路径当output为file或both时必需 -
Prefix string 日志前缀 -
DisableTimestamp bool 禁用时间戳 false
Async bool 是否使用异步模式 false同步
BufferSize int 异步模式下的缓冲区大小 1000

配置示例

输出到标准输出

{
  "logger": {
    "level": "info",
    "output": "stdout",
    "prefix": "app"
  }
}

输出到文件

{
  "logger": {
    "level": "debug",
    "output": "file",
    "filePath": "./logs/app.log",
    "prefix": "app"
  }
}

同时输出到标准输出和文件

{
  "logger": {
    "level": "info",
    "output": "both",
    "filePath": "./logs/app.log",
    "prefix": "app",
    "disableTimestamp": false
  }
}

异步模式配置

{
  "logger": {
    "level": "info",
    "output": "file",
    "filePath": "./logs/app.log",
    "prefix": "app",
    "async": true,
    "bufferSize": 1000
  }
}

说明:

  • async: 设置为 true 启用异步模式,false 或不设置则使用同步模式(默认)
  • bufferSize: 异步模式下的channel缓冲区大小默认1000。当缓冲区满时新的日志会阻塞直到有空间或降级为同步写入

日志级别说明

  • debug: 调试信息,最详细的日志级别
  • info: 一般信息,正常的程序运行信息
  • warn: 警告信息,可能的问题但不影响程序运行
  • error: 错误信息,程序运行中的错误

注意事项

  1. 文件路径

    • 当output为fileboth时,必须提供filePath
    • 日志文件目录会自动创建(如果不存在)
  2. 日志级别

    • 设置为debug时,会记录所有级别的日志
    • 设置为info会记录info、warn、error级别的日志
    • 设置为warn只记录warn和error级别的日志
    • 设置为error只记录error级别的日志
  3. 文件权限

    • 日志文件创建时使用0666权限
    • 目录创建时使用0755权限
  4. 性能考虑

    • 使用标准库log包性能较好
    • 文件输出使用追加模式,不会覆盖已有日志
    • 异步模式适合高并发场景,减少日志写入对业务代码的阻塞
    • 同步模式适合需要确保日志立即写入的场景(如调试)
  5. 异步模式注意事项

    • 异步模式下,程序退出前必须调用 Close() 方法,确保所有日志写入完成
    • 如果channel缓冲区已满会自动降级为同步写入避免丢失日志
    • FatalPanic 方法始终使用同步模式,确保日志写入后再退出/panic

完整示例

package main

import (
    "git.toowon.com/jimmy/go-common/config"
    "git.toowon.com/jimmy/go-common/factory"
)

func main() {
    // 加载配置
    cfg, err := config.LoadFromFile("./config.json")
    if err != nil {
        log.Fatal(err)
    }

    // 使用工厂创建日志记录器
    fac := factory.NewFactory(cfg)
    logger, err := fac.GetLogger()
    if err != nil {
        log.Fatal(err)
    }

    // 使用日志记录器
    logger.Info("Application started")
    
    // 记录带字段的日志
    logger.Infof(map[string]interface{}{
        "user_id": 123,
        "action": "login",
    }, "User logged in successfully")
    
    logger.Error("An error occurred: %v", err)
    
    // 如果使用异步模式程序退出前需要关闭logger
    // defer logger.Close()
}

示例

完整示例请参考 examples/logger_example.go