xlog

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 9, 2026 License: MIT Imports: 7 Imported by: 0

README

xlog

xlog 是一个基于 go.uber.org/zap 封装的 Go 日志库,目标是在保留高性能的同时,提供更易用、更统一的日志调用方式。

它同时支持:

  • 全局单例日志器,适合中小型项目快速接入
  • 面向接口的日志抽象,便于依赖注入与测试替换
  • 普通日志、格式化日志、键值对日志、字段日志等多种调用风格
  • 运行时动态切换日志级别
  • 子日志器扩展
  • 文件输出与自动轮转
  • 未显式初始化时的懒加载默认日志器

当前仓库模块路径:github.com/xmapst/xlog


功能特性

1. 基于 Zap 的高性能封装

底层依赖 go.uber.org/zapzapcore,既支持 SugaredLogger 的便捷写法,也支持 Logger + Field 的高性能结构化写法。

2. 统一的日志接口

仓库通过 ILogger 抽象出完整日志能力,覆盖以下级别:

  • Debug
  • Info
  • Warn / Warning
  • Error
  • DPanic
  • Panic
  • Fatal

每个级别基本都支持以下五种风格:

  • 普通参数风格:如 Info(...)
  • 换行风格:如 Infoln(...)
  • 格式化风格:如 Infof(...)
  • 键值对风格:如 Infow(...)
  • 字段风格:如 Infox(...)
3. 支持全局直接调用

通过 xlog.go 暴露一组包级函数,可以直接使用:

  • xlog.Info(...)
  • xlog.Warnf(...)
  • xlog.Errorw(...)
  • xlog.Debugx(...)

这种方式适合快速集成,无需在业务层显式维护 logger 实例。

4. 支持懒初始化

如果业务代码没有主动调用 SetupLogger(),首次调用任意包级日志函数时会自动触发默认初始化逻辑 initDefaultLogger()

默认行为是:

  • 输出到标准输出
  • 使用当前全局级别控制器
  • 立即可用,适合脚本、小工具、测试代码
5. 支持运行时动态调整日志级别

通过 SetLevel() 可在程序运行期间动态切换日志级别,无需重启服务。

当前实现基于 zap.NewAtomicLevelAt() 创建原子级别控制器,默认初始级别为 Debug

6. 支持文件输出与轮转

SetupLogger() 传入非空文件路径时,日志会输出到文件,并通过 fileWriter() 创建的 timberjack 写入器执行自动轮转。

当前轮转策略为:

  • 单文件最大 50MB
  • 最多保留 7 个备份文件
  • 最长保留 7
  • 24 小时轮转一次
  • 本地时间
  • 备份时间格式:2006-01-02-15-04-05
7. 自动附加调用位置与错误堆栈

SetupLogger() 中默认启用了:

  • zap.AddCaller():输出调用文件与行号
  • zap.AddCallerSkip(2):跳过封装层,尽量定位到业务实际调用处
  • zap.AddStacktrace(zapcore.ErrorLevel)Error 及以上级别自动附带调用栈
8. 支持子日志器

可通过以下函数创建子日志器:

  • SubLogger()
  • SubLoggerWithFields()
  • SubLoggerWithKeyValue()
  • SubLoggerWithOption()

子日志器适用于:

  • 为不同模块附加固定字段
  • 为请求上下文附加 trace / request id
  • 对局部组件定制 logger 选项

安装

使用 go get
go get github.com/xmapst/xlog
当前依赖

根据 go.mod,本项目核心依赖包括:


快速开始

最小示例:输出到标准输出
package main

import (
	"github.com/xmapst/xlog"
)

func main() {
	xlog.SetupLogger("")
	defer xlog.CloseLogger()

	xlog.Info("service started")
	xlog.Infof("listen at %s", ":8080")
	xlog.Warnw("slow request", "path", "/healthz", "cost_ms", 120)
}
输出到文件
package main

import "github.com/xmapst/xlog"

func main() {
	xlog.SetupLogger("logs/app.log")
	defer xlog.CloseLogger()

	xlog.Info("write log to file")
	xlog.Error("something wrong")
}
不手动初始化也可以使用
package main

import "github.com/xmapst/xlog"

func main() {
	// 未调用 SetupLogger,会在首次输出时自动初始化默认 logger
	xlog.Info("hello from default logger")
}

初始化与生命周期管理

初始化日志器

使用 SetupLogger() 初始化全局日志器:

xlog.SetupLogger("")

或输出到文件:

xlog.SetupLogger("logs/app.log")
参数说明
  • 空字符串:输出到标准输出
  • 非空字符串:输出到指定文件,并启用文件轮转
程序退出前刷盘

使用 CloseLogger() 在程序退出前将缓冲区刷写到底层输出:

defer xlog.CloseLogger()

这在文件日志场景尤其重要,可避免最后几条日志未及时落盘。


日志格式说明

当前日志编码在 SetupLogger() 中使用 ConsoleEncoder,核心字段如下:

  • 时间:time
  • 级别:level
  • 调用位置:line
  • 消息:message
  • 堆栈:stacktrace

时间格式为:

2006-01-02 15:04:05.999

级别会被转换为大写文本,例如:

  • DEBUG
  • INFO
  • WARN
  • ERROR

调用位置输出类似:

[main.go:18]
典型输出示例
2026-06-09 15:30:45.123 INFO [main.go:18] service started
2026-06-09 15:30:45.124 WARN [handler/user.go:52] slow request path=/api/user cost_ms=138

说明:实际输出细节会受到调用风格、字段内容以及底层 Zap 编码方式影响。


日志级别与调用方式

日志级别概览

本仓库支持如下日志级别:

  • Debug
  • Info
  • Warn
  • WarningWarn 的别名)
  • Error
  • DPanic
  • Panic
  • Fatal
普通参数风格

适合快速输出多个参数,底层由 SugaredLogger 处理。

xlog.Info("user login", 1001, "from", "web")
换行风格

在普通输出基础上附加换行语义:

xlog.Infoln("task finished")
格式化风格

适合已有格式化模板的场景:

xlog.Infof("user=%s cost=%dms", name, cost)
键值对风格

适合结构化排查与日志检索:

xlog.Infow("user login",
	"user_id", 1001,
	"source", "web",
	"success", true,
)
字段风格

适合追求性能和类型安全的场景:

package main

import (
	"github.com/xmapst/xlog"
	"go.uber.org/zap"
)

func main() {
	xlog.SetupLogger("")
	defer xlog.CloseLogger()

	xlog.Infox("user login",
		zap.Int("user_id", 1001),
		zap.String("source", "web"),
		zap.Bool("success", true),
	)
}

动态调整日志级别

通过 SetLevel() 可以实时切换日志级别:

package main

import (
	"github.com/xmapst/xlog"
	"go.uber.org/zap/zapcore"
)

func main() {
	xlog.SetupLogger("")
	defer xlog.CloseLogger()

	xlog.SetLevel(zapcore.InfoLevel)
	xlog.Debug("this log may be ignored")
	xlog.Info("this log will be printed")

	xlog.SetLevel(zapcore.DebugLevel)
	xlog.Debug("debug log is enabled now")
}

适用场景:

  • 线上临时打开 Debug 排查问题
  • 问题定位后恢复 InfoWarn
  • 配合管理接口动态控制日志噪音

子日志器用法

创建普通子日志器
child := xlog.SubLogger()
child.Info("from child logger")
附加固定字段
package main

import (
	"github.com/xmapst/xlog"
	"go.uber.org/zap"
)

func main() {
	xlog.SetupLogger("")
	defer xlog.CloseLogger()

	logger := xlog.SubLoggerWithFields(
		zap.String("module", "order"),
		zap.String("service", "trade"),
	)

	logger.Infow("create order", "order_id", "A10001")
}
通过键值对创建子日志器
fields := map[string]string{
	"service": "user-api",
	"node":    "node-01",
}

logger := xlog.SubLoggerWithKeyValue(fields)
logger.Info("child logger with fixed fields")
通过选项创建子日志器
logger := xlog.SubLoggerWithOption()
logger.Info("child logger with custom option")

说明:当前仓库对 SubLoggerWithOption() 进行了透传封装,适合后续与更多 Zap 选项组合使用。


接口设计说明

ILogger 是本库最核心的抽象接口,适合作为业务层依赖注入的边界。例如:

type Service struct {
	logger xlog.ILogger
}

func NewService(logger xlog.ILogger) *Service {
	return &Service{logger: logger}
}

func (s *Service) Run() {
	s.logger.Infow("service run", "module", "demo")
}

这种设计的优点:

  • 业务代码不直接依赖具体实现
  • 更容易为测试注入 mock logger
  • 更方便切换全局 logger / 子 logger
  • 更容易在大型项目中保持统一日志规范

Print 系列说明

除了常见的 Info/Debug/Warn 等方法外,接口中还定义了:

  • Print(...)
  • Println(...)
  • Printf(...)
  • Printw(...)
  • Printx(...)

这些方法在实现中会映射到 Info 级别,相关逻辑可见:

  • Print()
  • Println()
  • Printf()
  • Printw()
  • Printx()

如果你的代码中习惯使用类似标准库 log 的写法,这组方法会更顺手。


Warning 系列说明

为兼容部分依赖 Warning 命名的方法接口(例如某些第三方组件或 gRPC 相关生态),本库提供了 Warning 系列作为 Warn 的别名:

  • Warning(...)
  • Warningln(...)
  • Warningf(...)
  • Warningw(...)
  • Warningx(...)

对应实现位于 logger.goxlog.go 中。


文件轮转策略

当日志输出到文件时,底层通过 github.com/DeRuina/timberjack 实现轮转,相关配置定义于 fileWriter()

当前策略如下:

配置项 当前值 说明
MaxSize 50 单个日志文件最大 50MB
MaxBackups 7 最多保留 7 个备份文件
MaxAge 7 最长保留 7 天
RotationInterval 24h 每 24 小时轮转一次
Compression none 不压缩
LocalTime true 使用本地时间
BackupTimeFormat 2006-01-02-15-04-05 备份文件时间格式

如果后续需要按项目要求自定义轮转策略,可以直接扩展 fileWriter() 或增加新的初始化入口。


源码结构

当前仓库核心文件如下:

  • xlog.go:对外暴露包级日志函数与全局 root logger 入口
  • setup.go:初始化、关闭、动态级别控制、文件写入器创建
  • logger.goILogger 接口定义与 zLogger 实现
  • go.mod:模块与依赖声明
  • LICENSE:MIT 许可证

设计取舍与适用场景

适合的场景
  • Go 服务端项目
  • CLI / 工具型程序
  • 希望快速拥有统一日志规范的项目
  • 需要同时兼顾易用性和性能的项目
  • 需要支持子日志器与结构化日志的业务系统
当前封装的优势
  • 包级 API 上手成本低
  • 接口抽象完整,利于工程化
  • 保留 Zap 的性能优势
  • 支持文件轮转和动态级别
  • 默认日志格式对人类可读性较友好
需要注意的点
  • 当前为全局单例模型,若项目中存在多套完全独立日志配置,需要自行扩展实例化能力
  • SetupLogger() 每次调用都会重建全局 logger,建议在程序启动阶段统一初始化
  • Fatal 会直接终止进程,Panic / DPanic 会触发恐慌,使用前应明确其副作用
  • CloseLogger() 内部会调用底层 Sync,建议在 main 中通过 defer 统一收尾

常见使用建议

建议 1:在 main 中统一初始化
func main() {
	xlog.SetupLogger("logs/app.log")
	defer xlog.CloseLogger()

	// business logic
}
建议 2:业务普通日志优先使用 Infow/Errorw

结构化字段更利于日志平台检索和告警聚合。

建议 3:高频热点路径优先使用 Infox/Debugx

当日志调用位于性能敏感路径时,优先使用 zap.Field 风格以降低额外开销。

建议 4:为模块创建子日志器
orderLogger := xlog.SubLoggerWithKeyValue(map[string]string{
	"module": "order",
})
orderLogger.Info("module logger ready")

这样可以减少重复字段拼接,并提升日志语义一致性。


一个相对完整的示例

package main

import (
	"errors"

	"github.com/xmapst/xlog"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

func main() {
	xlog.SetupLogger("logs/app.log")
	defer xlog.CloseLogger()

	xlog.SetLevel(zapcore.DebugLevel)

	xlog.Info("application booting")
	xlog.Infof("http server listen on %s", ":8080")
	xlog.Infow("config loaded", "env", "prod", "version", "1.0.0")

	xlog.Debugx("request received",
		zap.String("path", "/api/orders"),
		zap.String("method", "POST"),
	)

	orderLogger := xlog.SubLoggerWithKeyValue(map[string]string{
		"module": "order",
		"service": "trade-api",
	})
	orderLogger.Infow("create order", "order_id", "OD20260609001")

	err := errors.New("inventory not enough")
	xlog.Errorw("create order failed", "err", err, "order_id", "OD20260609001")
}

许可证

本项目基于 MIT License 开源发布。


结语

如果你希望在 Go 项目中快速获得一套统一、易用、可结构化、支持动态级别与文件轮转的日志能力,xlog 是一个轻量直接的选择。

对于小型项目,你可以直接使用 xlog.go 提供的包级函数;对于中大型项目,则可以围绕 ILogger 构建更清晰的依赖注入与模块化日志体系。

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CloseLogger

func CloseLogger()

CloseLogger 在进程退出前调用,将缓冲区中未写入的日志强制刷写到磁盘。

Zap 为了性能会缓冲部分日志,不调用 Sync 可能导致最后几条日志丢失。 建议在 main 函数中通过 defer CloseLogger() 确保此函数被调用。

func DPanic

func DPanic(args ...any)

DPanic 在 Development 模式下 panic,生产模式下仅记录日志。

func DPanicf

func DPanicf(format string, args ...any)

DPanicf 同 DPanic,支持格式化字符串。

func DPanicln

func DPanicln(args ...any)

DPanicln 同 DPanic,末尾追加换行。

func DPanicw

func DPanicw(msg string, keysAndValues ...any)

DPanicw 同 DPanic,支持键值对结构化输出。

func DPanicx

func DPanicx(msg string, fields ...zapcore.Field)

DPanicx 同 DPanic,以 zapcore.Field 方式输出高性能日志。

func Debug

func Debug(args ...any)

Debug 输出 Debug 级别日志。

func Debugf

func Debugf(format string, args ...any)

Debugf 输出格式化的 Debug 级别日志。

func Debugln

func Debugln(args ...any)

Debugln 输出 Debug 级别日志(末尾追加换行)。

func Debugw

func Debugw(msg string, keysAndValues ...any)

Debugw 输出带键值对的 Debug 级别结构化日志。

func Debugx

func Debugx(msg string, fields ...zapcore.Field)

Debugx 以 zapcore.Field 方式输出高性能 Debug 级别日志(零分配)。

func Error

func Error(args ...any)

Error 输出 Error 级别日志,自动附加调用栈信息。

func Errorf

func Errorf(format string, args ...any)

Errorf 输出格式化的 Error 级别日志。

func Errorln

func Errorln(args ...any)

Errorln 输出 Error 级别日志(末尾追加换行)。

func Errorw

func Errorw(msg string, keysAndValues ...any)

Errorw 输出带键值对的 Error 级别结构化日志。

func Errorx

func Errorx(msg string, fields ...zapcore.Field)

Errorx 以 zapcore.Field 方式输出高性能 Error 级别日志(零分配)。

func Fatal

func Fatal(args ...any)

Fatal 输出 Fatal 级别日志,并调用 os.Exit(1) 终止进程。

func Fatalf

func Fatalf(format string, args ...any)

Fatalf 同 Fatal,支持格式化字符串。

func Fatalln

func Fatalln(args ...any)

Fatalln 同 Fatal,末尾追加换行。

func Fatalw

func Fatalw(msg string, keysAndValues ...any)

Fatalw 同 Fatal,支持键值对结构化输出。

func Fatalx

func Fatalx(msg string, fields ...zapcore.Field)

Fatalx 同 Fatal,以 zapcore.Field 方式输出高性能日志。

func Info

func Info(args ...any)

Info 输出 Info 级别日志。

func Infof

func Infof(format string, args ...any)

Infof 输出格式化的 Info 级别日志。

func Infoln

func Infoln(args ...any)

Infoln 输出 Info 级别日志(末尾追加换行)。

func Infow

func Infow(msg string, keysAndValues ...any)

Infow 输出带键值对的 Info 级别结构化日志。

func Infox

func Infox(msg string, fields ...zapcore.Field)

Infox 以 zapcore.Field 方式输出高性能 Info 级别日志(零分配)。

func Panic

func Panic(args ...any)

Panic 输出 Panic 级别日志,并调用 panic() 触发运行时恐慌。

func Panicf

func Panicf(format string, args ...any)

Panicf 同 Panic,支持格式化字符串。

func Panicln

func Panicln(args ...any)

Panicln 同 Panic,末尾追加换行。

func Panicw

func Panicw(msg string, keysAndValues ...any)

Panicw 同 Panic,支持键值对结构化输出。

func Panicx

func Panicx(msg string, fields ...zapcore.Field)

Panicx 同 Panic,以 zapcore.Field 方式输出高性能日志。

func SetLevel

func SetLevel(l zapcore.Level)

SetLevel 动态调整全局日志输出级别,无需重启服务即时生效。

适用场景:生产环境临时开启 Debug 日志排查问题,排查完毕后恢复 Info 级别。

func SetupLogger

func SetupLogger(logfile string)

SetupLogger 初始化全局日志器。

日志格式(Console 格式):时间 级别 [文件:行号] 消息

logfile 参数行为:

  • 空字符串:日志输出到 stdout
  • 非空路径:日志输出到指定文件(通过 timberjack 自动按天轮转)

配置要点:

  • AddCallerSkip(2):跳过封装层调用帧,确保显示业务代码的真实调用位置
  • AddStacktrace(ErrorLevel):Error 及以上级别自动附加调用栈,便于问题定位
  • 时间格式含毫秒(.999),兼顾可读性和精度

func Warn

func Warn(args ...any)

Warn 输出 Warn 级别日志。

func Warnf

func Warnf(format string, args ...any)

Warnf 输出格式化的 Warn 级别日志。

func Warning

func Warning(args ...any)

Warning 是 Warn 的别名,兼容 gRPC 等期望 Warning 方法的第三方接口。

func Warningf

func Warningf(format string, args ...any)

Warningf 是 Warnf 的别名。

func Warningln

func Warningln(args ...any)

Warningln 是 Warnln 的别名。

func Warningw

func Warningw(msg string, keysAndValues ...any)

Warningw 是 Warnw 的别名。

func Warningx

func Warningx(msg string, fields ...zapcore.Field)

Warningx 是 Warnx 的别名。

func Warnln

func Warnln(args ...any)

Warnln 输出 Warn 级别日志(末尾追加换行)。

func Warnw

func Warnw(msg string, keysAndValues ...any)

Warnw 输出带键值对的 Warn 级别结构化日志。

func Warnx

func Warnx(msg string, fields ...zapcore.Field)

Warnx 以 zapcore.Field 方式输出高性能 Warn 级别日志(零分配)。

Types

type ILogger

type ILogger interface {
	Print(...any)
	Println(...any)
	Printf(string, ...any)
	Printw(string, ...any)
	Printx(string, ...zapcore.Field)

	Debug(...any)
	Debugln(...any)
	Debugf(string, ...any)
	Debugw(string, ...any)
	Debugx(string, ...zapcore.Field)

	Info(...any)
	Infoln(...any)
	Infof(string, ...any)
	Infow(string, ...any)
	Infox(string, ...zapcore.Field)

	Warn(...any)
	Warnln(...any)
	Warnf(string, ...any)
	Warnw(string, ...any)
	Warnx(string, ...zapcore.Field)

	Warning(...any)
	Warningln(...any)
	Warningf(string, ...any)
	Warningw(string, ...any)
	Warningx(string, ...zapcore.Field)

	Error(...any)
	Errorln(...any)
	Errorf(string, ...any)
	Errorw(string, ...any)
	Errorx(string, ...zapcore.Field)

	Panic(...any)
	Panicln(...any)
	Panicf(string, ...any)
	Panicw(string, ...any)
	Panicx(string, ...zapcore.Field)

	Fatal(...any)
	Fatalln(...any)
	Fatalf(string, ...any)
	Fatalw(string, ...any)
	Fatalx(string, ...zapcore.Field)

	DPanic(...any)
	DPanicln(...any)
	DPanicf(string, ...any)
	DPanicw(string, ...any)
	DPanicx(string, ...zapcore.Field)

	Enabled(level zapcore.Level) bool
	SubLogger() ILogger
	SubLoggerWithFields(fields ...zap.Field) ILogger
	SubLoggerWithKeyValue(map[string]string) ILogger
	SubLoggerWithOption(...zap.Option) ILogger
}

ILogger 定义完整的日志记录接口,覆盖 Debug/Info/Warn/Error/Panic/Fatal/DPanic 七个级别。

每个级别提供五种调用风格:

  • 普通风格(Debug):接受任意参数,空格分隔
  • 换行风格(Debugln):同普通风格,末尾追加换行
  • 格式化风格(Debugf):fmt.Sprintf 格式
  • 键值对风格(Debugw):msg + key/value 对,适合结构化日志
  • 字段风格(Debugx):msg + zapcore.Field,性能最优,零内存分配

Warning 系列是 Warn 系列的别名,兼容 gRPC 等期望 Warning 方法的接口。

func SubLogger

func SubLogger() ILogger

SubLogger 获取继承当前配置的子 Logger。

func SubLoggerWithFields

func SubLoggerWithFields(fields ...zap.Field) ILogger

SubLoggerWithFields 获取附加了固定字段的子 Logger。

func SubLoggerWithKeyValue

func SubLoggerWithKeyValue(keysAndValues map[string]string) ILogger

SubLoggerWithKeyValue 通过键值对 map 获取附加了固定字段的子 Logger。

func SubLoggerWithOption

func SubLoggerWithOption(opts ...zap.Option) ILogger

SubLoggerWithOption 通过 zap.Option 获取自定义配置的子 Logger。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL