You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
6.9 KiB
187 lines
6.9 KiB
package core
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// DefaultLineEnding defines the default line ending when writing logs.
|
|
// Alternate line endings specified in EncoderConfig can override this
|
|
// behavior.
|
|
const DefaultLineEnding = "\n"
|
|
|
|
// ObjectEncoder is a strongly-typed, encoding-agnostic interface for adding a
|
|
// map- or struct-like object to the logging context. Like maps, ObjectEncoders
|
|
// aren't safe for concurrent use (though typical use shouldn't require locks).
|
|
type ObjectEncoder interface {
|
|
// Logging-specific marshalers.
|
|
AddArray(key string, marshaler ArrayMarshaler) error
|
|
AddObject(key string, marshaler ObjectMarshaler) error
|
|
|
|
// Built-in types.
|
|
AddBinary(key string, value []byte) // for arbitrary bytes
|
|
AddByteString(key string, value []byte) // for UTF-8 encoded bytes
|
|
AddBool(key string, value bool)
|
|
AddComplex128(key string, value complex128)
|
|
AddComplex64(key string, value complex64)
|
|
AddDuration(key string, value time.Duration)
|
|
AddFloat64(key string, value float64)
|
|
AddFloat32(key string, value float32)
|
|
AddInt(key string, value int)
|
|
AddInt64(key string, value int64)
|
|
AddInt32(key string, value int32)
|
|
AddInt16(key string, value int16)
|
|
AddInt8(key string, value int8)
|
|
AddString(key, value string)
|
|
AddTime(key string, value time.Time)
|
|
AddUint(key string, value uint)
|
|
AddUint64(key string, value uint64)
|
|
AddUint32(key string, value uint32)
|
|
AddUint16(key string, value uint16)
|
|
AddUint8(key string, value uint8)
|
|
AddUintptr(key string, value uintptr)
|
|
|
|
// AddReflected uses reflection to serialize arbitrary objects, so it's slow
|
|
// and allocation-heavy.
|
|
AddReflected(key string, value interface{}) error
|
|
// OpenNamespace opens an isolated namespace where all subsequent fields will
|
|
// be added. Applications can use namespaces to prevent key collisions when
|
|
// injecting loggers into sub-components or third-party libraries.
|
|
OpenNamespace(key string)
|
|
}
|
|
|
|
// ObjectMarshaler allows user-defined types to efficiently add themselves to the
|
|
// logging context, and to selectively omit information which shouldn't be
|
|
// included in logs (e.g., passwords).
|
|
type ObjectMarshaler interface {
|
|
MarshalLogObject(ObjectEncoder) error
|
|
}
|
|
|
|
// ObjectMarshalerFunc is a type adapter that turns a function into an
|
|
// ObjectMarshaler.
|
|
type ObjectMarshalerFunc func(ObjectEncoder) error
|
|
|
|
// MarshalLogObject calls the underlying function.
|
|
func (f ObjectMarshalerFunc) MarshalLogObject(enc ObjectEncoder) error {
|
|
return f(enc)
|
|
}
|
|
|
|
// ArrayMarshaler allows user-defined types to efficiently add themselves to the
|
|
// logging context, and to selectively omit information which shouldn't be
|
|
// included in logs (e.g., passwords).
|
|
type ArrayMarshaler interface {
|
|
MarshalLogArray(ArrayEncoder) error
|
|
}
|
|
|
|
// ArrayMarshalerFunc is a type adapter that turns a function into an
|
|
// ArrayMarshaler.
|
|
type ArrayMarshalerFunc func(ArrayEncoder) error
|
|
|
|
// MarshalLogArray calls the underlying function.
|
|
func (f ArrayMarshalerFunc) MarshalLogArray(enc ArrayEncoder) error {
|
|
return f(enc)
|
|
}
|
|
|
|
// ArrayEncoder is a strongly-typed, encoding-agnostic interface for adding
|
|
// array-like objects to the logging context. Of note, it supports mixed-type
|
|
// arrays even though they aren't typical in Go. Like slices, ArrayEncoders
|
|
// aren't safe for concurrent use (though typical use shouldn't require locks).
|
|
type ArrayEncoder interface {
|
|
// Built-in types.
|
|
PrimitiveArrayEncoder
|
|
|
|
// Time-related types.
|
|
AppendDuration(time.Duration)
|
|
AppendTime(time.Time)
|
|
|
|
// Logging-specific marshalers.
|
|
AppendArray(ArrayMarshaler) error
|
|
AppendObject(ObjectMarshaler) error
|
|
|
|
// AppendReflected uses reflection to serialize arbitrary objects, so it's
|
|
// slow and allocation-heavy.
|
|
AppendReflected(value interface{}) error
|
|
}
|
|
|
|
// PrimitiveArrayEncoder is the subset of the ArrayEncoder interface that deals
|
|
// only in Go's built-in types. It's included only so that Duration- and
|
|
// TimeEncoders cannot trigger infinite recursion.
|
|
type PrimitiveArrayEncoder interface {
|
|
// Built-in types.
|
|
AppendBool(bool)
|
|
AppendByteString([]byte) // for UTF-8 encoded bytes
|
|
AppendComplex128(complex128)
|
|
AppendComplex64(complex64)
|
|
AppendFloat64(float64)
|
|
AppendFloat32(float32)
|
|
AppendInt(int)
|
|
AppendInt64(int64)
|
|
AppendInt32(int32)
|
|
AppendInt16(int16)
|
|
AppendInt8(int8)
|
|
AppendString(string)
|
|
AppendUint(uint)
|
|
AppendUint64(uint64)
|
|
AppendUint32(uint32)
|
|
AppendUint16(uint16)
|
|
AppendUint8(uint8)
|
|
AppendUintptr(uintptr)
|
|
}
|
|
|
|
// An EncoderConfig allows users to configure the concrete encoders supplied by
|
|
// zapcore.
|
|
type EncoderConfig struct {
|
|
EncodeTime TimeEncoder `json:"timeEncoder" yaml:"timeEncoder"`
|
|
EncodeDuration DurationEncoder `json:"durationEncoder" yaml:"durationEncoder"`
|
|
// Configure the primitive representations of common complex types. For
|
|
// example, some users may want all time.Times serialized as floating-point
|
|
// seconds since epoch, while others may prefer ISO8601 strings.
|
|
/*EncodeLevel LevelEncoder `json:"levelEncoder" yaml:"levelEncoder"`
|
|
EncodeTime TimeEncoder `json:"timeEncoder" yaml:"timeEncoder"`
|
|
EncodeDuration DurationEncoder `json:"durationEncoder" yaml:"durationEncoder"`
|
|
EncodeCaller CallerEncoder `json:"callerEncoder" yaml:"callerEncoder"`
|
|
// Unlike the other primitive type encoders, EncodeName is optional. The
|
|
// zero value falls back to FullNameEncoder.
|
|
EncodeName NameEncoder `json:"nameEncoder" yaml:"nameEncoder"`*/
|
|
}
|
|
|
|
// Encoder is a format-agnostic interface for all log entry marshalers. Since
|
|
// log encoders don't need to support the same wide range of use cases as
|
|
// general-purpose marshalers, it's possible to make them faster and
|
|
// lower-allocation.
|
|
//
|
|
// Implementations of the ObjectEncoder interface's methods can, of course,
|
|
// freely modify the receiver. However, the Clone and EncodeEntry methods will
|
|
// be called concurrently and shouldn't modify the receiver.
|
|
type Encoder interface {
|
|
ObjectEncoder
|
|
|
|
// Clone copies the encoder, ensuring that adding fields to the copy doesn't
|
|
// affect the original.
|
|
Clone() Encoder
|
|
|
|
// EncodeEntry encodes an entry and fields, along with any accumulated
|
|
// context, into a byte buffer and returns it.
|
|
Encode(*Buffer, ...Field) error
|
|
}
|
|
|
|
// A TimeEncoder serializes a time.Time to a primitive type.
|
|
type TimeEncoder func(time.Time, PrimitiveArrayEncoder)
|
|
|
|
// A DurationEncoder serializes a time.Duration to a primitive type.
|
|
type DurationEncoder func(time.Duration, PrimitiveArrayEncoder)
|
|
|
|
// EpochTimeEncoder serializes a time.Time to a floating-point number of seconds
|
|
// since the Unix epoch.
|
|
func EpochTimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
|
|
//var d []byte
|
|
enc.AppendString(t.Format("2006-01-02T15:04:05.999999"))
|
|
//enc.AppendByteString(t.AppendFormat(d, "2006-01-02T15:04:05.999999"))
|
|
/*nanos := t.UnixNano()
|
|
sec := float64(nanos) / float64(time.Second)
|
|
enc.AppendFloat64(sec)*/
|
|
}
|
|
|
|
// SecondsDurationEncoder serializes a time.Duration to a floating-point number of seconds elapsed.
|
|
func SecondsDurationEncoder(d time.Duration, enc PrimitiveArrayEncoder) {
|
|
enc.AppendFloat64(float64(d) / float64(time.Second))
|
|
}
|
|
|