This commit is contained in:
yun
2026-09-14 00:14:30 +08:00
parent 316c6420a7
commit 7e1b474823
20 changed files with 1885 additions and 166 deletions
+96 -7
View File
@@ -9,11 +9,12 @@ import (
type loggerOption struct {
prefix string // 日志前缀
format string // text json
format Format // json / text
dir string // 文件目录
isGinLog bool
isGid bool
isPrintFile bool
asGlobalLog bool // 是否接管全局 stdlib log(默认 false
writeType writeType // 是否异步罗盘
traceField string // trace字段
errorToInfo bool // 错误日志是否写入info日志
@@ -24,6 +25,8 @@ type loggerOption struct {
compress bool // 归档文件是否压缩为 .gz
compressLvl int // gzip 压缩级别
flushEvery time.Duration // 定时刷盘间隔,0 表示不开启
minLevel Level // 最低输出级别
onError func(error) // 内部错误回调
timeZone *time.Location // 时区
escapeHTML bool
expandData map[string]string // 扩展字段
@@ -40,11 +43,11 @@ const (
func defaultOptions() loggerOption {
return loggerOption{
isGinLog: true,
isGinLog: false, // 默认不接管 gin 写手:非 Gin 服务不该被改全局状态
isGid: true,
isPrintFile: true,
writeType: writeTypeDefault, // 默认同步
format: "json",
format: FormatJSON,
dir: "./log",
traceField: "trace_id",
days: 7,
@@ -99,17 +102,31 @@ func SetErrorToInfo() Option {
}
}
// 日志前缀
// 日志前缀
// 会加在每行日志最前面(JSON 与 text 都生效),便于多实例共用一个目录时区分来源
func SetPrefix(prefix string) Option {
return func(o *loggerOption) {
o.prefix = prefix
}
}
// 日志格式(默认json)
func SetFormat(format string) Option {
// 输出格式
type Format string
const (
// FormatJSON 每行一条 JSON(默认,推荐给采集端)
FormatJSON Format = "json"
// FormatText 每行一条紧凑文本,适合人直接看
FormatText Format = "text"
)
// 日志格式(默认 FormatJSON
// 传非法值时保持原值,不会静默切到别的格式
func SetFormat(format Format) Option {
return func(o *loggerOption) {
o.format = format
if format == FormatJSON || format == FormatText {
o.format = format
}
}
}
@@ -127,6 +144,78 @@ func SetGinLog(open bool) Option {
}
}
// 日志级别。级别低于设定值的日志会被直接丢弃,不落盘
type Level uint8
const (
LevelDebug Level = iota
LevelInfo
LevelWarn
LevelError
// LevelOff 关闭所有级别(连 error 也不写)
LevelOff
)
// String 便于打印
func (lv Level) String() string {
switch lv {
case LevelDebug:
return "debug"
case LevelInfo:
return "info"
case LevelWarn:
return "warn"
case LevelError:
return "error"
case LevelOff:
return "off"
default:
return "unknown"
}
}
// SetMinLevel 设置最低输出级别(默认 LevelDebug,即全部输出)
//
// 生产环境通常设成 LevelInfo:这样代码里的 Debug 调用不会白算一遍
// JSON、也不会落盘占空间
func SetMinLevel(lv Level) Option {
return func(o *loggerOption) {
o.minLevel = lv
}
}
// SetErrorHandler 注册内部错误处理回调(默认 nil)
//
// 用于把「日志库自身的故障」暴露给运维:磁盘满、句柄失效、归档压缩失败、
// 定时刷盘失败等。不注册时这些错误只体现在返回值里,而调用方通常忽略返回值,
// 问题就完全不可见了。
//
// 建议接到告警通道或一个「不会失败」的输出(例如 stderr):
//
// loggerx.NewLogger(ctx, loggerx.SetErrorHandler(func(err error) {
// fmt.Fprintln(os.Stderr, "loggerx:", err)
// }))
//
// 回调在写日志的调用栈上同步执行,务必保持轻量,
// 且不要在里面再调用本实例的日志方法(可能递归)
func SetErrorHandler(fn func(error)) Option {
return func(o *loggerOption) {
o.onError = fn
}
}
// 是否把全局标准库 log 的输出接管到本实例(默认 false,不接管)
//
// 默认不接管是刻意的:日志库在 import / NewLogger 时静默劫持宿主全局 log
// 会带来两个生产事故场景 —— 多个实例时后建的把先建的顶掉;
// Close 之后全局 log 仍指向已关闭实例,之后的日志被静默丢弃。
// 确需接管(例如老代码大量使用 log.Printf)时再显式打开。
func SetAsGlobalLog() Option {
return func(o *loggerOption) {
o.asGlobalLog = true
}
}
// 文件路径
func SetDir(dir string) Option {
return func(o *loggerOption) {