Help us shape the future of Go! Take the 2026 Go Developer Survey

logit

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package logit 是 pixiu 的日志模块:门面与核心同包,零第三方依赖,性能优先。

日常使用(不需要轮转时只需 import logit 一个包):

logger := logit.MustNew(logit.OptWriter(logit.Stdout()))
logit.SetDefault(logger) // 显式启用默认日志
defer logit.Close(logger)
ctx := context.Background()
ctx = logit.WithContextLogID(ctx)               // 入口初始化字段并生成链路 ID
ctx = logit.WithStart(ctx)                      // 记录请求起点
msgCtx := logit.NewContextScope(ctx)             // 并发消息各用独立字段存储
msgCtx = logit.NewDurationScope(msgCtx)          // 独立计时,不继承父请求耗时表
logit.AddField(ctx, logit.Str("uid", "42"))    // 请求级字段
logit.Info(ctx, "user login", logit.Int("uid", 42))
logit.AddDownstreamDurationAuto(ctx, "mysql", 12*time.Millisecond) // 自动生成 mysql_1
logit.InfoDuration(ctx, "request done")       // 自动追加 mysql_1、self 和 total 耗时
svc := logit.With(logit.Str("mod", "Order")) // 模块级子 Logger
svc.Error(ctx, "create failed", logit.Err(err))

WithContextLogID 每次调用都会追加新的 ID,只在入口调用一次;后续直接传递 ctx。 无需 ID 时仍使用 WithContext;已有 ID 时初始化后调用 AddMeta(ctx, Str(LogId, id))。LogIDFromContext 读取 meta 中最后一个非空字符串 LogId, 不从普通字段或调用点字段读取,不改变日志重复字段的输出规则。

基础功能模块可用 AddDownstreamDurationAuto 自动编号并记录下游耗时;ctx 没有 WithStart 时跳过,不要求未启用耗时统计的调用方额外初始化 context。

按 context 选择命名 Logger(未注册时回退默认 Logger):

logit.SetNamed("http", logit.MustNew(logit.OptWriter(logit.Stderr())))
httpCtx := logit.WithLoggerName(ctx, "http")
if logit.InfoEnabled(httpCtx) {
    logit.Output(httpCtx, logit.InfoLevel, 0, "request done")
}

DebugEnabled/InfoEnabled/WarnEnabled/ErrorEnabled 按 ctx 选择 Logger; 任意级别可通过 LoggerFromContext(ctx).Enabled(level) 判断。 无 ctx 的 logit.With 始终基于默认 Logger。上例 Output 的 callDepth=0 指向其直接调用者。

统一记录下游调用时,可用 DownstreamFields 生成四个标准字段:

fields := logit.DownstreamFields("httpcall", "wechat", 12*time.Millisecond,
    map[string]any{"method": "POST", "status": 200})
logit.Info(ctx, "downstream call", fields...)

四个标准字段名也可通过普通字段构造器直接写入。

构造专属实例(依赖注入 / 测试):

buf := &bytes.Buffer{}
logger := logit.MustNew(logit.OptWriter(logit.NewWriter(buf)))

生产落盘链路:

file, _ := rotatefile.New("/var/log/app/app.log") // 独立轮转包;要求绝对路径
rotated := logit.NewWriter(file)
logger := logit.MustNew(logit.OptDispatch(
    logit.Target{Levels: []logit.Level{logit.DebugLevel, logit.InfoLevel}, Writer: rotated},
))
defer logit.Close(logger) // 应用退出最后一步
_ = logit.SetMinLevel(logger, logit.InfoLevel) // 可在运行期原子调整

应用退出时,先停止接收新请求、等待后台任务结束并关闭其他组件,再关闭 Logger。 其他组件在收尾期间可能仍需记录日志,因此 logit.Close 应是资源关闭的最后一步。

多资源关闭时,可用 lifecycle.Stack 替代上例的 defer,按登记的逆序关闭:

var stack lifecycle.Stack
if err := stack.Register(func() error { return logit.Close(logger) }); err != nil {
    return err
}
if err := stack.Register(client.Close); err != nil { // client 由应用创建
    return err
}
// 停止业务入口并等待使用 client 的任务结束后:
return stack.Close() // 先关闭 client,最后关闭 logger

全局默认 Logger 初始为空操作 Logger;所有级别(含 Fatal)直接返回,不输出、不退出, 不校验输出字段或执行 Defer 回调;Enabled 始终为 false,With 仍为空操作,Close 返回 nil。 启动期用 SetDefault 显式启用;独立构造和显式注册的命名 Logger 不受默认配置影响。 初始化前取得的 Logger 或 With 子 Logger 保持空操作,需要输出时须重新获取。 使用 bootstrap 的新项目须先完成 MustBaseInit,再通过 Default、With 或 Named 创建和保存模块 Logger; 不要在先于 bootstrap 执行的包变量初始化或 Go 的 init() 中缓存这些 Logger。 后续 SetDefault 或命名注册不会更新已保存的空操作实例;包级 Info(ctx, ...) 等方法每次选择当前 Logger。 WithContext 前置约束及 panic 专用接口语义不受默认 Logger 是否配置影响。 测试可先用 Default 保存旧值,再用 SetDefault 替换并在结束时恢复。 panic 处理见 ReportPanic/RecoverAndReport;processStart 保存包初始化时的时间点, 输出时按当前 time.Local 格式化。应用必须在并发使用日志前完成默认时区设置。

Index

Constants

View Source
const (
	DownstreamTypeKey       = "downstream_type"
	DownstreamDurationMSKey = "downstream_duration_ms"
	DownstreamIDKey         = "downstream_id"
	DownstreamDetailsKey    = "downstream_details"
)

下游日志的标准字段名,调用方也可直接用普通字段构造器写入。

View Source
const LogId = "logId"

LogId 是链路 ID 的统一日志字段名;通过 AddMeta(ctx, Str(LogId, id)) 设置传播值。

Variables

View Source
var DefaultJSONEncoder = JSONEncoder{}

DefaultJSONEncoder 是共享的 JSON 编码器实例(无状态,可复用)。

View Source
var DefaultTextEncoder = TextEncoder{}

DefaultTextEncoder 是共享的文本编码器实例(无状态,可复用)。

View Source
var ErrLevelControlUnsupported = errors.New("logit: logger does not support runtime level control")

ErrLevelControlUnsupported 表示 Logger 没有实现运行时级别调整。

View Source
var ErrLoggerCloseUnsupported = errors.New("logit: logger does not support close")

ErrLoggerCloseUnsupported 表示自定义 Logger 未提供 Close 方法。

View Source
var ErrPanicLoggerNotConfigured = errors.New("logit: panic logger not configured")

ErrPanicLoggerNotConfigured 表示尚未设置 panic 专用 Logger。

Functions

func AddDebugField

func AddDebugField(ctx context.Context, fields ...Field)

AddDebugField 添加仅 Debug 级别日志行可见的字段(敏感调试信息不漏进 Info 日志)。 保留字段名会 panic。

func AddDownstreamDurationAuto

func AddDownstreamDurationAuto(ctx context.Context, prefix string, duration time.Duration)

AddDownstreamDurationAuto 自动为一次下游调用生成请求内唯一的 prefix_序号; 空 prefix、self、total 会 panic;有效 prefix 在 ctx 没有 WithStart 时跳过。 适合基础功能模块在不要求业务启用耗时统计时调用。

func AddField

func AddField(ctx context.Context, fields ...Field)

AddField 向普通作用域添加字段(所有级别可见)。ctx 必须已经 WithContext, 否则 panic——这是编程错误,应在首次测试时暴露。保留字段名也会 panic。

func AddMeta

func AddMeta(ctx context.Context, fields ...Field)

AddMeta 向 meta 作用域添加字段(全级别可见,派生 context 共享)。 保留字段名会 panic。

func CallerPath

func CallerPath(skip int) string

CallerPath 返回调用点 file:line(跳过 skip 层栈帧,0 = 调用 CallerPath 处), 路径裁剪掉模块前缀以缩短行宽。定位失败返回 "unknown"。

func Close

func Close(l Logger) error

Close 关闭 Logger 的全部目标 writer(应用优雅关闭的最后一步调用)。 自定义 Logger 实现 Close() error 时调用该方法,否则返回 ErrLoggerCloseUnsupported。

func Debug

func Debug(ctx context.Context, msg string, fields ...Field)

func DebugEnabled

func DebugEnabled(ctx context.Context) bool

DebugEnabled 报告 ctx 选中的 Logger 是否输出 Debug,超热路径守卫用:

if logit.DebugEnabled(ctx) { logit.Debug(ctx, "detail", logit.Defer(...)) }

ctx 未指定命名 Logger 时检查默认 Logger。

func Error

func Error(ctx context.Context, msg string, fields ...Field)

func ErrorEnabled

func ErrorEnabled(ctx context.Context) bool

func Fatal

func Fatal(ctx context.Context, msg string, fields ...Field)

func HookStderr

func HookStderr(w Writer) error

HookStderr 把进程标准错误劫持到 w:未捕获 panic 的 runtime 输出、 三方库错误打印等一并进入 w。要求与注意事项同 HookStdout。

func HookStdout

func HookStdout(w Writer) error

HookStdout 把进程标准输出劫持到 w:fmt.Println、三方库直接打印等 原本走 stdout 的输出改写入 w(推荐使用 OpenFile 打开独立文件)。 w 需实现 Fd() uintptr;nil Writer 返回错误。进程级一次性操作,重复调用以最后一次为准。

注意:dup2 劫持绑定的是打开瞬间的文件描述符;若目标文件会轮转, 轮转发生后续写仍落在已转出的旧文件(随保留策略被清理)。 建议劫持到独立的非轮转文件(如专用 std.log)。

func Info

func Info(ctx context.Context, msg string, fields ...Field)

func InfoDuration

func InfoDuration(ctx context.Context, msg string, fields ...Field)

InfoDuration 与 Info 相同;ctx 含 WithStart 起点时追加下游、自身和总耗时。

func InfoEnabled

func InfoEnabled(ctx context.Context) bool

func LogIDFromContext

func LogIDFromContext(ctx context.Context) (string, bool)

LogIDFromContext 返回 meta 中最后一个非空字符串 LogId。 普通字段、非字符串与空值不参与传播,也不会执行惰性字段回调。

func NewContextScope

func NewContextScope(parent context.Context) context.Context

NewContextScope 在保留 parent 取消与其他值的同时创建独立日志字段存储。 消息等并发入口不能复用 parent 的可变字段存储,否则字段会跨消息累积。

func NewDurationScope

func NewDurationScope(parent context.Context) context.Context

NewDurationScope 创建独立起点和下游耗时表,保留 parent 的取消、期限及其他值。 嵌套的独立工作使用此入口;普通派生仍用 WithStart 保留首次计时。

func NewLogID

func NewLogID() string

NewLogID 返回 RFC 9562 UUIDv4 的小写 canonical 字符串。

func Output

func Output(ctx context.Context, level Level, callDepth int, msg string, fields ...Field)

Output 按 ctx 选择 Logger 并输出;callDepth 为 0 时 caller 指向直接调用者。

func RecoverAndReport

func RecoverAndReport(ctx context.Context)

RecoverAndReport 是 defer 用的便捷 recover 处理器: 未配置 panic Logger 时重新抛出原 panic,避免静默吞掉异常。

defer logit.RecoverAndReport(ctx)

func ReportPanic

func ReportPanic(ctx context.Context, recovered any, fields ...Field) error

ReportPanic 记录一次 panic:panic 值、保留物理换行的 goroutine 栈、 pid 与按当前本地时区格式化的进程启动时间;以 Fatal 级别同步写入并尽力 Sync, 写入或 Sync 失败通过 PanicLogger 的 WriteErrorStats 观察,不承诺必然落盘。 未配置 panic Logger 时返回 ErrPanicLoggerNotConfigured;记录后不退出进程。 供 recover 处理器调用,也可用更省心的 RecoverAndReport。

func SetDefault

func SetDefault(l Logger)

SetDefault 替换默认 Logger(应用启动期调用一次),nil Logger 会 panic。

func SetMinLevel

func SetMinLevel(l Logger, level Level) error

SetMinLevel 在 Logger 支持时原子调整最低输出级别。

func SetNamed

func SetNamed(name string, l Logger)

SetNamed 注册命名 Logger(应用启动期调用),nil Logger 会 panic。

func SetPanicLogger

func SetPanicLogger(w Writer)

SetPanicLogger 从 Writer 构造 panic 专用 Logger(推荐使用独立 panic 文件, 需要轮转时由外部创建文件并通过 NewWriter 适配)。只路由 Fatal,固定文本编码、无 caller, 写入并尽力 Sync 后继续运行;无效 Writer 在此处 panic。

func Warn

func Warn(ctx context.Context, msg string, fields ...Field)

func WarnEnabled

func WarnEnabled(ctx context.Context) bool

func WithContext

func WithContext(ctx context.Context) context.Context

WithContext 初始化 ctx 的字段存储(普通 + meta 双作用域),已初始化则原样返回。 之后才可调用 AddField/AddMeta 等可变 API;服务入口处调用一次即可。

func WithContextLogID

func WithContextLogID(ctx context.Context) context.Context

WithContextLogID 初始化日志字段存储,并生成、追加一个新的链路 ID。 每次调用都会追加新 ID,应只在入口调用;后续直接传递返回的 context。

func WithLoggerName

func WithLoggerName(ctx context.Context, name string) context.Context

WithLoggerName 在 ctx 中设置命名 Logger 的路由键;空名字表示使用默认 Logger。 此路由不要求预先调用 WithContext,也不会写入日志字段。

func WithStart

func WithStart(ctx context.Context) context.Context

WithStart 在 ctx 中记录首次调用的时间点;已有起点时原样返回。 同时初始化请求级下游耗时表,不要求预先调用 WithContext。

Types

type Encoder

type Encoder interface {
	// AppendPrefix 追加行前缀(级别、时间,以及调用方已解析好的 caller)。
	AppendPrefix(buf []byte, level Level, now time.Time, caller string) []byte
	// AppendField 追加一个字段(f 已完成 Defer 求值与脱敏)。
	AppendField(buf []byte, f Field) []byte
	// AppendMessage 追加消息体。
	AppendMessage(buf []byte, msg string) []byte
	// Finish 追加行尾(如换行符)。
	Finish(buf []byte) []byte
}

Encoder 负责把一条日志记录的各部分按顺序追加进字节缓冲。 全部方法以 append 风格工作,编码过程零中间对象分配。 包外自定义实现仅支持包装或嵌入内置编码器,由内置编码器处理 Field; Field 的内部值不开放给包外独立实现字段编码。

type Field

type Field struct {
	Key string
	// contains filtered or unexported fields
}

Field 是值类型的日志字段:数值直接存进 num,不经过 interface 装箱、不逃逸。 float64 以位模式存于 num;布局 64B,5 字段变参切片 344B,降低调用点分配。 构造函数返回值,调用点以变参切片传给 Logger。

func Any

func Any(key string, v any) Field

Any 构造任意类型字段,编码时走反射序列化(冷路径,慎用于热路径)。

func Auto

func Auto(key string, v any) Field

Auto 依据运行时类型分发给强类型构造器,避免装箱;未识别类型退化为 Any。

func Bool

func Bool(key string, v bool) Field

Bool 构造 bool 字段。

func Defer

func Defer(key string, fn func() Field) Field

Defer 构造惰性字段:只有当日志行级别检查通过、真正编码时才调用 fn 求值。 fn 应返回一个不含 deferType 的普通字段;nil 回调在构造时 panic。

func DownstreamFields

func DownstreamFields(kind, id string, duration time.Duration, details map[string]any) []Field

DownstreamFields 构造统一的下游调用字段。 kind 为技术类型,id 为稳定的业务目标标识,duration 以毫秒数值输出, details 为自定义详情;nil details 输出空对象。

func Dur

func Dur(key string, v time.Duration) Field

Dur 构造 time.Duration 字段。

func Err

func Err(err error) Field

Err 构造 error 字段,构造时求一次 Error(),打印时零额外开销。

func ErrKey

func ErrKey(key string, err error) Field

ErrKey 构造自定义 key 的 error 字段。

func Float64

func Float64(key string, v float64) Field

Float64 构造 float64 字段。

func Int

func Int(key string, v int) Field

Int 构造 int 字段。

func Int64

func Int64(key string, v int64) Field

Int64 构造 int64 字段。

func Str

func Str(key string, v string) Field

Str 构造 string 字段。

func Time

func Time(key string, v time.Time) Field

Time 构造 time.Time 字段(装箱存储,属冷路径)。

func Uint64

func Uint64(key string, v uint64) Field

Uint64 构造 uint64 字段。

func (Field) Type

func (f Field) Type() FieldType

Type 返回字段类型。

type FieldType

type FieldType uint8

FieldType 标记 Field 携带的数据类型,编码器据此选择零反射的序列化路径。

type JSONEncoder

type JSONEncoder struct{}

JSONEncoder 输出有序 JSON 行:键顺序 = 编码顺序(前缀 → 字段 → msg), 直接追加进调用方缓冲,无中间 map、无排序。

字符串转义使用表驱动扫描和干净段整段拷贝,并转义 U+2028/U+2029; 输出与 encoding/json(SetEscapeHTML(false)) 逐字节一致,不转义 HTML 字符。

行形如:

{"level":"INFO","ts":"2026-09-15T10:00:00.123+08:00","logId":["..."],
 "uid":42,"msg":"user login"}

func (JSONEncoder) AppendField

func (JSONEncoder) AppendField(buf []byte, f Field) []byte

AppendField 实现 Encoder:写入 "key":value 与尾随逗号。

func (JSONEncoder) AppendMessage

func (JSONEncoder) AppendMessage(buf []byte, msg string) []byte

AppendMessage 实现 Encoder:写入 "msg":... 与尾随逗号。

func (JSONEncoder) AppendPrefix

func (JSONEncoder) AppendPrefix(buf []byte, level Level, now time.Time, caller string) []byte

AppendPrefix 实现 Encoder:写入 {"level":..,"ts":..(,"caller":..) 与尾随逗号。

func (JSONEncoder) Finish

func (JSONEncoder) Finish(buf []byte) []byte

Finish 实现 Encoder:去掉最后一个尾随逗号,闭合对象并换行。

type Level

type Level uint16

Level 是位掩码日志级别。单个级别只占一个比特,数值大小与严重程度一致, 因此可以直接用数值比较做"最低级别"过滤;字段可见性用位与判断。

const (
	// UnknownLevel 未设置级别。
	UnknownLevel Level = 0

	// DebugLevel 调试信息。
	DebugLevel Level = 1 << 0

	// InfoLevel 常规运行信息。
	InfoLevel Level = 1 << 1

	// WarnLevel 需要关注的异常。
	WarnLevel Level = 1 << 2

	// ErrorLevel 出错,但程序可继续运行。
	ErrorLevel Level = 1 << 3

	// FatalLevel 致命错误,程序无法继续运行。
	FatalLevel Level = 1 << 4

	// AllLevels 所有比特位置位,用于字段可见性:任意级别的日志行都输出该字段。
	AllLevels Level = 1<<8 - 1
)

func ParseLevel

func ParseLevel(s string) (Level, error)

ParseLevel 解析级别字符串,大小写不敏感,如 "info"、"ERROR"、"Warn"。 仅在加载配置时调用,不在热路径。

func (Level) Is

func (l Level) Is(lineLevel Level) bool

Is 报告字段可见性掩码 l 是否在 lineLevel 级别的日志行中可见。 例如 l=DebugLevel 只在 DebugLevel 日志行可见;l=AllLevels 在任何级别可见。

func (Level) String

func (l Level) String() string

String 返回级别名,如 "INFO"。

type LevelController

type LevelController interface {
	SetMinLevel(Level) error
	MinLevel() Level
}

LevelController 是 Logger 的可选运行时级别控制能力。

type Logger

type Logger interface {
	// Debug 打印 Debug 级别日志。
	Debug(ctx context.Context, msg string, fields ...Field)
	// Info 打印 Info 级别日志。
	Info(ctx context.Context, msg string, fields ...Field)
	// Warn 打印 Warn 级别日志。
	Warn(ctx context.Context, msg string, fields ...Field)
	// Error 打印 Error 级别日志。
	Error(ctx context.Context, msg string, fields ...Field)
	// Fatal 打印 Fatal 级别日志,尽力 Sync 后退出进程。
	Fatal(ctx context.Context, msg string, fields ...Field)
	// Output 打印指定级别日志;callDepth 用于二次封装时修正 caller 定位,
	// 0 表示 Output 的直接调用者。
	Output(ctx context.Context, level Level, callDepth int, msg string, fields ...Field)
	// Enabled 报告该级别日志是否会被输出,供热路径手动守卫:
	// if l.Enabled(DebugLevel) { ... } 可彻底省掉字段求值与变参分配。
	Enabled(level Level) bool
	// With 返回预埋了固定字段的子 Logger(如模块级 mod 字段),不改变其余行为。
	// 传入保留字段名会 panic。
	With(fields ...Field) Logger
}

Logger 是 pixiu 日志的核心接口。业务代码只依赖它,不依赖任何具体实现。

func Default

func Default() Logger

Default 返回当前默认 Logger;SetDefault 前为空操作 Logger,所有级别均不输出或退出。

func LoggerFromContext

func LoggerFromContext(ctx context.Context) Logger

LoggerFromContext 返回 ctx 指定的命名 Logger;无名字或未注册时返回默认 Logger。

func MustNew

func MustNew(opts ...Option) Logger

MustNew 构造 Logger,失败 panic(仅用于启动期)。

func Named

func Named(name string) Logger

Named 返回命名 Logger,未注册时退回全局默认。

func New

func New(opts ...Option) (Logger, error)

New 构造 Logger。无目标、空 Writer 或空 Levels 的 Target 视为配置错误。

func PanicLogger

func PanicLogger() Logger

PanicLogger 返回 panic 专用 Logger;未调用 SetPanicLogger 时返回 nil。

func With

func With(fields ...Field) Logger

With 返回基于默认 Logger 预埋固定字段的子 Logger(如模块名)。

type Option

type Option func(*config)

Option 是 Logger 的构造选项,支持配置文件与纯编程两种入口(P0 提供编程式, 配置文件加载由上层 app 模块解析后转成 Option 传入)。

func OptCaller

func OptCaller(on bool) Option

OptCaller 开启行前缀中的调用点定位(默认关闭,开销约百纳秒)。

func OptDispatch

func OptDispatch(targets ...Target) Option

OptDispatch 设置分级分发目标(如 Warn 以上写 .wf 文件)。 同一 Writer 可被多个 Target 复用。

func OptEncoder

func OptEncoder(enc Encoder) Option

OptEncoder 指定编码器,默认 DefaultTextEncoder;nil 编码器立即 panic。

func OptFileName

func OptFileName(name string) Option

OptFileName 设置绝对路径的追加模式日志文件作为单一目标。文件延迟到 New 最终校验后打开; 打开失败会让 New/MustNew 返回错误(启动期暴露,而不是静默丢日志)。

func OptFilterKeys

func OptFilterKeys(keys ...string) Option

OptFilterKeys 设置脱敏字段名:命中字段值统一打码为 ***。

func OptMinLevel

func OptMinLevel(l Level) Option

OptMinLevel 设置最低输出级别,低于该级别的日志直接丢弃,默认 DebugLevel。

func OptNoExit

func OptNoExit() Option

OptNoExit 让 Fatal 级别日志写入并尽力 Sync 后不退出进程。 用于 panic 日志等需要记录 Fatal、又要继续运行的 Logger。

func OptOnWriteError

func OptOnWriteError(fn func(error)) Option

OptOnWriteError 注册写入错误回调。日志调用仍不返回该错误;同一 Logger 及其 With 子 Logger 的回调串行执行。回调应快速完成,且不要写回同一个持续失败的 Logger。

func OptWriter

func OptWriter(w Writer) Option

OptWriter 设置单一目标:全部级别写到 w。

type Target

type Target struct {
	Levels []Level
	Writer Writer
}

Target 把若干级别路由到一个 Writer,实现分级文件(如 .wf)。

type TextEncoder

type TextEncoder struct{}

TextEncoder 输出以下格式的文本行:

INFO: 2026-09-14T18:00:00.000+08:00 main.go:42 uid=[42] msg=[user login]

func (TextEncoder) AppendField

func (TextEncoder) AppendField(buf []byte, f Field) []byte

AppendField 实现 Encoder。

func (TextEncoder) AppendMessage

func (TextEncoder) AppendMessage(buf []byte, msg string) []byte

AppendMessage 实现 Encoder。

func (TextEncoder) AppendPrefix

func (TextEncoder) AppendPrefix(buf []byte, level Level, now time.Time, caller string) []byte

AppendPrefix 实现 Encoder。

func (TextEncoder) Finish

func (TextEncoder) Finish(buf []byte) []byte

Finish 实现 Encoder:裁掉行尾多余分隔空格后换行。

type WriteErrorStats

type WriteErrorStats interface {
	WriteErrors() int64
	LastWriteError() error
}

WriteErrorStats 暴露被日志调用吞掉的底层写入错误,供监控与健康检查使用。

type Writer

type Writer interface {
	Write(p []byte) (int, error)
	Close() error
	WriterKey() WriterKey
}

Writer 是日志落盘目标的接口。NewWriter 可适配普通 io.Writer, OpenFile 提供同步追加文件;轮转文件可由外部按需创建后适配。

契约:Write 必须并发安全且单次调用写入完整记录(普通日志一行,panic 堆栈可多行)。 WriterKey 必须返回生命周期内不变的非零 key;同一 Writer 的副本共享 key。

func NewWriter

func NewWriter(w io.Writer) Writer

NewWriter 把非 nil io.Writer 适配为并发安全的 Writer;nil 输入立即 panic。 底层实现 io.Closer 时 Close 透传;带 Fd 的 io.WriteCloser 也透传文件描述符。 非 *os.File 目标发生短写时会在同一把锁内继续,避免与其他调用交错。

func OpenFile

func OpenFile(path string) (Writer, error)

OpenFile 要求绝对路径,以追加模式打开日志文件(自动创建父目录),返回同步 Writer。

func Stderr

func Stderr() Writer

Stderr 返回共享的标准错误输出 Writer;Close 不关闭进程标准错误输出。

func Stdout

func Stdout() Writer

Stdout 返回共享的标准输出 Writer;Close 不关闭进程标准输出。

type WriterKey

type WriterKey struct {
	// contains filtered or unexported fields
}

WriterKey 是可复制的 Writer 身份标识;零值无效。

func NewWriterKey

func NewWriterKey() WriterKey

NewWriterKey 为自定义 Writer 创建新的身份标识。

Jump to

Keyboard shortcuts

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