Files
go-common/docs/logger.md

342 lines
8.3 KiB
Markdown
Raw Permalink 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.

# 日志工具文档
## 概述
日志工具提供了统一的日志记录功能使用Go标准库实现无需第三方依赖。
## 功能特性
- 支持多种日志级别debug, info, warn, error
- 支持多种输出方式stdout, stderr, file, both
- 支持日志文件自动创建
- 支持日志前缀
- 支持禁用时间戳
- 支持带字段的日志记录
- **支持异步/同步日志模式(默认同步)**
- 使用配置工具统一管理配置
## 使用方法
### 1. 从配置创建日志记录器(推荐)
```go
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. 直接创建日志记录器
```go
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. 基本日志记录
```go
// 记录不同级别的日志
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. 带字段的日志记录
```go
// 记录带字段的日志
fields := map[string]interface{}{
"user_id": 123,
"action": "login",
}
logger.Infof(fields, "User logged in")
logger.Errorf(fields, "Failed to process request")
```
### 5. 异步/同步模式
#### 同步模式(默认)
```go
// 配置中不设置async或设置为false使用同步模式
// 同步模式:日志直接写入,会阻塞调用方直到写入完成
logger.Info("This is a synchronous log")
```
#### 异步模式
```go
// 配置中设置async为true使用异步模式
// 异步模式日志写入通过channel异步处理不阻塞调用方
// 配置文件示例:
// {
// "logger": {
// "async": true,
// "bufferSize": 1000
// }
// }
// 使用异步模式时程序退出前需要调用Close()确保所有日志写入完成
defer logger.Close()
logger.Info("This is an asynchronous log")
```
**注意:**
- `Fatal``Panic` 方法始终使用同步模式,确保日志写入后再退出/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 |
## 配置示例
### 输出到标准输出
```json
{
"logger": {
"level": "info",
"output": "stdout",
"prefix": "app"
}
}
```
### 输出到文件
```json
{
"logger": {
"level": "debug",
"output": "file",
"filePath": "./logs/app.log",
"prefix": "app"
}
}
```
### 同时输出到标准输出和文件
```json
{
"logger": {
"level": "info",
"output": "both",
"filePath": "./logs/app.log",
"prefix": "app",
"disableTimestamp": false
}
}
```
### 异步模式配置
```json
{
"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为`file``both`时,必须提供`filePath`
- 日志文件目录会自动创建(如果不存在)
2. **日志级别**
- 设置为`debug`时,会记录所有级别的日志
- 设置为`info`会记录info、warn、error级别的日志
- 设置为`warn`只记录warn和error级别的日志
- 设置为`error`只记录error级别的日志
3. **文件权限**
- 日志文件创建时使用0666权限
- 目录创建时使用0755权限
4. **性能考虑**
- 使用标准库log包性能较好
- 文件输出使用追加模式,不会覆盖已有日志
- 异步模式适合高并发场景,减少日志写入对业务代码的阻塞
- 同步模式适合需要确保日志立即写入的场景(如调试)
5. **异步模式注意事项**
- 异步模式下,程序退出前必须调用 `Close()` 方法,确保所有日志写入完成
- 如果channel缓冲区已满会自动降级为同步写入避免丢失日志
- `Fatal``Panic` 方法始终使用同步模式,确保日志写入后再退出/panic
## 完整示例
```go
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`