golang의zap의marshaler에 대해서 얘기를 해볼게요.

6673 단어 golang

순서


본고는 주로 golang의zap의marshaler를 연구하고자 한다

ObjectMarshaler


[email protected]/zapcore/marshaler.go
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)
}

Object Marshaler 인터페이스는 MarshalLog Object 방법을 정의합니다.ObjectMarshalerFunc 유형은 MarshalLogObject 방법을 정의하여 ObjectMarshalerFunc로 하여금 ObjectMarshaler 인터페이스를 실현하게 한다

ArrayMarshaler


[email protected]/zapcore/marshaler.go
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)
}

Array Marshaler 인터페이스는 MarshalLogArray 방법을 정의합니다.ArrayMarshalerFunc 유형은 MarshalLogArray 방법을 정의하여 ArrayMarshalerFunc가 MarshalLogArray 인터페이스를 실현하도록 합니다.

ObjectEncoder


[email protected]/zapcore/encoder.go
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 can be
    // 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)
}

ObjectEncoder의 AddArray 방법에는 ArrayMarshaler 매개 변수가 필요하고, AddObject 방법에는 ObjectMarshaler 매개 변수가 필요합니다.

zap.Object


[email protected]/field.go
// Object constructs a field with the given key and ObjectMarshaler. It
// provides a flexible, but still type-safe and efficient, way to add map- or
// struct-like user-defined types to the logging context. The struct's
// MarshalLogObject method is called lazily.
func Object(key string, val zapcore.ObjectMarshaler) Field {
    return Field{Key: key, Type: zapcore.ObjectMarshalerType, Interface: val}
}

zap.Object 방법은zapcore를 실현하기 위해value를 요구합니다.ObjectMarshaler 인터페이스

zap.Array


[email protected]/array.go
// Array constructs a field with the given key and ArrayMarshaler. It provides
// a flexible, but still type-safe and efficient, way to add array-like types
// to the logging context. The struct's MarshalLogArray method is called lazily.
func Array(key string, val zapcore.ArrayMarshaler) Field {
    return Field{Key: key, Type: zapcore.ArrayMarshalerType, Interface: val}
}

zap.Array 메서드는 zapcore의 값을 요구합니다.ArrayMarshaler 커넥터

인스턴스

type User struct {
    Name      string
    Email     string
    CreatedAt time.Time
}

func (u *User) MarshalLogObject(enc zapcore.ObjectEncoder) error {
    enc.AddString("name", u.Name)
    enc.AddString("email", u.Email)
    enc.AddInt64("created_at", u.CreatedAt.UnixNano())
    return nil
}

type Users []*User

func (uu Users) MarshalLogArray(arr zapcore.ArrayEncoder) error {
    var err error
    for i := range uu {
        err = multierr.Append(err, arr.AppendObject(uu[i]))
    }
    return err
}

func marshalerDemo() {
    logger, err := zap.NewProduction()
    defer logger.Sync()
    if err != nil {
        panic(err)
    }
    var user = &User{
        Name:      "hello1",
        Email:     "[email protected]",
        CreatedAt: time.Date(2020, 12, 19, 8, 0, 0, 0, time.UTC),
    }
    var users Users
    users = append(users, &User{
        Name:      "hello2",
        Email:     "[email protected]",
        CreatedAt: time.Date(2020, 12, 19, 9, 0, 0, 0, time.UTC),
    }, &User{
        Name:      "hello3",
        Email:     "[email protected]",
        CreatedAt: time.Date(2020, 12, 20, 10, 0, 0, 0, time.UTC),
    })
    logger.Info("marshaler", zap.Object("user", user))
    logger.Info("marshaler", zap.Array("users", users))
}

사용자 유형은 MarshalLogObject 방법을 실현했다.Users 유형은 MarshalLogArray 방법을 실현했다.이후 logger에서 Field를 추가할 때zap를 사용할 수 있습니다.Object 또는zap.Array 메서드
출력
{"level":"info","ts":1608348349.487255,"caller":"zap/zap_demo.go:66","msg":"marshaler","user":{"name":"hello1","email":"[email protected]","created_at":1608364800000000000}}
{"level":"info","ts":1608348349.4873412,"caller":"zap/zap_demo.go:67","msg":"marshaler","users":[{"name":"hello2","email":"[email protected]","created_at":1608368400000000000},{"name":"hello3","email":"[email protected]","created_at":1608458400000000000}]}

작은 매듭


zap의 marshaler는 Object Marshaler(MarshalLogObject 및 Array Marshaler(MarshalLogArray 인터페이스를 정의했다.logger에서 zap를 사용하고 싶으면.Object 또는zap.Array 방법은 대응하는 유형에 대응하는 인터페이스를 요구합니다.

doc

  • zap
  • 좋은 웹페이지 즐겨찾기