基于 log/slog 的 Go 日志库,提供多路输出、彩色打印、文件轮转、远程传输等能力。
package main
import "github.com/injoyai/logs/v2"
func main() {
// 开箱即用
logs.Debug("调试信息")
logs.Info("普通信息")
logs.Error("错误信息")
// 计时
defer logs.Spend("操作耗时: ")()
// 自定义实体,写入文件
logs.New("业务日志").
SetSelfLevel(logs.LevelInfo).
WriteToFile("./output/{type}.log",
logs.WithMaxSize(100),
logs.WithMaxAge(30),
).
Println("这是一条业务日志")
}go get github.com/injoyai/logs/v2依赖:fatih/color(终端颜色)、lumberjack(文件轮转)。
从低到高,handler 只输出 >= 设定等级 的日志:
| 等级 | 常量 | 说明 |
|---|---|---|
| ALL | LevelAll |
全部 |
| TRACE | LevelTrace |
追溯 |
| DEBUG | LevelDebug |
调试 |
| READ | LevelRead |
读取 |
| WRITE | LevelWrite |
写入 |
| INFO | LevelInfo |
信息 |
| WARN | LevelWarn |
警告 |
| ERROR | LevelError |
错误 |
| NONE | LevelNone |
无 |
// 全局设置
logs.SetLevel(logs.LevelDebug)
// 单个实体设置
entity.SetLevel(logs.LevelWarn)Entity 是核心类型,包装 slog.Logger。每个 Entity 拥有独立的名称、标签、颜色、等级和输出目标。
// 创建(同名返回同一实例,线程安全)
e := logs.New("模块A")
// 链式配置
e.SetTag("v1.0", "生产").
SetColor(color.FgCyan).
SetShowColor(true).
SetLevel(logs.LevelDebug)所有输出目标统一实现 io.Writer,通过 SetWriter / AddWriter 挂载到 Entity 上。
控制日志行的输出格式。
logs.New("业务").
SetFormatter(logs.DefaultFormatter). // 默认:[名称] 日期 时间 文件:行 [标签] 内容
SetFormatter(logs.TimeFormatter). // 简洁:HH:MM:SS [名称] [标签] 内容
SetFormatter(logs.JsonFormatter). // JSON:{"name":"...","time":"...","msg":"..."}
SetFormatter(logs.FormatFunc(func(r *logs.FormatRecord) string {
return r.Msg // 仅输出消息本身
}))所有预设函数自带颜色和标签,开箱即用:
| 函数 | 颜色 | 级别 | 说明 |
|---|---|---|---|
Trace() |
绿色 | TRACE | 请求链路追溯 |
Debug() |
黄色 | DEBUG | 调试输出 |
Read() |
蓝色 | READ | 数据读取 |
Write() |
蓝色 | WRITE | 数据写入 |
Info() |
青色 | INFO | 一般信息 |
Warn() |
品红 | WARN | 警告 |
Error() |
红色 | ERROR | 错误(不退出) |
Fatal() |
红色 | ERROR | 错误后 os.Exit |
Panic() |
红色 | ERROR | 错误后 panic |
每种函数都有 Xxxf 格式化版本(如 Infof("value=%d", v))。
默认输出,支持颜色和交互式过滤:
e.WriteToConsole() // 默认已启用
logs.EnableStdoutFilter() // 终端输入关键词实时过滤
logs.StopStdoutFilter() // 停止过滤e.WriteToFile("./logs/{type}.log",
logs.WithMaxSize(100), // 单文件上限 100MB
logs.WithMaxBackups(10), // 保留 10 个旧文件
logs.WithMaxAge(30), // 保留 30 天
logs.WithCompress(true), // 压缩旧文件
logs.WithLocalTime(false), // UTC 时间命名
)
// {type} 会被替换为实体名,如 "./logs/业务日志.log"// 输出端 — 作为客户端发送日志
if err := e.WriteToTCPClient("192.168.1.100:10086"); err != nil {
// 处理连接错误
}
// 接收端 — 作为服务端收集日志
logs.DialTCP("0.0.0.0:10086", func(p []byte) {
fmt.Print(string(p))
})
// 广播模式 — 服务端转发给所有连接客户端
w, _ := logs.NewTCPServer(10086)
e.AddWriter(w)e.WriteToHTTPServer("POST", "http://log-collector:8080/ingest",
logs.WithTimeout(5 * time.Second),
logs.WithInsecureSkipVerify(false),
)发布-订阅模式,多消费者共享:
// 发布
e.WriteToTrunk()
// 订阅
key := logs.Trunk.Subscribe(1024, func(data []byte) {
fmt.Print(string(data))
})
defer logs.Trunk.Unsubscribe(key)// 设置(覆盖)
e.SetWriter(myWriter)
// 追加(保留原有)
e.AddWriter(myWriter)
// 实现 io.Writer 即可接入
type MyOutput struct{}
func (m *MyOutput) Write(p []byte) (int, error) { /* ... */ }对所有已注册 Entity 生效:
logs.SetLevel(logs.LevelDebug) // 等级
logs.SetShowColor(true) // 颜色
logs.SetFormatter(logs.TimeFormatter) // 格式
logs.SetWriter(w) // 覆盖输出
logs.AddWriter(w) // 追加输出
logs.WriteToTCPClient("127.0.0.1:10086") // 所有日志写入 TCP基于 slog 的键值对支持:
// 记录时带属性
e.Log(logs.LevelInfo, "请求完成",
"method", "GET",
"url", "/api/users",
"latency", 12*time.Millisecond,
)
// 绑定固定属性
sub := e.With("service", "gateway", "env", "prod")
sub.Log(logs.LevelWarn, "连接池即将耗尽", "active", 98)// 显式启用颜色(默认已启)
e.SetShowColor(true)
// 选择颜色
e.SetColor(color.FgBlue)颜色仅对终端(Stdout/Stderr)和标记了 ColorWriter 的 writer 生效,文件和网络输出不会产生多余 ANSI 码。
Carriage Return Writer — 原地刷新输出(适合进度条):
w := logs.NewCarriageReturnWriter(logs.Stdout)
e.AddWriter(w)
// 每次写入前添加 \r\033[K 清除当前行用于依赖注入场景,实现常见 Logger 接口:
var logger *logs.Logger // 空方法集,可嵌入结构体
logger.Debug("注入调试日志")
logger.Infof("格式化: %s", val)DefaultFormatter:
[模块A] 2026-07-24 15:04:05 entity.go:392 [v1.0] 这是一条日志 key=value
TimeFormatter:
15:04:05 [模块A] [v1.0] 这是一条日志 key=value
JsonFormatter:
{"name":"模块A","time":"2026-07-24T15:04:05+08:00","tag":["v1.0"],"msg":"这是一条日志","key":"value"}MIT