zap

package
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Aug 8, 2023 License: MIT Imports: 8 Imported by: 0

README

zap

基于 zap 开发的日志包,致力于提升 zap 使用体验。

特性

  • 类似 log 标准库的 API 设计
  • 动态修改日志级别
  • 可以设置不同日志级别输出到不同位置
  • 日志轮转,支持按时间/日志大小

使用示例

开箱即用
package main

import (
	"os"
	"time"

	log "github.com/todayVenturn/gokit/log/zap"
)

func main() {
	defer log.Sync()
	log.Info("failed to fetch URL", log.String("url", "https://jianghushinian.cn/"))
	log.Warn("Warn msg", log.Int("attempt", 3))
	log.Error("Error msg", log.Duration("backoff", time.Second))

	// 修改日志级别
	log.SetLevel(log.ErrorLevel)
	log.Info("Info msg")
	log.Warn("Warn msg")
	log.Error("Error msg")

	// 替换默认 Logger
	file, _ := os.OpenFile("custom.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
	logger := log.New(file, log.InfoLevel)
	log.ReplaceDefault(logger)
	log.Info("Info msg in replace default logger after")
}

控制台输出:

{"level":"info","ts":"2023-03-19T21:57:59+08:00","msg":"failed to fetch URL","url":"https://jianghushinian.cn/"}
{"level":"warn","ts":"2023-03-19T21:57:59+08:00","msg":"Warn msg","attempt":3}
{"level":"error","ts":"2023-03-19T21:57:59+08:00","msg":"Error msg","backoff":1}
{"level":"error","ts":"2023-03-19T21:57:59+08:00","msg":"Error msg"}

custom.log 输出:

{"level":"info","ts":"2023-03-19T21:57:59+08:00","msg":"Info msg in replace default logger after"}
选项

支持 zap 选项

package main

import (
	"fmt"
	"io"
	"os"
	"time"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"

	log "github.com/todayVenturn/gokit/log/zap"
)

func main() {
	file, _ := os.OpenFile("test.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
	opts := []log.Option{
		// 附加日志调用信息
		log.WithCaller(true),
		log.AddCallerSkip(1),
		// Warn 级别日志 Hook
		log.Hooks(func(entry zapcore.Entry) error {
			if entry.Level == log.WarnLevel {
				fmt.Printf("Warn Hook: msg=%s\n", entry.Message)
			}
			return nil
		}),
		// Fatal 级别日志 Hook
		zap.WithFatalHook(Hook{}),
	}
	logger := log.New(io.MultiWriter(os.Stdout, file), log.InfoLevel, opts...)
	defer logger.Sync()

	logger.Info("Info msg", log.String("val", "string"))
	logger.Warn("Warn msg", log.Int("val", 7))
	logger.Fatal("Fatal msg", log.Time("val", time.Now()))
}

type Hook struct{}

func (h Hook) OnWrite(ce *zapcore.CheckedEntry, field []zapcore.Field) {
	fmt.Printf("Fatal Hook: msg=%s, field=%+v\n", ce.Message, field)
}

控制台输出:

{"level":"info","ts":"2023-03-19T22:02:25+08:00","caller":"examples/main.go:55","msg":"Info msg","val":"string"}
{"level":"warn","ts":"2023-03-19T22:02:25+08:00","caller":"examples/main.go:56","msg":"Warn msg","val":7}
Warn Hook: msg=Warn msg
{"level":"fatal","ts":"2023-03-19T22:02:25+08:00","caller":"examples/main.go:57","msg":"Fatal msg","val":"2023-03-19T22:02:25+08:00"}
Fatal Hook: msg=Fatal msg, field=[{Key:val Type:16 Integer:1679234545108924000 String: Interface:Local}]

test.log 输出:

{"level":"info","ts":"2023-03-19T22:02:25+08:00","caller":"examples/main.go:55","msg":"Info msg","val":"string"}
{"level":"warn","ts":"2023-03-19T22:02:25+08:00","caller":"examples/main.go:56","msg":"Warn msg","val":7}
{"level":"fatal","ts":"2023-03-19T22:02:25+08:00","caller":"examples/main.go:57","msg":"Fatal msg","val":"2023-03-19T22:02:25+08:00"}
不同级别日志输出到不同位置

Info 级别日志输出到 os.StdoutWarn 级别日志输出到 test-warn.log,其他级别日志不会输出。

package main

import (
	"os"

	log "github.com/todayVenturn/gokit/log/zap"
)

func main() {
	file, _ := os.OpenFile("test-warn.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
	tees := []log.TeeOption{
		{
			Out: os.Stdout,
			LevelEnablerFunc: func(level log.Level) bool {
				return level == log.InfoLevel
			},
		},
		{
			Out: file,
			LevelEnablerFunc: func(level log.Level) bool {
				return level == log.WarnLevel
			},
		},
	}
	logger := log.NewTee(tees)
	defer logger.Sync()

	logger.Info("Info tee msg")
	logger.Warn("Warn tee msg")
	logger.Error("Error tee msg") // 不会输出
}

控制台输出:

{"level":"info","ts":"2023-03-19T22:06:25+08:00","msg":"Info tee msg"}

test-warn.log 输出:

{"level":"warn","ts":"2023-03-19T22:06:25+08:00","msg":"Warn tee msg"}
日志轮转

Warn 以下级别日志按大小轮转,Warn 及以上级别日志按时间轮转。

package main

import (
	log "github.com/todayVenturn/gokit/log/zap"
)

func main() {
	tees := []log.TeeOption{
		{
			Out: log.NewProductionRotateBySize("rotate-by-size.log"),
			LevelEnablerFunc: log.LevelEnablerFunc(func(level log.Level) bool {
				return level < log.WarnLevel
			}),
		},
		{
			Out: log.NewProductionRotateByTime("rotate-by-time.log"),
			LevelEnablerFunc: log.LevelEnablerFunc(func(level log.Level) bool {
				return level >= log.WarnLevel
			}),
		},
	}
	lts := log.NewTee(tees)
	defer lts.Sync()

	lts.Debug("Debug msg")
	lts.Info("Info msg")
	lts.Warn("Warn msg")
	lts.Error("Error msg")
}

rotate-by-size.log 输出:

{"level":"debug","ts":"2023-03-19T22:50:54+08:00","msg":"Debug msg"}
{"level":"info","ts":"2023-03-19T22:50:54+08:00","msg":"Info msg"}

rotate-by-time.log 输出:

{"level":"warn","ts":"2023-03-19T22:50:54+08:00","msg":"Warn msg"}
{"level":"error","ts":"2023-03-19T22:50:54+08:00","msg":"Error msg"}

更多使用详情请参考 examples

Documentation

Index

Constants

View Source
const (
	DebugLevel = zapcore.DebugLevel
	InfoLevel  = zapcore.InfoLevel
	WarnLevel  = zapcore.WarnLevel
	ErrorLevel = zapcore.ErrorLevel
	PanicLevel = zapcore.PanicLevel
	FatalLevel = zapcore.FatalLevel
)

Variables

View Source
var (
	Skip        = zap.Skip
	Binary      = zap.Binary
	Bool        = zap.Bool
	Boolp       = zap.Boolp
	ByteString  = zap.ByteString
	Complex128  = zap.Complex128
	Complex128p = zap.Complex128p
	Complex64   = zap.Complex64
	Complex64p  = zap.Complex64p
	Float64     = zap.Float64
	Float64p    = zap.Float64p
	Float32     = zap.Float32
	Float32p    = zap.Float32p
	Int         = zap.Int
	Intp        = zap.Intp
	Int64       = zap.Int64
	Int64p      = zap.Int64p
	Int32       = zap.Int32
	Int32p      = zap.Int32p
	Int16       = zap.Int16
	Int16p      = zap.Int16p
	Int8        = zap.Int8
	Int8p       = zap.Int8p
	String      = zap.String
	Stringp     = zap.Stringp
	Uint        = zap.Uint
	Uintp       = zap.Uintp
	Uint64      = zap.Uint64
	Uint64p     = zap.Uint64p
	Uint32      = zap.Uint32
	Uint32p     = zap.Uint32p
	Uint16      = zap.Uint16
	Uint16p     = zap.Uint16p
	Uint8       = zap.Uint8
	Uint8p      = zap.Uint8p
	Uintptr     = zap.Uintptr
	Uintptrp    = zap.Uintptrp
	Reflect     = zap.Reflect
	Namespace   = zap.Namespace
	Stringer    = zap.Stringer
	Time        = zap.Time
	Timep       = zap.Timep
	Stack       = zap.Stack
	StackSkip   = zap.StackSkip
	Duration    = zap.Duration
	Durationp   = zap.Durationp
	Object      = zap.Object
	Inline      = zap.Inline
	Any         = zap.Any
)
View Source
var (
	WrapCore      = zap.WrapCore
	Hooks         = zap.Hooks
	Fields        = zap.Fields
	ErrorOutput   = zap.ErrorOutput
	Development   = zap.Development
	AddCaller     = zap.AddCaller
	WithCaller    = zap.WithCaller
	AddCallerSkip = zap.AddCallerSkip
	AddStacktrace = zap.AddStacktrace
	IncreaseLevel = zap.IncreaseLevel
	WithFatalHook = zap.WithFatalHook
	WithClock     = zap.WithClock
)

Functions

func Debug

func Debug(args ...interface{})

func Debugf

func Debugf(template string, args ...interface{})

func Error

func Error(args ...interface{})

func Errorf

func Errorf(template string, args ...interface{})

func Fatal

func Fatal(args ...interface{})

func Fatalf

func Fatalf(template string, args ...interface{})

func Info

func Info(args ...interface{})

func Infof

func Infof(template string, args ...interface{})

func NewProductionRotateBySize

func NewProductionRotateBySize(filename string) io.Writer

NewProductionRotateBySize 创建按大小轮转的 io.Writer

func NewProductionRotateByTime

func NewProductionRotateByTime(filename string) io.Writer

NewProductionRotateByTime 创建按时间轮转的 io.Writer

func NewRotateBySize

func NewRotateBySize(cfg *RotateConfig) io.Writer

func NewRotateByTime

func NewRotateByTime(cfg *RotateConfig) io.Writer

func Panic

func Panic(args ...interface{})

func Panicf

func Panicf(template string, args ...interface{})

func ReplaceDefault

func ReplaceDefault(l *Logger)

func SetLevel

func SetLevel(level Level)

func Sync

func Sync() error

func Warn

func Warn(args ...interface{})

func Warnf

func Warnf(template string, args ...interface{})

Types

type Field

type Field = zap.Field

type Level

type Level = zapcore.Level

type LevelEnablerFunc

type LevelEnablerFunc func(Level) bool

type Logger

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

func Default

func Default() *Logger

func New

func New(out io.Writer, level Level, opts ...Option) *Logger

func NewTee

func NewTee(tees []TeeOption, opts ...Option) *Logger

NewTee 根据日志级别写入多个输出 https://pkg.go.dev/go.uber.org/zap#example-package-AdvancedConfiguration

func (*Logger) Debug

func (l *Logger) Debug(args ...interface{})

func (*Logger) Debugf

func (l *Logger) Debugf(template string, args ...interface{})

func (*Logger) Error

func (l *Logger) Error(args ...interface{})

func (*Logger) Errorf

func (l *Logger) Errorf(template string, args ...interface{})

func (*Logger) Fatal

func (l *Logger) Fatal(args ...interface{})

func (*Logger) Fatalf

func (l *Logger) Fatalf(template string, args ...interface{})

func (*Logger) Info

func (l *Logger) Info(args ...interface{})

func (*Logger) Infof

func (l *Logger) Infof(template string, args ...interface{})

func (*Logger) L

func (l *Logger) L() *zap.Logger

func (*Logger) Panic

func (l *Logger) Panic(args ...interface{})

func (*Logger) Panicf

func (l *Logger) Panicf(template string, args ...interface{})

func (*Logger) S

func (l *Logger) S() *zap.SugaredLogger

func (*Logger) SetLevel

func (l *Logger) SetLevel(level Level)

SetLevel 动态更改日志级别 对于使用 NewTee 创建的 Logger 无效,因为 NewTee 本意是根据不同日志级别 创建的多个 zap.Core,不应该通过 SetLevel 将多个 zap.Core 日志级别统一

func (*Logger) Sync

func (l *Logger) Sync() error

func (*Logger) Warn

func (l *Logger) Warn(args ...interface{})

func (*Logger) Warnf

func (l *Logger) Warnf(template string, args ...interface{})

type Option

type Option = zap.Option

type RotateConfig

type RotateConfig struct {
	// 共用配置
	Filename string // 完整文件名
	MaxAge   int    // 保留旧日志文件的最大天数

	// 按时间轮转配置
	RotationTime time.Duration // 日志文件轮转时间

	// 按大小轮转配置
	MaxSize    int  // 日志文件最大大小(MB)
	MaxBackups int  // 保留日志文件的最大数量
	Compress   bool // 是否对日志文件进行压缩归档
	LocalTime  bool // 是否使用本地时间,默认 UTC 时间
}

func NewProductionRotateConfig

func NewProductionRotateConfig(filename string) *RotateConfig

type TeeOption

type TeeOption struct {
	Out io.Writer
	LevelEnablerFunc
}

Jump to

Keyboard shortcuts

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