允许不同级别的写入info

This commit is contained in:
yun
2026-10-05 19:30:40 +08:00
parent 7e1b474823
commit a9adc11fad
6 changed files with 600 additions and 32 deletions
+40 -3
View File
@@ -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)
}