logs

package module
v7.6.0 Latest Latest
Warning

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

Go to latest
Published: Apr 16, 2024 License: MIT Imports: 18 Imported by: 6

README

logs Go PkgGoDev Go version codecov

高性能日志库

goos: darwin
goarch: amd64
pkg: github.com/imkira/go-loggers-bench
cpu: Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
BenchmarkLogsTextPositive-4   	100000000	       320.9 ns/op	      40 B/op	       2 allocs/op
BenchmarkLogsTextNegative-4   	1000000000	         9.407 ns/op	       0 B/op	       0 allocs/op
BenchmarkLogsJSONNegative-4   	1000000000	        11.42 ns/op	       0 B/op	       0 allocs/op
BenchmarkLogsJSONPositive-4   	65887180	       578.6 ns/op	      40 B/op	       2 allocs/op
import "github.com/issue9/logs/v7"

l := logs.New(logs.NewTextHandler(...))
l.DEBUG().Print("debug start...")

l.ERROR().AppendAttrs(map[string]interface{}{"k1":"v1"})
l.ERROR().Printf("带默认参数 k1=v1") // 不用 With 指定 k1,err 全都自动带上此参数

安装

go get github.com/issue9/logs/v7

版权

本项目采用 MIT 开源授权许可证,完整的授权说明可在 LICENSE 文件中找到。

Documentation

Overview

Package logs 高性能的日志系统

Index

Constants

View Source
const (
	DateMilliLayout = "2006-01-02T15:04:05.000"
	DateMicroLayout = "2006-01-02T15:04:05.000000"
	DateNanoLayout  = "2006-01-02T15:04:05.000000000"

	MilliLayout = "15:04:05.000"
	MicroLayout = "15:04:05.000000"
	NanoLayout  = "15:04:05.000000000"
)

常用的日志时间格式

Variables

This section is empty.

Functions

func FreeAttrLogs added in v7.2.0

func FreeAttrLogs(logs *AttrLogs)

FreeAttrLogs 回收 AttrLogs

如果需要频繁地生成 AttrLogs 且其生命周期都有固定的销毁时间点, 可以用此方法达到复用 AttrLogs 以达到些许性能提升。

NOTE: 此操作会让 logs 不再可用。

func IsValidLevel

func IsValidLevel(l Level) bool

Types

type AppendFunc

type AppendFunc = func(*Buffer)

type Attr

type Attr struct {
	K string
	V any
}

type AttrLogs added in v7.2.0

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

AttrLogs 带有固定属性的日志

func (*AttrLogs) AppendAttrs added in v7.2.0

func (l *AttrLogs) AppendAttrs(attrs map[string]any)

AppendAttrs 为所有的 Logger 对象添加属性

func (*AttrLogs) DEBUG added in v7.2.0

func (logs *AttrLogs) DEBUG() *Logger

func (*AttrLogs) ERROR added in v7.2.0

func (logs *AttrLogs) ERROR() *Logger

func (*AttrLogs) FATAL added in v7.2.0

func (logs *AttrLogs) FATAL() *Logger

func (*AttrLogs) INFO added in v7.2.0

func (logs *AttrLogs) INFO() *Logger

func (*AttrLogs) IsEnable added in v7.2.0

func (logs *AttrLogs) IsEnable(l Level) bool

IsEnable 指定级别日志是否会真实被启用

func (*AttrLogs) Logger added in v7.2.0

func (logs *AttrLogs) Logger(lv Level) *Logger

Logger 返回指定级别的日志对象

func (*AttrLogs) NewRecord added in v7.2.0

func (l *AttrLogs) NewRecord() *Record

func (*AttrLogs) TRACE added in v7.2.0

func (logs *AttrLogs) TRACE() *Logger

func (*AttrLogs) WARN added in v7.2.0

func (logs *AttrLogs) WARN() *Logger

type Buffer

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

Buffer []byte 复用对象池

同时实现了 xerrors.Printer 接口。 Handler 接口的实现中可能需要用到此对象。

func NewBuffer

func NewBuffer(detail bool) *Buffer

NewBuffer 声明 Buffer 对象

detail 是否打印错误信息的调用堆栈;

func (*Buffer) Append

func (w *Buffer) Append(v ...any) *Buffer

func (*Buffer) AppendBuffer

func (w *Buffer) AppendBuffer(f func(b *Buffer)) *Buffer

func (*Buffer) AppendBytes

func (w *Buffer) AppendBytes(b ...byte) *Buffer

func (*Buffer) AppendFloat

func (w *Buffer) AppendFloat(n float64, fmt byte, prec, bitSize int) *Buffer

func (*Buffer) AppendFunc

func (w *Buffer) AppendFunc(f AppendFunc) *Buffer

func (*Buffer) AppendInt

func (w *Buffer) AppendInt(n int64, base int) *Buffer

func (*Buffer) AppendString

func (w *Buffer) AppendString(s string) *Buffer

func (*Buffer) AppendTime

func (w *Buffer) AppendTime(t time.Time, layout string) *Buffer

func (*Buffer) AppendUint

func (w *Buffer) AppendUint(n uint64, base int) *Buffer

func (*Buffer) Appendf

func (w *Buffer) Appendf(format string, v ...any) *Buffer

func (*Buffer) Appendln

func (w *Buffer) Appendln(v ...any) *Buffer

func (*Buffer) Bytes

func (w *Buffer) Bytes() []byte

func (*Buffer) Detail

func (w *Buffer) Detail() bool

func (*Buffer) Free

func (w *Buffer) Free()

func (*Buffer) Len

func (w *Buffer) Len() int

func (*Buffer) Print

func (w *Buffer) Print(v ...any)

func (*Buffer) Printf

func (w *Buffer) Printf(f string, v ...any)

func (*Buffer) Println

func (w *Buffer) Println(v ...any)

func (*Buffer) Reset

func (w *Buffer) Reset(detail bool) *Buffer

func (*Buffer) Write

func (w *Buffer) Write(b []byte) (int, error)

type Handler

type Handler interface {
	// Handle 将 [Record] 写入日志
	//
	// [Record] 中各个字段的名称由处理器自行决定;
	// detail 表示是否显示错误的堆栈信息;
	//
	// NOTE: 此方法应该保证输出内容是以换行符作为结尾。
	Handle(r *Record)

	// New 根据当前对象的参数派生新的 [Handler] 对象
	//
	// detail 表示是否需要显示错误的调用堆栈信息;
	// lv 表示输出的日志级别;
	// attrs 表示日志属性;
	// 这三个参数主要供 [Handler] 缓存这些数据以提升性能;
	//
	// 对于重名的问题并无规定,只要 [Handler] 自身能处理相应的情况即可。
	//
	// NOTE: 即便所有的参数均为零值,也应该返回一个新的对象。
	New(detail bool, lv Level, attrs []Attr) Handler
}

Handler 日志后端的处理接口

func MergeHandler

func MergeHandler(w ...Handler) Handler

MergeHandler 将多个 Handler 合并成一个 Handler 接口对象

func NewDispatchHandler

func NewDispatchHandler(d map[Level]Handler) Handler

NewDispatchHandler 根据 Level 派发到不同的 Handler 对象

返回对象的 [Handler.New] 方法会根据其传递的 Level 参数从 d 中选择一个相应的对象返回。

func NewJSONHandler

func NewJSONHandler(w ...io.Writer) Handler

NewJSONHandler 返回将 Record 以 JSON 的形式写入 w 的对象

NOTE: 如果向 w 输出内容时出错,会将错误信息输出到终端作为最后的处理方式。

func NewNopHandler

func NewNopHandler() Handler

func NewTermHandler

func NewTermHandler(w io.Writer, foreColors map[Level]colors.Color) Handler

NewTermHandler 返回将 Record 写入终端的对象

w 表示终端的接口,可以是 os.Stderr 或是 os.Stdout, 如果是其它的实现者则会带控制字符一起输出; foreColors 表示各类别信息的字符颜色,背景始终是默认色,未指定的颜色会从 [defaultTermColors] 获取;

NOTE: 如果向 w 输出内容时出错,将会导致 panic。

func NewTextHandler

func NewTextHandler(w ...io.Writer) Handler

NewTextHandler 返回将 Record 以普通文本的形式写入 w 的对象

NOTE: 如果向 w 输出内容时出错,会将错误信息输出到终端作为最后的处理方式。

type Level

type Level int8
const (
	LevelInfo Level = iota
	LevelTrace
	LevelDebug
	LevelWarn
	LevelError
	LevelFatal
)

目前支持的日志类型

func AllLevels

func AllLevels() []Level

func ParseLevel

func ParseLevel(s string) (Level, error)

func (Level) MarshalText

func (l Level) MarshalText() ([]byte, error)

func (Level) String

func (l Level) String() string

func (*Level) UnmarshalText

func (l *Level) UnmarshalText(data []byte) error

type Logger

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

Logger 日志对象

func (*Logger) AppendAttrs

func (l *Logger) AppendAttrs(attrs map[string]any)

AppendAttrs 添加新属性

不会影响之前调用 Logger.New 生成的对象。

func (*Logger) Error

func (l *Logger) Error(err error)

func (*Logger) Handler

func (l *Logger) Handler() Handler

Handler 返回关联的 Handler 对象

func (*Logger) IsEnable

func (l *Logger) IsEnable() bool

IsEnable 当前日志是否会真实输出内容

此返回值与 Logs.IsEnable 返回的值是相同的。

func (*Logger) Level

func (l *Logger) Level() Level

Level 当前日志的类别

func (*Logger) LocaleString added in v7.1.0

func (l *Logger) LocaleString(s localeutil.Stringer)

func (*Logger) LogLogger

func (l *Logger) LogLogger() *log.Logger

LogLogger 将当前对象转换成标准库的日志对象

NOTE: 不要设置返回对象的 Prefix 和 Flag,这些配置项与当前模块的功能有重叠。 log.Logger 应该仅作为向 Logger 输入 [Record.Message] 内容使用。

func (*Logger) New

func (l *Logger) New(attrs map[string]any) *Logger

New 根据当前对象派生新的 Logger

新对象会继承当前对象的 [Logger.attrs] 同时还拥有参数 attrs。

func (*Logger) Print

func (l *Logger) Print(v ...any)

func (*Logger) Printf

func (l *Logger) Printf(format string, v ...any)

func (*Logger) String

func (l *Logger) String(s string)

func (*Logger) With

func (l *Logger) With(name string, val any) Recorder

With 创建 Recorder 对象

type Logs

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

func New

func New(h Handler, o ...Option) *Logs

New 声明 Logs 对象

h 如果为 nil,则表示采用 NewNopHandler

func (*Logs) AppendAttrs

func (logs *Logs) AppendAttrs(attrs map[string]any)

AppendAttrs 为所有的 Logger 对象添加属性

func (*Logs) CreatedFormat

func (logs *Logs) CreatedFormat() string

CreatedFormat created 的时间格式

如果返回空值,表示禁用在日志中显示时间信息。

func (*Logs) DEBUG

func (logs *Logs) DEBUG() *Logger

func (*Logs) ERROR

func (logs *Logs) ERROR() *Logger

func (*Logs) Enable

func (logs *Logs) Enable(level ...Level)

Enable 允许的日志通道

调用此函数之后,所有不在 level 参数的通道都将被关闭。

func (*Logs) FATAL

func (logs *Logs) FATAL() *Logger

func (*Logs) HasLocation

func (logs *Logs) HasLocation() bool

HasLocation 是否包含定位信息

func (*Logs) INFO

func (logs *Logs) INFO() *Logger

func (*Logs) IsEnable

func (logs *Logs) IsEnable(l Level) bool

IsEnable 指定级别日志是否会真实被启用

func (*Logs) Logger

func (logs *Logs) Logger(lv Level) *Logger

Logger 返回指定级别的日志对象

func (*Logs) New added in v7.2.0

func (logs *Logs) New(attrs map[string]any) *AttrLogs

New 声明一组带有 attrs 属性的日志

func (*Logs) NewRecord

func (logs *Logs) NewRecord() *Record

func (*Logs) SLogHandler

func (l *Logs) SLogHandler() slog.Handler

SLogHandler 将 logs 转换为 slog.Handler 接口

所有的 group 会作为普通 attr 的名称前缀,但是不影响 Level、Message 等字段。

func (*Logs) SetCreated

func (logs *Logs) SetCreated(v string)

SetCreated 指定日期的格式

如果 v 为空将会禁用日期显示。

func (*Logs) SetDetail added in v7.6.0

func (logs *Logs) SetDetail(v bool)

SetDetail 是否显示错误的堆栈信息

func (*Logs) SetLocale added in v7.6.0

func (logs *Logs) SetLocale(p *localeutil.Printer)

SetLocale 改变本地化对象

func (*Logs) SetLocation

func (logs *Logs) SetLocation(v bool)

SetLocation 设置是否输出位置信息

func (*Logs) TRACE

func (logs *Logs) TRACE() *Logger

func (*Logs) WARN

func (logs *Logs) WARN() *Logger

type Marshaler

type Marshaler interface {
	MarshalLog() string
}

Marshaler 定义了序列化日志属性的方法

[Recorder.With] 的 val 如果实现了该接口, 那么在传递进去之后会调用该接口转换成字符串之后保存。

type Option

type Option func(*Logs)

func WithAttrs

func WithAttrs(attrs map[string]any) Option

WithAttrs 为日志添加附加的固定字段

func WithCreated

func WithCreated(layout string) Option

WithCreated 指定日期的格式

如果 layout 为空将会禁用日期显示。

func WithDetail

func WithDetail(v bool) Option

WithDetail 错误信息的调用堆栈

如果向日志输出的是类型为 err 的信息,是否显示其调用堆栈。

NOTE: 该设置仅对 [Recorder.Error] 方法有效果, 如果将 err 传递给 [Recorder.Printf] 等方法,则遵照 fmt.Appendf 进行处理。

func WithLevels

func WithLevels(lv ...Level) Option

WithLevels 指定启用的日志级别

之后也可以通过 Logs.Enable 进行修改。

func WithLocale

func WithLocale(p *localeutil.Printer) Option

WithLocale 指定本地化信息

如果为 nil,那么将禁用本地化输出,如果多次调用,则以最后一次为准。

设置了此值为影响以下几个方法中实现了 localeutil.Stringer 的参数:

  • Recorder.Error 中的 error 类型参数;
  • Recorder.Print/Printf/Println 中的 any 类型参数;
  • Recorder.With 中的 any 类型参数

func WithLocation

func WithLocation(v bool) Option

WithLocation 是否显示定位信息

func WithStd

func WithStd() Option

WithStd 是否接管标准库中 log 和 log/slog 中的全局输出函数

type Record

type Record struct {

	// AppendCreated 添加字符串类型的日志创建时间
	//
	// 可能为空,根据 [Logs.CreatedFormat] 是否为空决定。
	AppendCreated AppendFunc

	// AppendMessage 向日志中添加字符串类型的日志消息
	//
	// 这是每一条日志的主消息,不会为空。
	AppendMessage AppendFunc

	// AppendLocation 添加字符串类型的日志触发位置信息
	//
	// 可能为空,根据 [Logs.HasLocation] 决定。
	AppendLocation AppendFunc

	// 额外的数据,比如由 [Recorder.With] 添加的数据。
	Attrs []Attr
	// contains filtered or unexported fields
}

Record 单条日志输出时产生的数据

NOTE: 该对象只能由 Logs.NewRecord 生成。

func (*Record) DepthError

func (e *Record) DepthError(depth int, err error) *Record

DepthError 输出 error 类型的内容到日志

depth 表示调用,2 表示调用此方法的位置;

如果 Logs.HasLocation 为 false,那么 depth 将不起实际作用。

func (*Record) DepthLocaleString added in v7.1.0

func (e *Record) DepthLocaleString(depth int, s localeutil.Stringer) *Record

DepthLocaleString 输出 localeutil.Stringer 类型的内容到日志

depth 表示调用,2 表示调用此方法的位置;

如果 Logs.HasLocation 为 false,那么 depth 将不起实际作用。

func (*Record) DepthPrint

func (e *Record) DepthPrint(depth int, v ...any) *Record

DepthPrint 输出任意类型的内容到日志

depth 表示调用,2 表示调用此方法的位置;

如果 Logs.HasLocation 为 false,那么 depth 将不起实际作用。

func (*Record) DepthPrintf

func (e *Record) DepthPrintf(depth int, format string, v ...any) *Record

DepthPrintf 输出任意类型的内容到日志

depth 表示调用,2 表示调用此方法的位置;

如果 Logs.HasLocation 为 false,那么 depth 将不起实际作用。

NOTE: 不会对内容进行翻译,否则对于字符串类型的枚举类型可能会输出意想不到的内容, 如果需要翻译内容,可以调用 Record.DepthLocaleString

func (*Record) DepthString

func (e *Record) DepthString(depth int, s string) *Record

DepthString 输出字符串类型的内容到日志

depth 表示调用,2 表示调用此方法的位置;

如果 Logs.HasLocation 为 false,那么 depth 将不起实际作用。

func (*Record) Output

func (e *Record) Output(l *Logger)

Output 输出当前记录到日志

type Recorder

type Recorder interface {
	// With 为输出的日志带上指定的参数
	//
	// 返回对象与当前对象未必是同一个,由实现者决定。
	// 且返回对象是一次性的,在调用 Error、String 等输出之后即被回收。
	//
	// 如果 val 实现了 [localeutil.Stringer] 或是 [Marshaler] 接口,
	// 将被转换成字符串保存。
	With(name string, val any) Recorder

	// Error 将一条错误信息作为一条日志输出
	//
	// 这是 Print 的特化版本,在已知类型为 error 时,
	// 采用此方法会比 Print(err) 有更好的性能。
	//
	// 如果 err 实现了 [xerrors.FormatError] 接口,同时也会打印调用信息。
	//
	// NOTE: 此操作之后,当前对象不再可用!
	Error(err error)

	// LocaleString 输出一条本地化的信息
	//
	// 这是 Print 的特化版本,在已知类型为 [localeutil.Stringer] 时,
	// 采用此方法会比 Print(s) 有更好的性能。
	//
	// NOTE: 此操作之后,当前对象不再可用!
	LocaleString(localeutil.Stringer)

	// String 将字符串作为一条日志输出
	//
	// 这是 Print 的特化版本,在已知类型为字符串时,
	// 采用此方法会比 Print(s) 有更好的性能。
	//
	// NOTE: 此操作之后,当前对象不再可用!
	String(s string)

	// 输出一条日志信息
	//
	// NOTE: 此操作之后,当前对象不再可用!
	Print(v ...any)

	// 输出一条日志信息
	//
	// NOTE: 此操作之后,当前对象不再可用!
	//
	// NOTE: 不会对内容进行翻译,否则对于字符串类型的枚举类型可能会输出意想不到的内容,
	// 如果需要翻译内容,可以调用 [Recorder.LocaleString]。
	Printf(format string, v ...any)
}

Recorder 定义了输出一条日志的各种方法

这可能是一个临时对象,当调用除 With 之外的方法输出日志之后, 将不再保证 Recorder 依然是有效的。

Directories

Path Synopsis
Package writers 提供了一组实现 io.Writer 接口的结构
Package writers 提供了一组实现 io.Writer 接口的结构
rotate
Package rotate 提供一个可以按文件大小进行分割的 io.Writer 实例
Package rotate 提供一个可以按文件大小进行分割的 io.Writer 实例

Jump to

Keyboard shortcuts

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