log/新增Logger.*ReportStackLevel;

develop
Ge Song 2 years ago
parent f58f914826
commit 216f3a1012

@ -0,0 +1,98 @@
# log 日志
安装: `go get git.blauwelle.com/go/crate/log`
简单使用方式
```go
package main
import (
"context"
"git.blauwelle.com/go/crate/log"
"git.blauwelle.com/go/crate/log/logsdk"
"git.blauwelle.com/go/crate/log/logsdk/logjson"
)
func main() {
log.Logger().AddProcessor(logsdk.AllLevels, logjson.New()) // 添加日志处理器, 默认没有处理器(日志生成后会被忽略)
log.Info(context.Background(), "hello world") // 打印日志, Context 会被传递给日志处理器
}
```
`log` 模块包含日志处理的代码, 由 3 个包组成:
1. [logsdk](./logsdk): 日志实现;
2. [logjson](./logsdk/logjson): 控制台 JSON 日志处理器(`Processor`);
3. [log](.): 根目录, 提供全局 `Logger`, 把 `Logger` / `Entry` 相关的方法封装成函数.
## 基本概念
`logsdk``Logger`, `Entry`, `Processor` 3 部分组成, 其中只有 `Processor` 是接口类型.
`Logger` 主要负责全局的日志配置, `Logger` 可以通过内嵌的 `Entry` 值对象实现日志处理.
`Entry` 负责保存局部的的日志配置, 比如覆盖 `Logger``Caller` 开关或设置日志的时间属性; `Entry` 生成单条日志(`ReadonlyEntry`), 并调用 `Processor` 输出日志.
## 使用方式
### 获取全局 `Logger` 对象
一般只用来配置全局 `Logger` 对象(通过 `Set*``AddProcessor` 方法)
```go
log.Logger()
```
### 修改 `Logger` 配置
`Logger` 提供以下方法用来修改全局配置
- `AddProcessor` 新增处理器;
- `SetLevel` 设置全局日志等级, 只有小于 `Logger` 上设置的日志等级的日志才会被生成;
- `SetCallerSkip` 设置从 `runtime` 包获取调用信息时的 `skip` 参数, 为了方便使用, 0 表示调用 `Logger` / `Entry` 的日志方法处;
- `SetReportCaller` 设置生成调用信息;
- `SetReportStack` 设置生成调用栈;
- `SetReportStackLevel` 当日志等级小于设定值时强制生成调用栈;
- `Reset` 把 Logger 恢复到初始状态;
- `SetExit` 设置 `Logger` 的退出函数(`Logger.Exit`), 当日志等级为 `LevelFatal` 时调用这个函数;
### 日志生成
`Entry` 负责生成日志, `Logger` 通过内嵌 `Entry` 值对象的方式获得 `Entry` 的方法.
`Entry` 提供以下方法来修改局部配置, `log` 包提供了对应的函数调用
- `AddCallerSkip` 增加通过 `runtime` 获取调用信息时的 `skip` 值, `skip` 可以是负值;
- `WithField` 添加1组键值对;
- `WithFields` 添加键值对;
- `WithTime` 设置生成的日志的时间;
- `WithReportCaller` 覆盖 `Logger` 上的生成调用信息的设置;
- `WithReportStack` 覆盖 `Logger` 上的生成调用栈的设置;
`Entry` 提供以下方法来生成日志, 所有方法的第 1 个参数都是 `context.Context`, `Log` 方法的参数包含日志等级和日志消息,
其他方法的参数是日志消息.
所有方法除了 `Log` 外日志等级从高到底(严重程度从低到高), 这些方法有对应的格式化方法(如 `Info``Infof`).
`log` 包提供了对应的函数调用
- `Log`
- `Trace`
- `Debug`
- `Info`
- `Warn`
- `Error`
- `Fatal`
- `Panic`
### 其他用法
关闭日志生成 `log.Logger().SetLevel(logsdk.LevelDisabled)`
关闭强制生成调用栈 `log.Logger().SetReportStackLevel(logsdk.LevelDisabled)`
mock 实现 mock 日志处理器对生成的日志进行处理
---
## 日志处理器
- [logsdk/logjson](logsdk/logjson) 控制台 JSON 日志
- [go get git.blauwelle.com/go/crate/logotel](../logotel) OpenTelemetry 日志

@ -198,7 +198,7 @@ func (entry Entry) log(ctx context.Context, level Level, message string) {
if newEntry.GetReportCaller() {
readonlyEntry.Caller = getCaller(newEntry.callerSkip)
}
if newEntry.GetReportStack() {
if newEntry.GetReportStack() || level <= newEntry.logger.GetReportStackLevel() {
readonlyEntry.Stack = getStack(newEntry.callerSkip, 32)
}
for _, processor := range newEntry.logger.getLevelProcessors(level) {

@ -10,6 +10,7 @@ import (
func New() *Logger {
logger := &Logger{}
logger.entry.logger = logger
logger.Reset()
return logger
}
@ -22,11 +23,12 @@ type Logger struct {
exit func(code int) // protected by lock
levelProcessors levelProcessors // protected by lock
entry
lock sync.RWMutex
level atomic.Int32
callerSkip atomic.Int32
reportCaller atomic.Bool
reportStack atomic.Bool
lock sync.RWMutex
level atomic.Int32
reportStackLevel atomic.Int32
callerSkip atomic.Int32
reportCaller atomic.Bool
reportStack atomic.Bool
}
// AddProcessor 把日志处理器增加到 Logger
@ -82,6 +84,16 @@ func (logger *Logger) SetReportStack(reportStack bool) {
logger.reportStack.Store(reportStack)
}
// GetReportStackLevel 获取自动添加调用栈对应的日志等级
func (logger *Logger) GetReportStackLevel() Level {
return Level(logger.reportStackLevel.Load())
}
// SetReportStackLevel 设置日志等级小于等于 level 时自动添加调用栈
func (logger *Logger) SetReportStackLevel(level Level) {
logger.reportStackLevel.Store(int32(level))
}
// Reset 把 Logger 重置到初始状态
func (logger *Logger) Reset() {
logger.lock.Lock()
@ -90,6 +102,7 @@ func (logger *Logger) Reset() {
logger.lock.Unlock()
logger.SetLevel(LevelInfo)
logger.SetReportStackLevel(LevelWarn)
logger.SetCallerSkip(0)
logger.SetReportCaller(false)
logger.SetReportStack(false)

Loading…
Cancel
Save