允许不同级别的写入info
This commit is contained in:
+40
-3
@@ -15,12 +15,39 @@ const closeDrainTimeout = 5 * time.Second
|
||||
|
||||
// 写入,需要判断同步还是异步
|
||||
func (l *Logger) write(event string, b []byte) (n int, err error) {
|
||||
if l.toAsync(event, b) {
|
||||
if l.toAsync(event, b, false) {
|
||||
return len(b), nil
|
||||
}
|
||||
return l.store(event, b)
|
||||
}
|
||||
|
||||
// writeFileOnly 只写文件,不写额外驱动
|
||||
//
|
||||
// 用于 allLevelToInfo 的镜像写入:这条日志的内容已经在原级别文件里走过一次驱动了,
|
||||
// 再走一遍会让控制台/自定义 writer 出现完全重复的两行
|
||||
func (l *Logger) writeFileOnly(event string, b []byte) (n int, err error) {
|
||||
if !l.option.isPrintFile {
|
||||
// 不落文件时镜像没有去处:直接返回,连队列和内存拷贝都省掉
|
||||
return len(b), nil
|
||||
}
|
||||
if l.toAsync(event, b, true) {
|
||||
return len(b), nil
|
||||
}
|
||||
return l.storeFileOnlyTo(l.channel, event, b)
|
||||
}
|
||||
|
||||
// storeFileOnlyTo 把日志只写进指定 channel 的文件,跳过全部驱动
|
||||
// 句柄缓冲不是并发安全的,因此和 storeFileTo 一样必须在 writeMu 内写
|
||||
func (l *Logger) storeFileOnlyTo(channel, event string, b []byte) (n int, err error) {
|
||||
if !l.option.isPrintFile {
|
||||
// 不落文件时该选项没有意义:镜像的唯一去处就是文件,直接当成功
|
||||
return len(b), nil
|
||||
}
|
||||
l.writeMu.Lock()
|
||||
defer l.writeMu.Unlock()
|
||||
return l.storeFileTo(channel, event, b)
|
||||
}
|
||||
|
||||
// 实际的存储
|
||||
// 必须满足 io.Writer 契约:成功时 n == len(b),否则调用方(log / io.MultiWriter)
|
||||
// 会认为发生了短写并把日志吞掉
|
||||
@@ -219,11 +246,14 @@ type cacheData struct {
|
||||
Channel string
|
||||
Event string
|
||||
Data []byte
|
||||
// FileOnly 只落文件、不写额外驱动(allLevelToInfo 的镜像任务用)
|
||||
FileOnly bool
|
||||
}
|
||||
|
||||
// toAsync 尝试异步写入
|
||||
// fileOnly 表示这条任务只落文件、不走驱动(见 writeFileOnly)
|
||||
// 返回 true 表示已经交给异步队列,返回 false 表示需要同步写入
|
||||
func (l *Logger) toAsync(event string, b []byte) bool {
|
||||
func (l *Logger) toAsync(event string, b []byte, fileOnly bool) bool {
|
||||
if l.writeType == writeTypeSync || // 指定同步模式
|
||||
(l.writeType == writeTypeDefault && l.option.writeType != writeTypeAsync) { // 默认同步模式
|
||||
return false
|
||||
@@ -259,7 +289,7 @@ func (l *Logger) toAsync(event string, b []byte) bool {
|
||||
data := make([]byte, len(b))
|
||||
copy(data, b)
|
||||
|
||||
ch <- cacheData{Channel: l.channel, Event: event, Data: data}
|
||||
ch <- cacheData{Channel: l.channel, Event: event, Data: data, FileOnly: fileOnly}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -285,6 +315,13 @@ func (l *Logger) consumeOne(val cacheData) {
|
||||
}
|
||||
}()
|
||||
// 按任务里记的 channel 落盘,避免多个 channel 的日志混到根目录
|
||||
if val.FileOnly {
|
||||
// 镜像只落文件;失败必须上报,否则异步模式下 info.log 写不进去是静默的
|
||||
if _, err := l.storeFileOnlyTo(val.Channel, val.Event, val.Data); err != nil {
|
||||
l.reportError(fmt.Errorf("loggerx: 写入 info 日志失败: %w", err))
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _ = l.storeTo(val.Channel, val.Event, val.Data)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user