zlog

package module
v1.0.4 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2025 License: MIT Imports: 19 Imported by: 16

README

zlog

基于slog,主要扩展了TextHandler
实现了一个用于流式日志的SafeWriter,适用于长日志(比如gorm)

✅ 1. 支持 attrsReplace 拦截所有字段

  • 级别显示(比如用 emoji 🟢/🟡/🔴)
  • 消息内容(比如脱敏)
  • 源码路径(比如只显示包名)

✅ 2. 支持智能颜色控制, 终端有颜色,文件无颜色
✅ 3. 支持 TimeFormat 配置时间格式
✅ 4. 精确的调用栈跳过设置
✅ 5. 完全兼容 slog 的 Group 语义
✅ 6. 流式日志的SafeWriter

基于slog

go get github.com/zohu/zlog
type Options struct {
	Level       slog.Leveler // 日志等级
	Color       Color        // 配置颜色
	TimeFormat  string       // 时间格式
	AttrReplace func(groups []string, attr slog.Attr) slog.Attr // 属性替换
	Stack       Stack       // 显示堆栈
	StackSkip   int         // 堆栈跳过
	Writer      io.Writer   // 日志写入 默认os.Stdout
}



// 修改配置
WithOptions(options *Options)

// 使用
Debug("hello world", "name", "zhang")
Info("hello world", "name", "zhang")
Warn("hello world", "name", "zhang")
Error("hello world", "name", "zhang")

log1 := NewZLogger(&Options{
    Level:      slog.LevelDebug,
    Color:      ColorAlways,
    TimeFormat: time.RFC3339,
})

log1.Debugf("hello world name=%s", "zhang")
log1.Infof("hello world name=%s", "zhang")
log1.Warnf("hello world name=%s", "zhang")
log1.Errorf("hello world name=%s", "zhang")

log2 := NewZLogger(&Options{
    Level:      slog.LevelDebug,
    Color:      ColorAlways,
    TimeFormat: time.RFC3339,
    Stack:      StackOff,
    Writer:     SafeWriter(),
})
log2.Info("hello ... world") // >= 64k
time.Sleep(time.Second)

// 写入日志文件
writer, err := NewTimeRotatingWriter("log", WithConsole(true))
if err != nil {
    t.Fatal(err)
    return
}
log3 := NewZLogger(&Options{
    Writer: writer,
})

// 流式
log3 := NewZLogger(&Options{
    Writer: SafeWriter(writer),
})
// 流式日志、长日志、gorm、或者遇到日志 token too long 的场景
log2 := NewZLogger(&Options{
    Writer: SafeWriter(), // 默认是os.Stdout,替换为 SafeWriter(/*os.Stdout*/)
})

// 比如 gorm 框架的日志
type Logger struct {
    *zlog.Logger
    ignoreRecordNotFound bool
    logSlow              time.Duration
}

func NewLogger(o *Options) *Logger {
    options := &zlog.Options{
        StackSkip: -1,
		Writer: SafeWriter(), // 默认是os.Stdout,替换为 SafeWriter(/*os.Stdout*/)
	}
    if o.Debug != nil && *o.Debug {
        options.Level = slog.LevelDebug
    }
    l := &Logger{
        Logger:               zlog.NewZLogger(options),
        ignoreRecordNotFound: o.LogIgnoreNotFound == "yes",
        logSlow:              o.LogSlow,
    }
    return l
}

func (l Logger) LogMode(level logger.LogLevel) logger.Interface {
    return l
}
func (l Logger) Info(ctx context.Context, s string, i ...interface{}) {
    l.Infof(s, i...)
}
func (l Logger) Warn(ctx context.Context, s string, i ...interface{}) {
    l.Warnf(s, i...)
}
func (l Logger) Error(ctx context.Context, s string, i ...interface{}) {
    l.Errorf(s, i...)
}
func (l Logger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
    elapsed := time.Since(begin)
    switch {
    case err != nil && (!l.ignoreRecordNotFound || !errors.Is(err, gorm.ErrRecordNotFound)):
        sql, rows := fc()
        l.Errorf("rows=%d elapsed=%.3fs err=%s sql=%s", rows, elapsed.Seconds(), err.Error(), sql)
    case l.logSlow != 0 && elapsed > l.logSlow:
        sql, rows := fc()
        var e string
        if err != nil {
            e = fmt.Sprintf("err=%s ", err.Error())
        }
        l.Warnf("rows=%d elapsed=%.3fs %ssql=%s", rows, elapsed.Seconds(), e, sql)
    default:
        sql, rows := fc()
        var e string
        if err != nil {
            e = fmt.Sprintf("err=%s ", err.Error())
        }
        l.Debugf("rows=%d elapsed=%.3fs %ssql=%s", rows, elapsed.Seconds(), e, sql)
    }
}

2025-10-17 01:22:06 INF zlog/zlog_test.go:11 hello world name=zhang
2025-10-17 01:22:06 WRN zlog/zlog_test.go:12 hello world name=zhang
2025-10-17 01:22:06 ERR zlog/zlog_test.go:13 hello world name=zhang
2025-10-17T01:22:06+08:00 DBG zlog/zlog_test.go:21 hello world name=zhang
2025-10-17T01:22:06+08:00 INF zlog/zlog_test.go:22 hello world name=zhang
2025-10-17T01:22:06+08:00 WRN zlog/zlog_test.go:23 hello world name=zhang
2025-10-17T01:22:06+08:00 ERR zlog/zlog_test.go:24 hello world name=zhang
2025-10-17T01:22:06+08:00 INF hello world

Documentation

Index

Constants

View Source
const (
	ANSIReset  = "\033[0m"
	ANSIDebug  = "\033[90m"
	ANSIInfo   = "\033[32m"
	ANSIWarn   = "\033[33m"
	ANSIError  = "\033[31m"
	ANSITime   = "\033[37m"
	ANSISource = "\033[34;4m"
)
View Source
const (
	StackDefaultSkip = 6
)

Variables

This section is empty.

Functions

func Debug

func Debug(msg string, args ...any)

func Debugf

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

func Error

func Error(msg string, args ...any)

func Errorf

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

func Fatal

func Fatal(msg string, args ...any)

func Fatalf

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

func Info

func Info(msg string, args ...any)

func Infof

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

func IsConsole added in v1.0.3

func IsConsole(w io.Writer) bool

func NewTextHandler added in v1.0.3

func NewTextHandler(opts *Options) slog.Handler

func Panic

func Panic(msg string, args ...any)

func Panicf

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

func SafeWriter

func SafeWriter(w ...io.Writer) *io.PipeWriter

func Warn

func Warn(msg string, args ...any)

func Warnf

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

func WithOptions

func WithOptions(options *Options)

Types

type Buffer added in v1.0.3

type Buffer struct {
	*bytes.Buffer
}

func NewBuff added in v1.0.3

func NewBuff() *Buffer

func (*Buffer) Clone added in v1.0.3

func (b *Buffer) Clone() []byte

func (*Buffer) Free added in v1.0.3

func (b *Buffer) Free()

func (*Buffer) WriteStringIf added in v1.0.3

func (b *Buffer) WriteStringIf(ok bool, s string) (int, error)

type Color added in v1.0.3

type Color int
const (
	ColorAuto Color = iota
	ColorAlways
	ColorNever
)

type Logger

type Logger struct {
	*slog.Logger
}

func NewZLogger added in v1.0.3

func NewZLogger(options *Options) *Logger

func (*Logger) Debugf added in v1.0.3

func (l *Logger) Debugf(format string, args ...any)

func (*Logger) Errorf added in v1.0.3

func (l *Logger) Errorf(format string, args ...any)

func (*Logger) Fatal added in v1.0.3

func (l *Logger) Fatal(msg string, args ...any)

func (*Logger) Fatalf added in v1.0.3

func (l *Logger) Fatalf(format string, args ...any)

func (*Logger) Infof added in v1.0.3

func (l *Logger) Infof(format string, args ...any)

func (*Logger) Panic added in v1.0.3

func (l *Logger) Panic(msg string, args ...any)

func (*Logger) Panicf added in v1.0.3

func (l *Logger) Panicf(format string, args ...any)

func (*Logger) Print added in v1.0.3

func (l *Logger) Print(msg string, args ...any)

func (*Logger) Printf added in v1.0.3

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

func (*Logger) Warnf added in v1.0.3

func (l *Logger) Warnf(format string, args ...any)

type Option added in v1.0.3

type Option func(*TimeRotatingWriter)

Option 配置函数

func WithConsole added in v1.0.3

func WithConsole(b bool) Option

func WithLinkName added in v1.0.3

func WithLinkName(name string) Option

func WithLocation added in v1.0.3

func WithLocation(loc *time.Location) Option

func WithMaxAge added in v1.0.3

func WithMaxAge(d time.Duration) Option

type Options

type Options struct {
	Level       slog.Leveler
	Color       Color
	TimeFormat  string
	AttrReplace func(groups []string, attr slog.Attr) slog.Attr
	Stack       Stack
	StackSkip   int
	Writer      io.Writer
}

func (*Options) Validate added in v1.0.3

func (o *Options) Validate()

type Stack added in v1.0.3

type Stack int
const (
	StackAuto Stack = iota
	StackOn
	StackOff
)

type TextHandler added in v1.0.3

type TextHandler struct {
	sync.Mutex
	// contains filtered or unexported fields
}

func (*TextHandler) Enabled added in v1.0.3

func (h *TextHandler) Enabled(ctx context.Context, level slog.Level) bool

func (*TextHandler) Handle added in v1.0.3

func (h *TextHandler) Handle(_ context.Context, r slog.Record) error

func (*TextHandler) WithAttrs added in v1.0.3

func (h *TextHandler) WithAttrs(attrs []slog.Attr) slog.Handler

func (*TextHandler) WithGroup added in v1.0.3

func (h *TextHandler) WithGroup(name string) slog.Handler

type TimeRotatingWriter added in v1.0.3

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

TimeRotatingWriter 按时间轮转的日志写入器

func NewTimeRotatingWriter added in v1.0.3

func NewTimeRotatingWriter(dir string, opts ...Option) (*TimeRotatingWriter, error)

NewTimeRotatingWriter 创建轮转写入器

func (*TimeRotatingWriter) Close added in v1.0.3

func (w *TimeRotatingWriter) Close() error

Close 实现 io.Closer

func (*TimeRotatingWriter) Write added in v1.0.3

func (w *TimeRotatingWriter) Write(p []byte) (n int, err error)

Write 实现 io.Writer

type XLogger added in v1.0.3

type XLogger struct {
	*Logger
}

func NewXLogger added in v1.0.3

func NewXLogger(options *Options) *XLogger

func (*XLogger) Debug added in v1.0.3

func (x *XLogger) Debug(args ...any)

func (*XLogger) Error added in v1.0.3

func (x *XLogger) Error(args ...any)

func (*XLogger) Info added in v1.0.3

func (x *XLogger) Info(args ...any)

func (*XLogger) Warn added in v1.0.3

func (x *XLogger) Warn(args ...any)

Jump to

Keyboard shortcuts

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