zap

package
v0.0.0-...-11132ae Latest Latest
Warning

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

Go to latest
Published: Apr 16, 2023 License: MIT Imports: 8 Imported by: 2

README

zap

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

文档

特性

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

使用示例

开箱即用
package main

import (
	"os"
	"time"

	log "github.com/jianghushinian/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/jianghushinian/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/jianghushinian/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/jianghushinian/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(msg string, fields ...Field)

func Error

func Error(msg string, fields ...Field)

func Fatal

func Fatal(msg string, fields ...Field)

func Info

func Info(msg string, fields ...Field)

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(msg string, fields ...Field)

func ReplaceDefault

func ReplaceDefault(l *Logger)

func SetLevel

func SetLevel(level Level)

func Sync

func Sync() error

func Warn

func Warn(msg string, fields ...Field)

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(msg string, fields ...Field)

func (*Logger) Error

func (l *Logger) Error(msg string, fields ...Field)

func (*Logger) Fatal

func (l *Logger) Fatal(msg string, fields ...Field)

func (*Logger) Info

func (l *Logger) Info(msg string, fields ...Field)

func (*Logger) Panic

func (l *Logger) Panic(msg string, fields ...Field)

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(msg string, fields ...Field)

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
}

Directories

Path Synopsis
examples module

Jump to

Keyboard shortcuts

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