go第三方库文档 日志构建zap


// go第三方库文档 日志构建zap
// https://pkg.go.dev/go.uber.org/zap

// 安装
// go get-u go.uber.org/zap

Quick Start
// 在性能良好但不关键的环境中,使用SugaredLogger。它比其他结构化日志软件包快4-10倍,同时包含结构化和printf风格的api。
logger, _ := zap.NewProduction()
defer logger.Sync() // flushes buffer, if any
sugar := logger.Sugar()
sugar.Infow("failed to fetch URL",
  // Structured context as loosely typed key-value pairs.
  "url", url,
  "attempt", 3,
  "backoff", time.Second,
)
sugar.Infof("Failed to fetch URL: %s", url)
// 当性能和类型安全至关重要时,使用记录器。它甚至比SugaredLogger更快,分配更少,但它只支持结构化日志记录。
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("failed to fetch URL",
  // Structured context as strongly typed Field values.
  zap.String("url", url),
  zap.Int("attempt", 3),
  zap.Duration("backoff", time.Second),
)
// 有关更多详细信息,请参阅文档和常见问题解答。



// 包zap提供快速、结构化、分级的日志记录。
// 对于登录到热路径的应用程序,基于反射的序列化和字符串格式的成本非常高——它们占用大量CPU,并且会进行许多小的分配。换句话说,使用json.Marshal和fmt.Fprintf来记录大量的接口{},会使应用程序运行缓慢。
// Zap采取了不同的方法。它包括一个无反射、零分配的JSON编码器,基本记录器尽可能避免序列化开销和分配。通过在该基础上构建高级SugaredLogger,ZAP允许用户在需要计算每一个分配时选择它们,而当它们更喜欢更熟悉的、松散类型的API时。

Choosing a Logger
// 在性能良好但不关键的环境中,使用SugaredLogger。它比其他结构化日志记录包快4-10倍,并且支持结构化和printf样式的日志记录。与log15和go kit一样,SugaredLogger的结构化日志API是松散类型的,并且接受不同数量的键值对。(对于更高级的用例,它们也接受强类型字段——请参阅SugaredLogger。附带文档以了解详细信息。)
sugar := zap.NewExample().Sugar()
defer sugar.Sync()
sugar.Infow("failed to fetch URL",
  "url", "http://example.com",
  "attempt", 3,
  "backoff", time.Second,
)
sugar.Infof("failed to fetch URL: %s", "http://example.com")
// 默认情况下,记录器是无缓冲的。然而,由于zap的低级API允许缓冲,所以在进程退出之前调用Sync是一个好习惯。
// 在极少数情况下,每一微秒和每一次分配都很重要,请使用记录器。它甚至比SugaredLogger更快,分配更少,但它只支持强类型、结构化的日志记录。
logger := zap.NewExample()
defer logger.Sync()
logger.Info("failed to fetch URL",
  zap.String("url", "http://example.com"),
  zap.Int("attempt", 3),
  zap.Duration("backoff", time.Second),
)
// 在Logger和SugaredLogger之间进行选择不需要是整个应用程序的决定:在两者之间进行转换既简单又便宜。
logger := zap.NewExample()
defer logger.Sync()
sugar := logger.Sugar()
plain := sugar.Desugar()

Configuring Zap
// 构建记录器的最简单方法是使用zap的自以为是的预设:NewExample、NewProduction和NewDevelopment。这些预设使用单个函数调用构建记录器:
logger, err := zap.NewProduction()
if err != nil {
  log.Fatalf("can't initialize zap logger: %v", err)
}
defer logger.Sync()
// 预设适用于小项目,但较大的项目和组织自然需要更多的定制。对于大多数用户来说,zap的Config struct在灵活性和便利性之间取得了恰当的平衡。有关示例代码,请参见包级基本配置示例。
// 可以进行更不寻常的配置(在文件之间分割输出、将日志发送到消息队列等),但需要直接使用go.uber.org/zap/zapcore。有关示例代码,请参阅包级别的AdvancedConfiguration示例。

Extending Zap
// zap包本身是go.uber.org/zap/zapcore中接口的一个相对较薄的包装。扩展zap以支持新的编码(如BSON)、新的日志接收器(如Kafka)或更奇特的东西(可能是异常聚合服务,如Sentry或Rollbar),通常需要实现zapcore.Encoder、zapcore.WriteSync或zapcore.Core接口。有关详细信息,请参阅zapcore文档。
// 类似地,包作者可以使用zapcore包中的高性能编码器和核心实现来构建自己的记录器。

Frequently Asked Questions
// 一个涵盖从安装错误到设计决策的常见问题解答可在https://github.com/uber-go/zap/blob/master/FAQ.md.

// 示例(AdvancedConfiguration)
package main

import (
	"io/ioutil"
	"os"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)
func main() {
    //捆绑配置结构仅支持最常见的配置
    //选项。更复杂的需求,如在多个文件之间拆分日志
    //或写入非文件输出,需要使用zapcore包。
    //
    //在本例中,假设我们都向卡夫卡发送日志并编写
    //把它们放在控制台上。我们想对控制台输出和卡夫卡进行编码
    //主题不同,我们也希望对
    //高优先级日志。

    //首先,定义我们的级别处理逻辑。
	highPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
		return lvl >= zapcore.ErrorLevel
	})
	lowPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
		return lvl < zapcore.ErrorLevel
	})

    //假设我们有两个卡夫卡主题的客户机。客户端实现
    //zapcore.WriteSyncer和可安全地同时使用。(如果他们
    //实现io.Writer,我们可以使用zapcore.AddSync添加无操作同步
    //方法。如果并发使用不安全,我们可以添加一个
    //带有zapcore.Lock的互斥锁。)
	topicDebugging := zapcore.AddSync(ioutil.Discard)
	topicErrors := zapcore.AddSync(ioutil.Discard)

    //高优先级输出也应转到标准错误,低优先级输出也应转到标准错误
    //输出也应转到标准输出。
	consoleDebugging := zapcore.Lock(os.Stdout)
	consoleErrors := zapcore.Lock(os.Stderr)

    //针对机器消耗和控制台输出优化卡夫卡输出
    //供人工操作人员使用。
	kafkaEncoder := zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
	consoleEncoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())

    //将输出、编码器和电平处理功能连接到
    //zapcore.型芯,然后将四个型芯三通在一起。
	core := zapcore.NewTee(
		zapcore.NewCore(kafkaEncoder, topicErrors, highPriority),
		zapcore.NewCore(consoleEncoder, consoleErrors, highPriority),
		zapcore.NewCore(kafkaEncoder, topicDebugging, lowPriority),
		zapcore.NewCore(consoleEncoder, consoleDebugging, lowPriority),
	)

    //从zapcore.Core,很容易构造一个记录器。
	logger := zap.New(core)
	defer logger.Sync()
	logger.Info("constructed a logger")
}


// 输出:

// 示例(BasicConfiguration)
package main

import (
	"encoding/json"

	"go.uber.org/zap"
)

func main() {
    //对于某些用户,新产品、新开发、,
    //而NewExample构造函数将不合适。对大多数人来说
    //对于用户来说,捆绑的配置结构提供了适当的灵活性平衡
    //和方便。(有关更复杂的需求,请参阅AdvancedConfiguration
    //例如。)
    //
    //请参阅Config和zapcore.EncoderConfig的文档以了解所有
    //可用选项。
	rawJSON := []byte(`{
	  "level": "debug",
	  "encoding": "json",
	  "outputPaths": ["stdout", "/tmp/logs"],
	  "errorOutputPaths": ["stderr"],
	  "initialFields": {"foo": "bar"},
	  "encoderConfig": {
	    "messageKey": "message",
	    "levelKey": "level",
	    "levelEncoder": "lowercase"
	  }
	}`)

	var cfg zap.Config
	if err := json.Unmarshal(rawJSON, &cfg); err != nil {
		panic(err)
	}
	logger, err := cfg.Build()
	if err != nil {
		panic(err)
	}
	defer logger.Sync()

	logger.Info("logger construction succeeded")
}

// 输出:
{"level":"info","message":"logger construction succeeded","foo":"bar"}


// 示例(Presets)
package main

import (
	"time"

	"go.uber.org/zap"
)

func main() {
	// Using zap's preset constructors is the simplest way to get a feel for the
	// package, but they don't allow much customization.
	logger := zap.NewExample() // or NewProduction, or NewDevelopment
	defer logger.Sync()

	const url = "http://example.com"

	// In most circumstances, use the SugaredLogger. It's 4-10x faster than most
	// other structured logging packages and has a familiar, loosely-typed API.
	sugar := logger.Sugar()
	sugar.Infow("Failed to fetch URL.",
		// Structured context as loosely typed key-value pairs.
		"url", url,
		"attempt", 3,
		"backoff", time.Second,
	)
	sugar.Infof("Failed to fetch URL: %s", url)

	// In the unusual situations where every microsecond matters, use the
	// Logger. It's even faster than the SugaredLogger, but only supports
	// structured logging.
	logger.Info("Failed to fetch URL.",
		// Structured context as strongly typed fields.
		zap.String("url", url),
		zap.Int("attempt", 3),
		zap.Duration("backoff", time.Second),
	)
}

// 输出:
{"level":"info","msg":"Failed to fetch URL.","url":"http://example.com","attempt":3,"backoff":"1s"}
{"level":"info","msg":"Failed to fetch URL: http://example.com"}
{"level":"info","msg":"Failed to fetch URL.","url":"http://example.com","attempt":3,"backoff":"1s"}


func CombineWriteSyncers(writers ...zapcore.WriteSyncer) zapcore.WriteSyncer
func LevelFlag(name string, defaultLevel zapcore.Level, usage string) *zapcore.Level
func NewDevelopmentEncoderConfig() zapcore.EncoderConfig
func NewProductionEncoderConfig() zapcore.EncoderConfig
func NewStdLog(l *Logger) *log.Logger
func NewStdLogAt(l *Logger, level zapcore.Level) (*log.Logger, error)
func Open(paths ...string) (zapcore.WriteSyncer, func(), error)
func RedirectStdLog(l *Logger) func()
func RedirectStdLogAt(l *Logger, level zapcore.Level) (func(), error)
func RegisterEncoder(name string, constructor func(zapcore.EncoderConfig) (zapcore.Encoder, error)) error
func RegisterSink(scheme string, factory func(*url.URL) (Sink, error)) error
func ReplaceGlobals(logger *Logger) func()
type AtomicLevel
func NewAtomicLevel() AtomicLevel
func NewAtomicLevelAt(l zapcore.Level) AtomicLevel
func (lvl AtomicLevel) Enabled(l zapcore.Level) bool
func (lvl AtomicLevel) Level() zapcore.Level
func (lvl AtomicLevel) MarshalText() (text []byte, err error)
func (lvl AtomicLevel) ServeHTTP(w http.ResponseWriter, r *http.Request)
func (lvl AtomicLevel) SetLevel(l zapcore.Level)
func (lvl AtomicLevel) String() string
func (lvl *AtomicLevel) UnmarshalText(text []byte) error
type Config
func NewDevelopmentConfig() Config
func NewProductionConfig() Config
func (cfg Config) Build(opts ...Option) (*Logger, error)
type Field
func Any(key string, value interface{}) Field
func Array(key string, val zapcore.ArrayMarshaler) Field
func Binary(key string, val []byte) Field
func Bool(key string, val bool) Field
func Boolp(key string, val *bool) Field
func Bools(key string, bs []bool) Field
func ByteString(key string, val []byte) Field
func ByteStrings(key string, bss [][]byte) Field
func Complex128(key string, val complex128) Field
func Complex128p(key string, val *complex128) Field
func Complex128s(key string, nums []complex128) Field
func Complex64(key string, val complex64) Field
func Complex64p(key string, val *complex64) Field
func Complex64s(key string, nums []complex64) Field
func Duration(key string, val time.Duration) Field
func Durationp(key string, val *time.Duration) Field
func Durations(key string, ds []time.Duration) Field
func Error(err error) Field
func Errors(key string, errs []error) Field
func Float32(key string, val float32) Field
func Float32p(key string, val *float32) Field
func Float32s(key string, nums []float32) Field
func Float64(key string, val float64) Field
func Float64p(key string, val *float64) Field
func Float64s(key string, nums []float64) Field
func Inline(val zapcore.ObjectMarshaler) Field
func Int(key string, val int) Field
func Int16(key string, val int16) Field
func Int16p(key string, val *int16) Field
func Int16s(key string, nums []int16) Field
func Int32(key string, val int32) Field
func Int32p(key string, val *int32) Field
func Int32s(key string, nums []int32) Field
func Int64(key string, val int64) Field
func Int64p(key string, val *int64) Field
func Int64s(key string, nums []int64) Field
func Int8(key string, val int8) Field
func Int8p(key string, val *int8) Field
func Int8s(key string, nums []int8) Field
func Intp(key string, val *int) Field
func Ints(key string, nums []int) Field
func NamedError(key string, err error) Field
func Namespace(key string) Field
func Object(key string, val zapcore.ObjectMarshaler) Field
func Reflect(key string, val interface{}) Field
func Skip() Field
func Stack(key string) Field
func StackSkip(key string, skip int) Field
func String(key string, val string) Field
func Stringer(key string, val fmt.Stringer) Field
func Stringp(key string, val *string) Field
func Strings(key string, ss []string) Field
func Time(key string, val time.Time) Field
func Timep(key string, val *time.Time) Field
func Times(key string, ts []time.Time) Field
func Uint(key string, val uint) Field
func Uint16(key string, val uint16) Field
func Uint16p(key string, val *uint16) Field
func Uint16s(key string, nums []uint16) Field
func Uint32(key string, val uint32) Field
func Uint32p(key string, val *uint32) Field
func Uint32s(key string, nums []uint32) Field
func Uint64(key string, val uint64) Field
func Uint64p(key string, val *uint64) Field
func Uint64s(key string, nums []uint64) Field
func Uint8(key string, val uint8) Field
func Uint8p(key string, val *uint8) Field
func Uint8s(key string, nums []uint8) Field
func Uintp(key string, val *uint) Field
func Uintptr(key string, val uintptr) Field
func Uintptrp(key string, val *uintptr) Field
func Uintptrs(key string, us []uintptr) Field
func Uints(key string, nums []uint) Field
type LevelEnablerFunc
func (f LevelEnablerFunc) Enabled(lvl zapcore.Level) bool
type Logger
func L() *Logger
func New(core zapcore.Core, options ...Option) *Logger
func NewDevelopment(options ...Option) (*Logger, error)
func NewExample(options ...Option) *Logger
func NewNop() *Logger
func NewProduction(options ...Option) (*Logger, error)
func (log *Logger) Check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry
func (log *Logger) Core() zapcore.Core
func (log *Logger) DPanic(msg string, fields ...Field)
func (log *Logger) Debug(msg string, fields ...Field)
func (log *Logger) Error(msg string, fields ...Field)
func (log *Logger) Fatal(msg string, fields ...Field)
func (log *Logger) Info(msg string, fields ...Field)
func (log *Logger) Named(s string) *Logger
func (log *Logger) Panic(msg string, fields ...Field)
func (log *Logger) Sugar() *SugaredLogger
func (log *Logger) Sync() error
func (log *Logger) Warn(msg string, fields ...Field)
func (log *Logger) With(fields ...Field) *Logger
func (log *Logger) WithOptions(opts ...Option) *Logger
type Option
func AddCaller() Option
func AddCallerSkip(skip int) Option
func AddStacktrace(lvl zapcore.LevelEnabler) Option
func Development() Option
func ErrorOutput(w zapcore.WriteSyncer) Option
func Fields(fs ...Field) Option
func Hooks(hooks ...func(zapcore.Entry) error) Option
func IncreaseLevel(lvl zapcore.LevelEnabler) Option
func OnFatal(action zapcore.CheckWriteAction) Option
func WithCaller(enabled bool) Option
func WithClock(clock zapcore.Clock) Option
func WrapCore(f func(zapcore.Core) zapcore.Core) Option
type SamplingConfig
type Sink
type SugaredLogger
func S() *SugaredLogger
func (s *SugaredLogger) DPanic(args ...interface{})
func (s *SugaredLogger) DPanicf(template string, args ...interface{})
func (s *SugaredLogger) DPanicw(msg string, keysAndValues ...interface{})
func (s *SugaredLogger) Debug(args ...interface{})
func (s *SugaredLogger) Debugf(template string, args ...interface{})
func (s *SugaredLogger) Debugw(msg string, keysAndValues ...interface{})
func (s *SugaredLogger) Desugar() *Logger
func (s *SugaredLogger) Error(args ...interface{})
func (s *SugaredLogger) Errorf(template string, args ...interface{})
func (s *SugaredLogger) Errorw(msg string, keysAndValues ...interface{})
func (s *SugaredLogger) Fatal(args ...interface{})
func (s *SugaredLogger) Fatalf(template string, args ...interface{})
func (s *SugaredLogger) Fatalw(msg string, keysAndValues ...interface{})
func (s *SugaredLogger) Info(args ...interface{})
func (s *SugaredLogger) Infof(template string, args ...interface{})
func (s *SugaredLogger) Infow(msg string, keysAndValues ...interface{})
func (s *SugaredLogger) Named(name string) *SugaredLogger
func (s *SugaredLogger) Panic(args ...interface{})
func (s *SugaredLogger) Panicf(template string, args ...interface{})
func (s *SugaredLogger) Panicw(msg string, keysAndValues ...interface{})
func (s *SugaredLogger) Sync() error
func (s *SugaredLogger) Warn(args ...interface{})
func (s *SugaredLogger) Warnf(template string, args ...interface{})
func (s *SugaredLogger) Warnw(msg string, keysAndValues ...interface{})
func (s *SugaredLogger) With(args ...interface{}) *SugaredLogger

Examples
Package (AdvancedConfiguration)
Package (BasicConfiguration)
Package (Presets)
AtomicLevel
AtomicLevel (Config)
Logger.Check
Logger.Named
Namespace
NewStdLog
Object
RedirectStdLog
ReplaceGlobals
WrapCore (Replace)
WrapCore (Wrap)

Constants
const (
    //DebugLevel日志通常非常庞大,通常在中被禁用
    //生产。
    DebugLevel = zapcore.DebugLevel
    //InfoLevel是默认的日志记录优先级。
    InfoLevel = zapcore.InfoLevel
    //警告级别日志比信息更重要,但不需要单独的日志
    //人类评论。
    WarnLevel = zapcore.WarnLevel
    //ErrorLevel日志具有高优先级。如果应用程序运行正常,
    //它不应该生成任何错误级别日志。
    ErrorLevel = zapcore.ErrorLevel
    //DPL级别日志是特别重要的错误。发展中
    //记录器在写入消息后惊慌失措。
    DPanicLevel = zapcore.DPanicLevel
    //PanicLevel记录一条消息,然后恐慌。
    PanicLevel = zapcore.PanicLevel
    //FatalLevel记录一条消息,然后调用os.Exit(1)。
	FatalLevel = zapcore.FatalLevel
)

func CombineWriteSyncers 
func CombineWriteSyncers(writers ...zapcore.WriteSyncer) zapcore.WriteSyncer
// CombineWriteSyncers是一个实用程序,它将多个WriteSyncers组合成一个锁定的WriteSyncer。如果未提供任何输入,则返回一个no op WriteSyncer。

// 提供它纯粹是为了方便;结果与单独使用zapcore.NewMultiWriteSyncer和zapcore.Lock没有什么不同。

func LevelFlag 
func LevelFlag(name string, defaultLevel zapcore.Level, usage string) *zapcore.Level
// LevelFlag使用标准库的flag.Var声明具有指定名称、默认值和使用指南的全局标志。返回的值是指向标志值的指针。

// 如果不想使用标志包的全局状态,可以使用任何非nil*级别作为带有自己的*flag.FlagSet的flag.Value。

func NewDevelopmentEncoderConfig 
func NewDevelopmentEncoderConfig() zapcore.EncoderConfig
// NewDevelopmentEncoderConfig为开发环境返回一个自以为是的EncoderConfig。

func NewProductionEncoderConfig 
func NewProductionEncoderConfig() zapcore.EncoderConfig
// NewProductionEncoderConfig为生产环境返回一个自以为是的编码器配置。

func NewStdLog 
func NewStdLog(l *Logger) *log.Logger
// NewStdLog返回一个*log.Logger,它在信息级别写入提供的zap记录器。要重定向标准库的包全局日志函数,请改用RedirectStdLog。

// 实例
package main

import (
	"go.uber.org/zap"
)

func main() {
	logger := zap.NewExample()
	defer logger.Sync()

	std := zap.NewStdLog(logger)
	std.Print("standard logger wrapper")
}

// 输出:
// {"level":"info","msg":"standard logger wrapper"}

func NewStdLogAt 
func NewStdLogAt(l *Logger, level zapcore.Level) (*log.Logger, error)
// NewStdLogAt返回*log.Logger,它以所需级别写入提供的zap记录器。

func Open 
func Open(paths ...string) (zapcore.WriteSyncer, func(), error)
// Open是一个高级包装器,它接受可变数量的URL,打开或创建每个指定的资源,并将它们组合到一个锁定的WriteSyncer中。它还返回遇到的任何错误以及关闭任何打开文件的函数。
// 不传递URL将返回无操作WriteSyncer。Zap处理没有方案的URL和带有“文件”方案的URL。第三方代码可以使用RegisterSink为其他方案注册工厂。
// 具有“文件”方案的URL必须使用本地文件系统上的绝对路径。不允许使用用户、密码、端口、片段或查询参数,主机名必须为空或“localhost”。
// 由于向本地文件系统写入日志是很常见的,因此没有方案的URL(例如“/var/log/foo.log”)被视为本地文件路径。如果没有方案,特殊路径“stdout”和“stderr”将被解释为os.stdout和os.stderr。在没有方案的情况下指定时,相对文件路径也可以工作。

func RedirectStdLog 
func RedirectStdLog(l *Logger) func()
// RedirectStdLog将标准库的包全局记录器的输出重定向到提供的InfoLevel记录器。由于zap已经处理调用方注释、时间戳等,因此它会自动禁用标准库的注释和前缀。
// 它返回一个函数来恢复原始前缀和标志,并将标准库的输出重置为os.Stderr。

// 实例
package main

import (
	"log"

	"go.uber.org/zap"
)

func main() {
	logger := zap.NewExample()
	defer logger.Sync()

	undo := zap.RedirectStdLog(logger)
	defer undo()

	log.Print("redirected standard library")
}


// 输出:
// {"level":"info","msg":"redirected standard library"}

func RedirectStdLogAt 
func RedirectStdLogAt(l *Logger, level zapcore.Level) (func(), error)
// RedirectStdLogAt将标准库的包全局记录器的输出重定向到指定级别的提供记录器。由于zap已经处理调用方注释、时间戳等,因此它会自动禁用标准库的注释和前缀。
// 它返回一个函数来恢复原始前缀和标志,并将标准库的输出重置为os.Stderr。

func RegisterEncoder 
func RegisterEncoder(name string, constructor func(zapcore.EncoderConfig) (zapcore.Encoder, error)) error
// RegisterEncoder注册编码器构造函数,然后Config结构可以引用该构造函数。默认情况下,注册“json”和“console”编码器。
// 试图注册一个已使用其名称的编码器将返回一个错误。

func RegisterSink 
func RegisterSink(scheme string, factory func(*url.URL) (Sink, error)) error
// RegisterSink使用特定方案为所有接收器注册用户提供的工厂。
// 所有方案必须为ASCII码,根据RFC 3986第3.1节的规定有效(https://tools.ietf.org/html/rfc3986#section-3.1),且不得已注册工厂。Zap自动为“文件”方案注册工厂。

func ReplaceGlobals 
func ReplaceGlobals(logger *Logger) func()
// ReplaceGlobals替换全局记录器和SugaredLogger,并返回用于恢复原始值的函数。同时使用是安全的。

// 实例
package main

import (
	"go.uber.org/zap"
)

func main() {
	logger := zap.NewExample()
	defer logger.Sync()

	undo := zap.ReplaceGlobals(logger)
	defer undo()

	zap.L().Info("replaced zap's global loggers")
}

// 输出:
// {"level":"info","msg":"replaced zap's global loggers"}


type AtomicLevel 
type AtomicLevel struct {
    //包含已过滤或未报告的字段
}
// 原子级别是一个原子上可变的动态日志级别。它允许您在运行时安全地更改日志记录器树(根日志记录器和通过添加上下文创建的任何子日志)的日志级别。
// AtomicLevel本身是一个http.Handler,为JSON端点提供服务以改变其级别。
// 必须使用NewAtomicLevel构造函数创建AtomicLevel,以分配其内部原子指针。

// 实例
package main
import (
	"os"

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

func main() {
	atom := zap.NewAtomicLevel()

	// To keep the example deterministic, disable timestamps in the output.
	encoderCfg := zap.NewProductionEncoderConfig()
	encoderCfg.TimeKey = ""

	logger := zap.New(zapcore.NewCore(
		zapcore.NewJSONEncoder(encoderCfg),
		zapcore.Lock(os.Stdout),
		atom,
	))
	defer logger.Sync()

	logger.Info("info logging enabled")

	atom.SetLevel(zap.ErrorLevel)
	logger.Info("info logging disabled")
}

// 输出:
// {"level":"info","msg":"info logging enabled"}

// 示例(Config)
package main

import (
	"encoding/json"

	"go.uber.org/zap"
)

func main() {
	// The zap.Config struct includes an AtomicLevel. To use it, keep a
	// reference to the Config.
	rawJSON := []byte(`{
		"level": "info",
		"outputPaths": ["stdout"],
		"errorOutputPaths": ["stderr"],
		"encoding": "json",
		"encoderConfig": {
			"messageKey": "message",
			"levelKey": "level",
			"levelEncoder": "lowercase"
		}
	}`)
	var cfg zap.Config
	if err := json.Unmarshal(rawJSON, &cfg); err != nil {
		panic(err)
	}
	logger, err := cfg.Build()
	if err != nil {
		panic(err)
	}
	defer logger.Sync()

	logger.Info("info logging enabled")

	cfg.Level.SetLevel(zap.ErrorLevel)
	logger.Info("info logging disabled")
}

// 输出:
// {"level":"info","message":"info logging enabled"}

func NewAtomicLevel 
func NewAtomicLevel() AtomicLevel
// NewAtomicLevel创建启用了InfoLevel和更高级别日志记录的AtomicLevel。

func NewAtomicLevelAt 
func NewAtomicLevelAt(l zapcore.Level) AtomicLevel
// NewAtomicLevelAt是一个方便的函数,它创建一个AtomicLevel,然后使用给定的级别调用SetLevel。

func (AtomicLevel) Enabled 
func (lvl AtomicLevel) Enabled(l zapcore.Level) bool
// Enabled实现zapcore.LevelEnabler接口,该接口允许使用AtomicLevel代替传统的静态级别。

func (AtomicLevel) Level 
func (lvl AtomicLevel) Level() zapcore.Level
// 级别返回启用的最小日志级别。

func (AtomicLevel) MarshalText 
func (lvl AtomicLevel) MarshalText() (text []byte, err error)
// MarshalText将原子级别封送到字节片。它使用与静态zapcore.Levels相同的文本表示形式(“调试”、“信息”、“警告”、“错误”、“dpanic”、“恐慌”和“致命”)。

func (AtomicLevel) ServeHTTP 
func (lvl AtomicLevel) ServeHTTP(w http.ResponseWriter, r *http.Request)
// ServeHTTP是一个简单的JSON端点,可以报告或更改当前日志记录级别。

GET
// GET请求返回当前日志记录级别的JSON描述,如:
{"level":"info"}

PUT
// PUT请求更改日志记录级别。在程序运行时更改日志记录级别是完全安全的。支持两种内容类型:
Content-Type: application/x-www-form-urlencoded

// 使用此内容类型,可以通过请求主体或查询参数提供级别。日志级别采用URL编码,如下所示:
level=debug

// 如果两者都指定,则请求正文优先于查询参数。
// 此内容类型是curl-PUT请求的默认内容类型。下面是两个示例curl请求,它们都将日志记录级别设置为debug。
curl -X PUT localhost:8080/log/level?level=debug
curl -X PUT localhost:8080/log/level -d level=debug

// 对于任何其他内容类型,负载应为JSON编码,如下所示:
{"level":"info"}

// 示例curl请求可能如下所示:
curl -X PUT localhost:8080/log/level -H "Content-Type: application/json" -d '{"level":"debug"}'

func (AtomicLevel) SetLevel 
func (lvl AtomicLevel) SetLevel(l zapcore.Level)
// SetLevel更改日志记录级别。

func (AtomicLevel) String 
func (lvl AtomicLevel) String() string
// String返回基础级别的字符串表示形式。

func (*AtomicLevel) UnmarshalText 
func (lvl *AtomicLevel) UnmarshalText(text []byte) error
// 解组文本将文本解组到原子级别。它使用与静态zapcore.Levels相同的文本表示形式(“调试”、“信息”、“警告”、“错误”、“dpanic”、“恐慌”和“致命”)。

type Config 
type Config struct {
    //级别是启用的最低日志记录级别。请注意,这是一个动态过程
    //级别,因此调用Config.level.SetLevel将自动更改日志
    //从此配置中降级的所有记录器的级别。
    Level AtomicLevel `json:"level" yaml:"level"`
    //开发将记录器置于开发模式,从而更改
    //DPA的行为水平较高,并且更自由地进行跟踪。
    Development bool `json:"development" yaml:"development"`
    //DisableCaller停止使用调用函数的文件注释日志
    //姓名和行号。默认情况下,所有日志都带有注释。
    DisableCaller bool `json:"disableCaller" yaml:"disableCaller"`
    //DisableStacktrace完全禁用自动stacktrace捕获。通过
    //默认情况下,会捕获WarnLevel及以上日志的堆栈跟踪
    //在生产中达到或超过开发和测试水平。
    DisableStacktrace bool `json:"disableStacktrace" yaml:"disableStacktrace"`
    //采样设置采样策略。零采样配置将禁用采样。
    Sampling *SamplingConfig `json:"sampling" yaml:"sampling"`
    //编码设置记录器的编码。有效值为“json”和
    //“控制台”,以及通过
    //注册编码器。
    Encoding string `json:"encoding" yaml:"encoding"`
    //EncoderConfig为所选编码器设置选项。看见
    //zapcore.EncoderConfig获取详细信息。
    EncoderConfig zapcore.EncoderConfig `json:"encoderConfig" yaml:"encoderConfig"`
    //OutputPaths是要将日志输出写入的URL或文件路径的列表。
    //有关详细信息,请参阅Open。
    OutputPaths []string `json:"outputPaths" yaml:"outputPaths"`
    //ErrorOutputPath是用于写入内部记录器错误的URL列表。
    //默认值为标准错误。
    //
    //请注意,此设置仅影响内部错误;对于示例代码
    //将错误级别日志发送到与信息和调试级别不同的位置
    //日志,请参阅包级AdvancedConfiguration示例。
    ErrorOutputPaths []string `json:"errorOutputPaths" yaml:"errorOutputPaths"`
    //InitialFields是要添加到根记录器的字段集合。
    InitialFields map[string]interface{} `json:"initialFields" yaml:"initialFields"`
}
// Config提供了一种声明式方法来构造记录器。它不做任何不能用New、Options和各种zapcore.WriteSyncer和zapcore.Core包装器完成的事情,但它是切换常用选项的一种更简单的方法。
// 请注意,Config故意只支持最常见的选项。更不寻常的日志设置(记录到网络连接或消息队列、在多个文件之间分割输出等)是可能的,但需要直接使用zapcore包。有关示例代码,请参阅包级基本配置和高级配置示例。
// 有关显示运行时日志级别更改的示例,请参阅AtomicLevel的文档。

func NewDevelopmentConfig 
func NewDevelopmentConfig() Config
// NewDevelopmentConfig是一种合理的开发日志配置。在调试级别及更高级别启用日志记录。
// 它启用开发模式(这会使DPL日志死机)、使用控制台编码器、写入标准错误并禁用采样。Stacktraces自动包含在WarnLevel及更高级别的日志中。

func NewProductionConfig 
func NewProductionConfig() Config
// NewProductionConfig是一种合理的生产日志配置。日志记录在InfoLevel及更高级别启用。
// 它使用JSON编码器,写入标准错误,并启用采样。Stacktraces自动包含在ErrorLevel及以上的日志中。

func (Config) Build 
func (cfg Config) Build(opts ...Option) (*Logger, error)
// Build根据配置和选项构造记录器。

type Field 
type Field = zapcore.Field
// 字段是字段的别名。使用此类型的别名可显著提高此包的API文档的可导航性。

func Any 
func Any(key string, value interface{}) Field
// Any接受一个键和一个任意值,并选择将它们表示为字段的最佳方式,只有在必要时才返回到基于反射的方法。
// 由于byte/uint8和rune/int32是别名,任何人都无法区分它们。为了尽量减少意外,[]字节值被视为二进制blob,字节值被视为uint8,符文总是被视为整数。

func Array 
func Array(key string, val zapcore.ArrayMarshaler) Field
// 数组用给定的键和ArrayMarshaler构造一个字段。它提供了一种灵活但仍然是类型安全且高效的方法,可以将类似数组的类型添加到日志上下文中。该结构的MarshallLogArray方法被延迟调用。

func Binary 
func Binary(key string, val []byte) Field
// Binary构造一个包含不透明二进制blob的字段。
// 二进制数据以适当的编码格式序列化。例如,zap的JSON编码器base64对二进制blob进行编码。要记录UTF-8编码的文本,请使用ByteString。

func Bool 
func Bool(key string, val bool) Field
// Bool构造一个包含Bool的字段。

func Boolp 
func Boolp(key string, val *bool) Field
// Boolp构造一个包含*bool的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Bools 
func Bools(key string, bs []bool) Field
// Bools构造了一个包含Bools片段的字段。

func ByteString 
func ByteString(key string, val []byte) Field
// ByteString构造一个字段,该字段以[]字节的形式携带UTF-8编码文本。要记录不透明的二进制blob(不一定是有效的UTF-8),请使用binary。

func ByteStrings 
func ByteStrings(key string, bss [][]byte) Field
// ByteStrings构造了一个字段,该字段包含一个[]字节的片段,每个字节都必须是UTF-8编码的文本。

func Complex128 
func Complex128(key string, val complex128) Field
// Complex128构造一个携带复数的字段。与大多数数字字段不同,这需要分配(将complex128转换为接口{})。

func Complex128p 
func Complex128p(key string, val *complex128) Field
// Complex128p构造一个字段,该字段包含*complex128。适当时,返回的字段将安全且明确地表示'nil'。

func Complex128s 
func Complex128s(key string, nums []complex128) Field
// Complex128s构造一个字段,该字段包含一段复数。

func Complex64 
func Complex64(key string, val complex64) Field
// Complex64构造一个携带复数的字段。与大多数数字字段不同,这需要分配(将complex64转换为接口{})。

func Complex64p 
func Complex64p(key string, val *complex64) Field
// Complex64p构造一个包含*complex64的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Complex64s 
func Complex64s(key string, nums []complex64) Field
// Complex64s构造一个字段,该字段包含一段复数。

func Duration 
func Duration(key string, val time.Duration) Field
// Duration使用给定的键和值构造一个字段。编码器控制如何序列化持续时间。

func Durationp 
func Durationp(key string, val *time.Duration) Field
// Durationp构造一个字段,其中包含*time.Duration。适当时,返回的字段将安全且明确地表示'nil'。

func Durations 
func Durations(key string, ds []time.Duration) Field
// Durations构造一个字段,该字段包含一段时间。Durations。

func Error 
func Error(err error) Field
// Error是通用成语NamedError(“Error”,err)的缩写。

func Errors 
func Errors(key string, errs []error) Field
// Errors构造一个字段,该字段包含一个错误片段。

func Float32 
func Float32(key string, val float32) Field
// Float32构造一个携带Float32的字段。浮点值的表示方式取决于编码器,因此封送处理必然是惰性的。

func Float32p 
func Float32p(key string, val *float32) Field
// Float32p构造一个携带*float32的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Float32s 
func Float32s(key string, nums []float32) Field
// Float32s构造一个字段,该字段包含一个浮动片段。

func Float64 
func Float64(key string, val float64) Field
// Float64构造一个携带Float64的字段。浮点值的表示方式取决于编码器,因此封送处理必然是惰性的。

func Float64p 
func Float64p(key string, val *float64) Field
// Float64p构造一个携带*float64的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Float64s 
func Float64s(key string, nums []float64) Field
// Float64s构造一个字段,该字段包含一个浮动片段。

func Inline 
func Inline(val zapcore.ObjectMarshaler) Field
// 内联构造了一个类似于Object的字段,但它会将提供的ObjectMarshaler的元素添加到当前命名空间中。

func Int 
func Int(key string, val int) Field
// Int用给定的键和值构造一个字段。

func Int16 
func Int16(key string, val int16) Field
// Int16用给定的键和值构造一个字段。

func Int16p 
func Int16p(key string, val *int16) Field
// Int16p构造一个携带*int16的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Int16s 
func Int16s(key string, nums []int16) Field
// Int16s构造一个携带整数切片的字段。

func Int32 
func Int32(key string, val int32) Field
// Int32用给定的键和值构造一个字段。

func Int32p 
func Int32p(key string, val *int32) Field
// Int32p构造一个携带*int32的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Int32s 
func Int32s(key string, nums []int32) Field
// Int32s构造一个字段,该字段包含一个整数片段。

func Int64 
func Int64(key string, val int64) Field
// Int64用给定的键和值构造一个字段。

func Int64p 
func Int64p(key string, val *int64) Field
// Int64p构造一个携带*int64的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Int64s 
func Int64s(key string, nums []int64) Field
// Int64s构造一个携带整数切片的字段。

func Int8 
func Int8(key string, val int8) Field
// Int8用给定的键和值构造一个字段。

func Int8p 
func Int8p(key string, val *int8) Field
// Int8p构造一个携带*int8的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Int8s 
func Int8s(key string, nums []int8) Field
// Int8s构造一个字段,该字段包含一个整数片段。

func Intp 
func Intp(key string, val *int) Field
// Intp构造了一个带有*int的字段。在适当的时候,返回的字段将安全且显式地表示'nil'。

func Ints 
func Ints(key string, nums []int) Field
// Ints构造一个包含整数片段的字段。

func NamedError 
func NamedError(key string, err error) Field
// NamedError构造一个字段,该字段在提供的键下惰性地存储err.Error()。同样实现fmt.Formatter的错误(如github.com/pkg/Errors产生的错误)也将在key+“verbose”下存储其详细表示。如果传递了nil错误,则该字段为no-op。
// 对于键仅为“error”的常见情况,error函数更短,重复性更少。

func Namespace 
func Namespace(key string) Field
// 命名空间在记录器的上下文中创建命名的隔离作用域。所有后续字段都将添加到新命名空间中。
// 这有助于在将记录器注入子组件或第三方库时防止密钥冲突。

// 实例
package main

import (
	"go.uber.org/zap"
)

func main() {
	logger := zap.NewExample()
	defer logger.Sync()

	logger.With(
		zap.Namespace("metrics"),
		zap.Int("counter", 1),
	).Info("tracked some metrics")
}

// 输出:
// {"level":"info","msg":"tracked some metrics","metrics":{"counter":1}}

func Object 
func Object(key string, val zapcore.ObjectMarshaler) Field
// 对象使用给定的键和ObjectMarshaler构造一个字段。它提供了一种灵活但仍然是类型安全且高效的方法,可以向日志上下文添加类似于map或struct的用户定义类型。该结构的MarshallLogObject方法被延迟调用。

// 实例
package main

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

type addr struct {
	IP   string
	Port int
}

type request struct {
	URL    string
	Listen addr
	Remote addr
}

func (a addr) MarshalLogObject(enc zapcore.ObjectEncoder) error {
	enc.AddString("ip", a.IP)
	enc.AddInt("port", a.Port)
	return nil
}

func (r request) MarshalLogObject(enc zapcore.ObjectEncoder) error {
	enc.AddString("url", r.URL)
	zap.Inline(r.Listen).AddTo(enc)
	return enc.AddObject("remote", r.Remote)
}

func main() {
	logger := zap.NewExample()
	defer logger.Sync()

	req := &request{
		URL:    "/test",
		Listen: addr{"127.0.0.1", 8080},
		Remote: addr{"127.0.0.1", 31200},
	}
	logger.Info("new request, in nested object", zap.Object("req", req))
	logger.Info("new request, inline", zap.Inline(req))
}

// 输出:
// {“level”:“info”,“msg”:“new request,in nested object”,“req”:{“url”:“/test”,“ip”:“127.0.0.1”,“port”:8080,“remote”:{“ip”:“127.0.0.1”,“port”:31200}
// {“level”:“info”,“msg”:“newrequest,inline”,“url”:“/test”,“ip”:“127.0.0.1”,“port”:8080,“remote”:{“ip”:“127.0.0.1”,“port”:31200}

func Reflect 
func Reflect(key string, val interface{}) Field
// Reflect使用给定的键和任意对象构造字段。它使用一个编码适当的、基于反射的函数将几乎所有对象延迟序列化到日志上下文中,但它相对较慢且分配量较大。在测试之外,任何测试都是更好的选择。

// 如果编码失败(例如,尝试将map[int]字符串序列化为JSON),Reflect将在最终日志输出中包含错误消息。

func Skip 
func Skip() Field
// Skip构造一个无操作字段,在处理其他字段构造函数中的无效输入时,该字段通常很有用。

func Stack 
func Stack(key string) Field
// 堆栈构造一个字段,该字段在提供的键下存储当前goroutine的stacktrace。请记住,进行stacktrace是一种渴望和昂贵的行为(相对而言);此函数同时进行分配,大约需要两微秒。

func StackSkip 
func StackSkip(key string, skip int) Field
// StackSkip构造一个类似于Stack的字段,但也会从stacktrace的顶部跳过给定数量的帧。

func String 
func String(key string, val string) Field
// String用给定的键和值构造一个字段。

func Stringer 
func Stringer(key string, val fmt.Stringer) Field
// Stringer使用给定的键和值的String方法的输出构造一个字段。Stringer的String方法被惰性地调用。

func Stringp 
func Stringp(key string, val *string) Field
// Stringp构造一个携带*字符串的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Strings 
func Strings(key string, ss []string) Field
// Strings构造一个字段,该字段包含一段字符串。

func Time 
func Time(key string, val time.Time) Field
// 时间用给定的键和值构造一个字段。编码器控制时间的序列化方式。

func Timep 
func Timep(key string, val *time.Time) Field
// Timep构造了一个字段,其中包含*time.time。适当时,返回的字段将安全且明确地表示'nil'。

func Times 
func Times(key string, ts []time.Time) Field
// Times构造了一个字段,其中包含一段time.Times。

func Uint 
func Uint(key string, val uint) Field
// Uint用给定的键和值构造一个字段。

func Uint16 
func Uint16(key string, val uint16) Field
// Uint16用给定的键和值构造一个字段。

func Uint16p 
func Uint16p(key string, val *uint16) Field
// Uint16p构造一个携带*uint16的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Uint16s 
func Uint16s(key string, nums []uint16) Field
// Uint16s构造一个字段,该字段包含一个无符号整数片段。

func Uint32 
func Uint32(key string, val uint32) Field
// Uint32用给定的键和值构造一个字段。

func Uint32p 
func Uint32p(key string, val *uint32) Field
// Uint32p构造一个携带*uint32的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Uint32s 
func Uint32s(key string, nums []uint32) Field
// Uint32s构造一个字段,该字段包含一个无符号整数片段。

func Uint64 
func Uint64(key string, val uint64) Field
// Uint64使用给定的键和值构造字段。

func Uint64p 
func Uint64p(key string, val *uint64) Field
// Uint64p构造一个携带*uint64的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Uint64s 
func Uint64s(key string, nums []uint64) Field
// Uint64s构造一个字段,该字段包含一个无符号整数片段。

func Uint8 
func Uint8(key string, val uint8) Field
// Uint8用给定的键和值构造一个字段。

func Uint8p 
func Uint8p(key string, val *uint8) Field
// Uint8p构造一个携带*uint8的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Uint8s 
func Uint8s(key string, nums []uint8) Field
// Uint8s构造一个字段,该字段包含一个无符号整数片段。

func Uintp 
func Uintp(key string, val *uint) Field
// Uintp构造一个携带*uint的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Uintptr 
func Uintptr(key string, val uintptr) Field
// Uintptr用给定的键和值构造一个字段。

func Uintptrp 
func Uintptrp(key string, val *uintptr) Field
// Uintptrp构造了一个携带*uintpttr的字段。适当时,返回的字段将安全且明确地表示'nil'。

func Uintptrs 
func Uintptrs(key string, us []uintptr) Field
// Uintptrs构造一个字段,该字段包含指针地址的一部分。

func Uints 
func Uints(key string, nums []uint) Field
// UINT构造一个字段,该字段包含一个无符号整数片段。

type LevelEnablerFunc 
type LevelEnablerFunc func(zapcore.Level) bool
// LevelEnablerFunc是使用匿名函数实现zapcore.LevelEnabler的一种方便方法。

// 当在不同输出(例如,标准错误和标准输出)之间拆分日志输出时,它特别有用。有关示例代码,请参阅包级AdvancedConfiguration示例。

func (LevelEnablerFunc) Enabled 
func (f LevelEnablerFunc) Enabled(lvl zapcore.Level) bool
// Enabled调用包装函数。

type Logger 
type Logger struct {
    //包含已过滤或未报告的字段
}
// 记录器提供快速、分级、结构化的日志记录。所有方法都可以安全地同时使用。
// 记录器是为每微秒和每一次分配都很重要的上下文而设计的,因此它的API有意地支持性能和类型安全,而不是简洁。对于大多数应用,SugaredLogger在性能和人体工程学之间取得了更好的平衡。

func L 
func L() *Logger
// L返回全局记录器,可使用ReplaceGlobals对其进行重新配置。同时使用是安全的。

func New 
func New(core zapcore.Core, options ...Option) *Logger
// New从提供的zapcore.Core和Options构建一个新的记录器。如果传递的zapcore.Core为nil,它将返回到使用no-op实现。
// 这是构造记录器最灵活的方法,但也是最冗长的方法。对于典型用例,高度自以为是的预设(NewProduction、NewDevelopment和NewExample)或配置结构更为方便。
// 有关示例代码,请参阅包级AdvancedConfiguration示例。

func NewDevelopment 
func NewDevelopment(options ...Option) (*Logger, error)
// NewDevelopment构建了一个开发记录器,它以人性化的格式将DebugLevel及以上日志写入标准错误。
// 这是NewDevelopmentConfig().Build(…选项)的快捷方式。

func NewExample 
func NewExample(options ...Option) *Logger
// NewExample构建了一个记录器,该记录器专为zap的可测试示例而设计。它将DebugLevel和更高级别的日志作为JSON写入标准输出,但省略了时间戳和调用函数,以保持示例输出的简短和确定性。

func NewNop 
func NewNop() *Logger
// NewNop返回一个无操作记录器。它从不写出日志或内部错误,也从不运行用户定义的钩子。

// 使用WithOptions替换无操作记录器的核心或错误输出可以重新启用日志记录。

func NewProduction 
func NewProduction(options ...Option) (*Logger, error)
// NewProduction构建了一个合理的生产记录器,将InfoLevel及以上日志作为JSON写入标准错误。

// 这是NewProductionConfig().Build(…选项)的快捷方式。

func (*Logger) Check 
func (log *Logger) Check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry
// 如果启用了在指定级别记录消息,则Check返回CheckedEntry。这是一个完全可选的优化;在高性能应用程序中,Check有助于避免将切片分配给保存字段。

// 实例
package main

import (
	"go.uber.org/zap"
)

func main() {
	logger := zap.NewExample()
	defer logger.Sync()

	if ce := logger.Check(zap.DebugLevel, "debugging"); ce != nil {
		// If debug-level log output isn't enabled or if zap's sampling would have
		// dropped this log entry, we don't allocate the slice that holds these
		// fields.
		ce.Write(
			zap.String("foo", "bar"),
			zap.String("baz", "quux"),
		)
	}

}

// 输出:
// {“level”:“debug”,“msg”:“debug”,“foo”:“bar”,“baz”:“qux”}

func (*Logger) Core 
func (log *Logger) Core() zapcore.Core
// Core返回记录器的基础zapcore.Core。

func (*Logger) DPanic 
func (log *Logger) DPanic(msg string, fields ...Field)
// DPanic在DPanic级别记录消息。该消息包括在日志站点传递的任何字段,以及在记录器上累积的任何字段。

// 如果记录器处于开发模式,则会出现恐慌(DPanic表示“开发恐慌”)。这对于捕获可恢复但不应该发生的错误非常有用。

func (*Logger) Debug 
func (log *Logger) Debug(msg string, fields ...Field)
// 调试在调试级别记录消息。该消息包括在日志站点传递的任何字段,以及在记录器上累积的任何字段。

func (*Logger) Error 
func (log *Logger) Error(msg string, fields ...Field)
// Error在ErrorLevel上记录消息。该消息包括在日志站点传递的任何字段,以及在记录器上累积的任何字段。

func (*Logger) Fatal 
func (log *Logger) Fatal(msg string, fields ...Field)
// Fatal在FatalLevel上记录消息。该消息包括在日志站点传递的任何字段,以及在记录器上累积的任何字段。

// 记录器然后调用os.Exit(1),即使FatalLevel的日志记录被禁用。

func (*Logger) Info 
func (log *Logger) Info(msg string, fields ...Field)
// Info在信息级别记录消息。该消息包括在日志站点传递的任何字段,以及在记录器上累积的任何字段。

func (*Logger) Named 
func (log *Logger) Named(s string) *Logger
// 命名将新路径段添加到记录器的名称中。段由句点连接。默认情况下,记录器未命名。

// 实例
package main

import (
	"go.uber.org/zap"
)

func main() {
	logger := zap.NewExample()
	defer logger.Sync()

    //默认情况下,记录器未命名。
	logger.Info("no name")

    //第一次调用Named设置记录器名称。
	main := logger.Named("main")
	main.Info("main logger")

    //对命名路径的其他调用将创建以句点分隔的路径。
	main.Named("subpackage").Info("sub-logger")
}

// 输出:
// {“level”:“info”,“msg”:“no name”}
// {“level”:“info”,“logger”:“main”,“msg”:“main logger”}
// {“level”:“info”,“logger”:“main.subpackage”,“msg”:“sublogger”}


func (*Logger) Panic 
func (log *Logger) Panic(msg string, fields ...Field)
// 恐慌在恐慌级别记录消息。该消息包括在日志站点传递的任何字段,以及在记录器上累积的任何字段。

// 然后,记录器会死机,即使禁用了“死机级别”的日志记录。

func (*Logger) Sugar 
func (log *Logger) Sugar() *SugaredLogger
// Sugar将Logger包裹起来,以提供更符合人体工程学但稍慢的API。为记录器添加糖分非常便宜,因此单个应用程序同时使用Logger和SugaredLogger是合理的,它们在性能敏感代码的边界上进行转换。

func (*Logger) Sync 
func (log *Logger) Sync() error
// Sync调用底层内核的Sync方法,刷新任何缓冲日志条目。应用程序在退出前应注意调用同步。

func (*Logger) Warn 
func (log *Logger) Warn(msg string, fields ...Field)
// Warn在Warn级别记录消息。该消息包括在日志站点传递的任何字段,以及在记录器上累积的任何字段。

func (*Logger) With 
func (log *Logger) With(fields ...Field) *Logger
// With创建子记录器并向其添加结构化上下文。添加到子级的字段不会影响父级,反之亦然。

func (*Logger) WithOptions 
func (log *Logger) WithOptions(opts ...Option) *Logger
// WithOptions克隆当前记录器,应用提供的选项,并返回结果记录器。同时使用是安全的。

type Option 
type Option interface {
    //包含已过滤或未报告的方法
}
// 一个选项配置记录器。

func AddCaller 
func AddCaller() Option
// AddCaller将记录器配置为使用zap调用者的文件名、行号和函数名注释每条消息。另请参见WithCaller。

func AddCallerSkip 
func AddCallerSkip(skip int) Option
// AddCallerSkip增加调用方注释跳过的调用方数量(由AddCaller选项启用)。在围绕Logger和SugaredLogger构建包装器时,提供此选项可防止zap始终将包装器代码报告为调用方。

func AddStacktrace 
func AddStacktrace(lvl zapcore.LevelEnabler) Option
// AddStacktrace将记录器配置为记录给定级别或以上的所有消息的堆栈跟踪。

func Development 
func Development() Option
// 开发将记录器置于开发模式,这会使DPanic级别的日志死机,而不是简单地记录错误。

func ErrorOutput 
func ErrorOutput(w zapcore.WriteSyncer) Option
// ErrorOutput设置记录器生成的错误的目标。请注意,此选项仅影响内部错误;有关将错误级别日志发送到与信息和调试级别日志不同位置的示例代码,请参阅包级别AdvancedConfiguration示例。

// 提供的WriteSyncer必须能够安全地并发使用。Open和zapcore.Lock函数是使用互斥锁保护文件的最简单方法。

func Fields 
func Fields(fs ...Field) Option
// 字段将字段添加到记录器。

func Hooks 
func Hooks(hooks ...func(zapcore.Entry) error) Option
// Hooks注册每次记录器写出条目时调用的函数。反复使用挂钩是一种累加。

// 钩子对于简单的副作用很有用,比如捕获已发出日志数的指标。更复杂的副作用,包括需要访问条目的结构化字段的任何内容,应该改为实现为zapcore.Core。有关详细信息,请参阅zapcore.RegisterHooks。

func IncreaseLevel 
func IncreaseLevel(lvl zapcore.LevelEnabler) Option
// IncreaseLevel增加记录器的级别。如果传入的级别试图降低记录器的级别,则它无效。

func OnFatal 
func OnFatal(action zapcore.CheckWriteAction) Option
// OnFatal设置要对致命日志执行的操作。

func WithCaller 
func WithCaller(enabled bool) Option
// WithCaller将记录器配置为根据enabled的值,使用zap调用者的文件名、行号和函数名注释每条消息。这是AddCaller的一种广义形式。

func WithClock 
func WithClock(clock zapcore.Clock) Option
// WithClock指定记录器用于确定记录条目的当前时间的时钟。默认为带time.Now的系统时钟。

func WrapCore 
func WrapCore(f func(zapcore.Core) zapcore.Core) Option
// WrapCore包装或替换记录器的底层zapcore.Core。

// 示例(Replace)
package main

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

func main() {
	// Replacing a Logger's core can alter fundamental behaviors.
	// For example, it can convert a Logger to a no-op.
	nop := zap.WrapCore(func(zapcore.Core) zapcore.Core {
		return zapcore.NewNopCore()
	})

	logger := zap.NewExample()
	defer logger.Sync()

	logger.Info("working")
	logger.WithOptions(nop).Info("no-op")
	logger.Info("original logger still works")
}

// 输出:
// {“level”:“info”,“msg”:“working”}
// {“level”:“info”,“msg”:“原始记录器仍然工作”}


// 示例(Wrap)
package main

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

func main() {
	// Wrapping a Logger's core can extend its functionality. As a trivial
	// example, it can double-write all logs.
	doubled := zap.WrapCore(func(c zapcore.Core) zapcore.Core {
		return zapcore.NewTee(c, c)
	})

	logger := zap.NewExample()
	defer logger.Sync()

	logger.Info("single")
	logger.WithOptions(doubled).Info("doubled")
}

// 输出:
// {“level”:“info”,“msg”:“single”}
// {“level”:“info”,“msg”:“double”}
// {“level”:“info”,“msg”:“double”}


type SamplingConfig 
type SamplingConfig struct {
	Initial    int                                           `json:"initial" yaml:"initial"`
	Thereafter int                                           `json:"thereafter" yaml:"thereafter"`
	Hook       func(zapcore.Entry, zapcore.SamplingDecision) `json:"-" yaml:"-"`
}
// SamplingConfig为记录器设置采样策略。采样会限制日志记录在进程上的全局CPU和I/O负载,同时尝试保留日志的代表性子集。
// 如果指定,采样器将在每个决策之后调用钩子。
// 此处配置的值为每秒。有关详细信息,请参阅zapcore.NewSamplerWithOptions。

type Sink 
type Sink interface {
	zapcore.WriteSyncer
	io.Closer
}
// Sink定义写入和关闭记录器目标的接口。

type SugaredLogger 
type SugaredLogger struct {
    //包含已过滤或未报告的字段
}
// SugaredLogger将基本记录器功能封装在较慢但不太详细的API中。任何记录器都可以使用其Sugar方法转换为SugaredLogger。

// 与记录器不同,SugaredLogger不坚持结构化日志记录。对于每个日志级别,它公开了三种方法:一种用于松散类型的结构化日志记录,一种用于println样式的格式化,另一种用于printf样式的格式化。例如,SugaredLogger可以使用Infow(“具有结构化上下文的信息”)、info或Infof生成InfoLevel输出。

func S 
func S() *SugaredLogger
// S返回全局SugaredLogger,可以使用ReplaceGlobals重新配置。同时使用是安全的。

func (*SugaredLogger) DPanic 
func (s *SugaredLogger) DPanic(args ...interface{})
// DPanic使用fmt.Sprint构造并记录消息。在开发过程中,记录器会出现恐慌。(有关详细信息,请参见DPL级别。)

func (*SugaredLogger) DPanicf 
func (s *SugaredLogger) DPanicf(template string, args ...interface{})
// DPanicf使用fmt.Sprintf记录模板化消息。在开发过程中,记录器会出现恐慌。(有关详细信息,请参见DPL级别。)

func (*SugaredLogger) DPanicw 
func (s *SugaredLogger) DPanicw(msg string, keysAndValues ...interface{})
// DPanicw使用一些附加上下文记录消息。在开发过程中,记录器会出现恐慌。(有关详细信息,请参见DPA级别。)可变键值对的处理方式与中的相同。

func (*SugaredLogger) Debug 
func (s *SugaredLogger) Debug(args ...interface{})
// Debug使用fmt.Sprint构造并记录消息。

func (*SugaredLogger) Debugf 
func (s *SugaredLogger) Debugf(template string, args ...interface{})
// Debugf使用fmt.Sprintf记录模板化消息。

func (*SugaredLogger) Debugw 
func (s *SugaredLogger) Debugw(msg string, keysAndValues ...interface{})
// Debugw使用一些附加上下文记录消息。可变键-值对的处理方式与相同。
// 禁用调试级别日志记录时,这比
s.With(keysAndValues).Debug(msg)

func (*SugaredLogger) Desugar 
func (s *SugaredLogger) Desugar() *Logger
// Desugar打开SugaredLogger,露出原始Logger。Desugaring非常便宜,因此单个应用程序同时使用Logger和SugaredLogger是合理的,它们在性能敏感代码的边界上进行转换。

func (*SugaredLogger) Error 
func (s *SugaredLogger) Error(args ...interface{})
// Error使用fmt.Sprint构造并记录消息。

func (*SugaredLogger) Errorf 
func (s *SugaredLogger) Errorf(template string, args ...interface{})
// Errorf使用fmt.Sprintf记录模板化消息。

func (*SugaredLogger) Errorw 
func (s *SugaredLogger) Errorw(msg string, keysAndValues ...interface{})
// Errorw使用一些附加上下文记录消息。可变键-值对的处理方式与相同。

func (*SugaredLogger) Fatal 
func (s *SugaredLogger) Fatal(args ...interface{})
// Fatal使用fmt.Sprint构造并记录消息,然后调用os.Exit。

func (*SugaredLogger) Fatalf 
func (s *SugaredLogger) Fatalf(template string, args ...interface{})
// Fatalf使用fmt.Sprintf记录模板化消息,然后调用os.Exit。

func (*SugaredLogger) Fatalw 
func (s *SugaredLogger) Fatalw(msg string, keysAndValues ...interface{})
// Fatalw记录一条带有一些附加上下文的消息,然后调用os.Exit。可变键-值对的处理方式与相同。

func (*SugaredLogger) Info 
func (s *SugaredLogger) Info(args ...interface{})
// Info使用fmt.Sprint构造并记录消息。

func (*SugaredLogger) Infof 
func (s *SugaredLogger) Infof(template string, args ...interface{})
// Infof使用fmt.Sprintf记录模板化消息。

func (*SugaredLogger) Infow 
func (s *SugaredLogger) Infow(msg string, keysAndValues ...interface{})
// Infow使用一些附加上下文记录消息。可变键-值对的处理方式与相同。

func (*SugaredLogger) Named 
func (s *SugaredLogger) Named(name string) *SugaredLogger
// 命名将子作用域添加到记录器的名称中。有关详细信息,请参阅Logger.Named。

func (*SugaredLogger) Panic 
func (s *SugaredLogger) Panic(args ...interface{})
// Panic使用fmt.Sprint构造并记录一条消息,然后panics。

func (*SugaredLogger) Panicf 
func (s *SugaredLogger) Panicf(template string, args ...interface{})
// Panicf使用fmt.Sprintf来记录模板化消息,然后使用panics。

func (*SugaredLogger) Panicw 
func (s *SugaredLogger) Panicw(msg string, keysAndValues ...interface{})
// Panicw使用一些附加上下文记录消息,然后panics。可变键-值对的处理方式与相同。

func (*SugaredLogger) Sync 
func (s *SugaredLogger) Sync() error
// 同步刷新所有缓冲日志条目。

func (*SugaredLogger) Warn 
func (s *SugaredLogger) Warn(args ...interface{})
// Warn使用fmt.Sprint构造并记录消息。

func (*SugaredLogger) Warnf 
func (s *SugaredLogger) Warnf(template string, args ...interface{})
// Warnf使用fmt.Sprintf记录模板化消息。

func (*SugaredLogger) Warnw 
func (s *SugaredLogger) Warnw(msg string, keysAndValues ...interface{})
// Warnw使用一些附加上下文记录消息。可变键-值对的处理方式与相同。

func (*SugaredLogger) With 
func (s *SugaredLogger) With(args ...interface{}) *SugaredLogger
// With向日志记录上下文添加可变数量的字段。它接受强类型字段对象和松散类型键值对的混合。处理对时,对中的第一个元素用作字段键,第二个元素用作字段值。

// 例如
 sugaredLogger.With(
   "hello", "world",
   "failure", errors.New("oh no"),
   Stack(),
   "count", 42,
   "user", User{Name: "alice"},
)

// 相当于
unsugared.With(
  String("hello", "world"),
  String("failure", "oh no"),
  Stack(),
  Int("count", 42),
  Object("user", User{Name: "alice"}),
)
// 注意,键值对中的键应该是字符串。在开发过程中,传递非字符串键会引起恐慌。在生产环境中,记录器更加宽容:记录单独的错误,但跳过键值对并继续执行。传递孤立密钥会触发类似的行为:开发恐慌和生产错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值