Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com> (cherry picked from commit 9186039f774168dfbacef04dac8ee56356149736)
707 lines
20 KiB
Diff
707 lines
20 KiB
Diff
From e1b4b7a7008855920f866d0fa4c16d09f9341baf Mon Sep 17 00:00:00 2001
|
|
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
Date: Sat, 25 Nov 2023 15:18:36 +0800
|
|
Subject: [PATCH 07/13] build: update vendor
|
|
|
|
use zapfmt to transform timestamp to human-readable format
|
|
|
|
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
---
|
|
.../github.com/sykesm/zap-logfmt/.gitignore | 1 +
|
|
.../github.com/sykesm/zap-logfmt/.travis.yml | 12 +
|
|
vendor/github.com/sykesm/zap-logfmt/LICENSE | 21 +
|
|
vendor/github.com/sykesm/zap-logfmt/README.md | 76 +++
|
|
.../github.com/sykesm/zap-logfmt/encoder.go | 527 ++++++++++++++++++
|
|
vendor/modules.txt | 3 +
|
|
6 files changed, 640 insertions(+)
|
|
create mode 100644 vendor/github.com/sykesm/zap-logfmt/.gitignore
|
|
create mode 100644 vendor/github.com/sykesm/zap-logfmt/.travis.yml
|
|
create mode 100644 vendor/github.com/sykesm/zap-logfmt/LICENSE
|
|
create mode 100644 vendor/github.com/sykesm/zap-logfmt/README.md
|
|
create mode 100644 vendor/github.com/sykesm/zap-logfmt/encoder.go
|
|
|
|
diff --git a/vendor/github.com/sykesm/zap-logfmt/.gitignore b/vendor/github.com/sykesm/zap-logfmt/.gitignore
|
|
new file mode 100644
|
|
index 0000000..7a6353d
|
|
--- /dev/null
|
|
+++ b/vendor/github.com/sykesm/zap-logfmt/.gitignore
|
|
@@ -0,0 +1 @@
|
|
+.envrc
|
|
diff --git a/vendor/github.com/sykesm/zap-logfmt/.travis.yml b/vendor/github.com/sykesm/zap-logfmt/.travis.yml
|
|
new file mode 100644
|
|
index 0000000..7ce1f7a
|
|
--- /dev/null
|
|
+++ b/vendor/github.com/sykesm/zap-logfmt/.travis.yml
|
|
@@ -0,0 +1,12 @@
|
|
+language: go
|
|
+
|
|
+matrix:
|
|
+ include:
|
|
+ - go: "1.13.x"
|
|
+ install: true
|
|
+ - go: "1.14.x"
|
|
+ install: true
|
|
+ - go: "1.15.x"
|
|
+ install: true
|
|
+
|
|
+script: go test -race ./...
|
|
diff --git a/vendor/github.com/sykesm/zap-logfmt/LICENSE b/vendor/github.com/sykesm/zap-logfmt/LICENSE
|
|
new file mode 100644
|
|
index 0000000..43a1c32
|
|
--- /dev/null
|
|
+++ b/vendor/github.com/sykesm/zap-logfmt/LICENSE
|
|
@@ -0,0 +1,21 @@
|
|
+The MIT License (MIT)
|
|
+
|
|
+Copyright (c) 2017 Jonathan Sternberg
|
|
+Copyright (c) 2019 Matthew Sykes
|
|
+
|
|
+Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
+this software and associated documentation files (the "Software"), to deal in
|
|
+the Software without restriction, including without limitation the rights to
|
|
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
+the Software, and to permit persons to whom the Software is furnished to do so,
|
|
+subject to the following conditions:
|
|
+
|
|
+The above copyright notice and this permission notice shall be included in all
|
|
+copies or substantial portions of the Software.
|
|
+
|
|
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
diff --git a/vendor/github.com/sykesm/zap-logfmt/README.md b/vendor/github.com/sykesm/zap-logfmt/README.md
|
|
new file mode 100644
|
|
index 0000000..751f288
|
|
--- /dev/null
|
|
+++ b/vendor/github.com/sykesm/zap-logfmt/README.md
|
|
@@ -0,0 +1,76 @@
|
|
+# Logfmt Encoder
|
|
+
|
|
+This package provides a logfmt encoder for [zap][zap].
|
|
+
|
|
+It is a fork of [github.com/jsternberg/zap-logfmt][jsternberg] that improves
|
|
+the handling of reflected fields and encodes arrays and objects instead of
|
|
+dropping them from logs. While logging simple fields is preferred for many
|
|
+reasons, having ugly data is often better than missing data.
|
|
+
|
|
+[](https://travis-ci.org/sykesm/zap-logfmt)
|
|
+[](https://godoc.org/github.com/sykesm/zap-logfmt)
|
|
+
|
|
+## Usage
|
|
+
|
|
+The encoder is easy to configure. Simply create a new core with an instance of
|
|
+the logfmt encoder and use it with your preferred logging interface.
|
|
+
|
|
+```go
|
|
+package main
|
|
+
|
|
+import (
|
|
+ "os"
|
|
+
|
|
+ "github.com/sykesm/zap-logfmt"
|
|
+ "go.uber.org/zap"
|
|
+ "go.uber.org/zap/zapcore"
|
|
+)
|
|
+
|
|
+func main() {
|
|
+ config := zap.NewProductionEncoderConfig()
|
|
+ logger := zap.New(zapcore.NewCore(
|
|
+ zaplogfmt.NewEncoder(config),
|
|
+ os.Stdout,
|
|
+ zapcore.DebugLevel,
|
|
+ ))
|
|
+ logger.Info("Hello World")
|
|
+}
|
|
+```
|
|
+
|
|
+## Arrays, Objects, and Reflected Fields
|
|
+
|
|
+While it's best to avoid complex data types in log fields, there are times
|
|
+when they sneak in. When complex fields are included in log records, they will
|
|
+be encoded, but they won't be very pretty.
|
|
+
|
|
+### Arrays
|
|
+
|
|
+Arrays are encoded as a comma separated list of values within square brackets.
|
|
+This format is very similar to JSON encoding. Arrays of simple scalars remain
|
|
+quite readable but including elements that require quoting will result in very
|
|
+ugly records.
|
|
+
|
|
+### Objects
|
|
+
|
|
+Objects are encoded as a space separated list of _key=value_ pairs. Because
|
|
+this format includes an equals sign, the encoded object will require quoting.
|
|
+If any value in the object requires quoting, the required escapes will make
|
|
+the encoded field pretty difficult for humans to read.
|
|
+
|
|
+### Channels and Functions
|
|
+
|
|
+Channels and functions are encoded as their type and their address. There
|
|
+aren't many meaningful ways to log channels and functions...
|
|
+
|
|
+### Maps and Structs
|
|
+
|
|
+Maps and structs are encoded as strings that contain the result of `fmt.Sprint`.
|
|
+
|
|
+## Namespaces
|
|
+
|
|
+Namespaces are supported. If a namespace is opened, all of the keys will
|
|
+be prepended with the namespace name. For example, with the namespace
|
|
+`foo` and the key `bar`, you would get a key of `foo.bar`.
|
|
+
|
|
+[zap]: https://github.com/uber-go/zap
|
|
+[jsternberg]: https://github.com/jsternberg/zap-logfmt
|
|
diff --git a/vendor/github.com/sykesm/zap-logfmt/encoder.go b/vendor/github.com/sykesm/zap-logfmt/encoder.go
|
|
new file mode 100644
|
|
index 0000000..9e960cc
|
|
--- /dev/null
|
|
+++ b/vendor/github.com/sykesm/zap-logfmt/encoder.go
|
|
@@ -0,0 +1,527 @@
|
|
+// Package zaplogfmt provides a zap encoder that formats log entries in
|
|
+// "logfmt" format.
|
|
+package zaplogfmt
|
|
+
|
|
+import (
|
|
+ "bytes"
|
|
+ "encoding"
|
|
+ "encoding/base64"
|
|
+ "encoding/json"
|
|
+ "fmt"
|
|
+ "math"
|
|
+ "reflect"
|
|
+ "strings"
|
|
+ "sync"
|
|
+ "time"
|
|
+ "unicode/utf8"
|
|
+
|
|
+ "go.uber.org/zap/buffer"
|
|
+ "go.uber.org/zap/zapcore"
|
|
+)
|
|
+
|
|
+var (
|
|
+ logfmtPool = sync.Pool{
|
|
+ New: func() interface{} { return &logfmtEncoder{} },
|
|
+ }
|
|
+ bufferpool = buffer.NewPool()
|
|
+)
|
|
+
|
|
+func getEncoder() *logfmtEncoder {
|
|
+ return logfmtPool.Get().(*logfmtEncoder)
|
|
+}
|
|
+
|
|
+func putEncoder(enc *logfmtEncoder) {
|
|
+ enc.EncoderConfig = nil
|
|
+ enc.buf = nil
|
|
+ enc.namespaces = nil
|
|
+ enc.arrayLiteral = false
|
|
+ logfmtPool.Put(enc)
|
|
+}
|
|
+
|
|
+type logfmtEncoder struct {
|
|
+ *zapcore.EncoderConfig
|
|
+ buf *buffer.Buffer
|
|
+ namespaces []string
|
|
+ arrayLiteral bool
|
|
+}
|
|
+
|
|
+// NewEncoder creates an encoder writes logfmt formatted log entries.
|
|
+func NewEncoder(cfg zapcore.EncoderConfig) zapcore.Encoder {
|
|
+ return &logfmtEncoder{
|
|
+ EncoderConfig: &cfg,
|
|
+ buf: bufferpool.Get(),
|
|
+ }
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddArray(key string, arr zapcore.ArrayMarshaler) error {
|
|
+ enc.addKey(key)
|
|
+ return enc.AppendArray(arr)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddBinary(key string, value []byte) {
|
|
+ enc.AddString(key, base64.StdEncoding.EncodeToString(value))
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddBool(key string, value bool) {
|
|
+ enc.addKey(key)
|
|
+ enc.AppendBool(value)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddByteString(key string, value []byte) {
|
|
+ enc.addKey(key)
|
|
+ enc.AppendByteString(value)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddComplex64(k string, v complex64) { enc.AddComplex128(k, complex128(v)) }
|
|
+func (enc *logfmtEncoder) AddComplex128(key string, value complex128) {
|
|
+ enc.addKey(key)
|
|
+ enc.AppendComplex128(value)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddDuration(key string, value time.Duration) {
|
|
+ enc.addKey(key)
|
|
+ enc.AppendDuration(value)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddFloat32(key string, value float32) {
|
|
+ enc.addKey(key)
|
|
+ enc.AppendFloat32(value)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddFloat64(key string, value float64) {
|
|
+ enc.addKey(key)
|
|
+ enc.AppendFloat64(value)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddInt(k string, v int) { enc.AddInt64(k, int64(v)) }
|
|
+func (enc *logfmtEncoder) AddInt8(k string, v int8) { enc.AddInt64(k, int64(v)) }
|
|
+func (enc *logfmtEncoder) AddInt32(k string, v int32) { enc.AddInt64(k, int64(v)) }
|
|
+func (enc *logfmtEncoder) AddInt16(k string, v int16) { enc.AddInt64(k, int64(v)) }
|
|
+func (enc *logfmtEncoder) AddInt64(key string, value int64) {
|
|
+ enc.addKey(key)
|
|
+ enc.AppendInt64(value)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddObject(key string, obj zapcore.ObjectMarshaler) error {
|
|
+ enc.addKey(key)
|
|
+ return enc.AppendObject(obj)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddReflected(key string, value interface{}) error {
|
|
+ enc.addKey(key)
|
|
+ return enc.AppendReflected(value)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddString(key, value string) {
|
|
+ enc.addKey(key)
|
|
+ enc.AppendString(value)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddTime(key string, value time.Time) {
|
|
+ enc.addKey(key)
|
|
+ enc.AppendTime(value)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AddUint(k string, v uint) { enc.AddUint64(k, uint64(v)) }
|
|
+func (enc *logfmtEncoder) AddUint8(k string, v uint8) { enc.AddUint64(k, uint64(v)) }
|
|
+func (enc *logfmtEncoder) AddUint32(k string, v uint32) { enc.AddUint64(k, uint64(v)) }
|
|
+func (enc *logfmtEncoder) AddUint16(k string, v uint16) { enc.AddUint64(k, uint64(v)) }
|
|
+func (enc *logfmtEncoder) AddUintptr(k string, v uintptr) { enc.AddUint64(k, uint64(v)) }
|
|
+func (enc *logfmtEncoder) AddUint64(key string, value uint64) {
|
|
+ enc.addKey(key)
|
|
+ enc.AppendUint64(value)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AppendArray(arr zapcore.ArrayMarshaler) error {
|
|
+ marshaler := enc.clone()
|
|
+ marshaler.namespaces = nil
|
|
+ marshaler.arrayLiteral = true
|
|
+
|
|
+ marshaler.buf.AppendByte('[')
|
|
+ err := arr.MarshalLogArray(marshaler)
|
|
+ if err == nil {
|
|
+ marshaler.buf.AppendByte(']')
|
|
+ enc.AppendByteString(marshaler.buf.Bytes())
|
|
+ } else {
|
|
+ enc.AppendByteString(nil)
|
|
+ }
|
|
+ marshaler.buf.Free()
|
|
+ putEncoder(marshaler)
|
|
+ return err
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AppendBool(value bool) {
|
|
+ if value {
|
|
+ enc.AppendString("true")
|
|
+ } else {
|
|
+ enc.AppendString("false")
|
|
+ }
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AppendByteString(value []byte) {
|
|
+ enc.addSeparator()
|
|
+
|
|
+ needsQuotes := bytes.IndexFunc(value, needsQuotedValueRune) != -1
|
|
+ if needsQuotes {
|
|
+ enc.buf.AppendByte('"')
|
|
+ }
|
|
+ enc.safeAddByteString(value)
|
|
+ if needsQuotes {
|
|
+ enc.buf.AppendByte('"')
|
|
+ }
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AppendComplex64(v complex64) { enc.AppendComplex128(complex128(v)) }
|
|
+func (enc *logfmtEncoder) AppendComplex128(value complex128) {
|
|
+ enc.addSeparator()
|
|
+
|
|
+ // Cast to a platform-independent, fixed-size type.
|
|
+ r, i := float64(real(value)), float64(imag(value))
|
|
+ enc.buf.AppendFloat(r, 64)
|
|
+ enc.buf.AppendByte('+')
|
|
+ enc.buf.AppendFloat(i, 64)
|
|
+ enc.buf.AppendByte('i')
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AppendDuration(value time.Duration) {
|
|
+ cur := enc.buf.Len()
|
|
+ if enc.EncodeDuration != nil {
|
|
+ enc.EncodeDuration(value, enc)
|
|
+ }
|
|
+ if cur == enc.buf.Len() {
|
|
+ enc.AppendInt64(int64(value))
|
|
+ }
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AppendFloat32(v float32) { enc.appendFloat(float64(v), 32) }
|
|
+func (enc *logfmtEncoder) AppendFloat64(v float64) { enc.appendFloat(v, 64) }
|
|
+func (enc *logfmtEncoder) appendFloat(val float64, bitSize int) {
|
|
+ enc.addSeparator()
|
|
+
|
|
+ switch {
|
|
+ case math.IsNaN(val):
|
|
+ enc.buf.AppendString(`NaN`)
|
|
+ case math.IsInf(val, 1):
|
|
+ enc.buf.AppendString(`+Inf`)
|
|
+ case math.IsInf(val, -1):
|
|
+ enc.buf.AppendString(`-Inf`)
|
|
+ default:
|
|
+ enc.buf.AppendFloat(val, bitSize)
|
|
+ }
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AppendInt(v int) { enc.AppendInt64(int64(v)) }
|
|
+func (enc *logfmtEncoder) AppendInt8(v int8) { enc.AppendInt64(int64(v)) }
|
|
+func (enc *logfmtEncoder) AppendInt16(v int16) { enc.AppendInt64(int64(v)) }
|
|
+func (enc *logfmtEncoder) AppendInt32(v int32) { enc.AppendInt64(int64(v)) }
|
|
+func (enc *logfmtEncoder) AppendInt64(value int64) {
|
|
+ enc.addSeparator()
|
|
+ enc.buf.AppendInt(value)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AppendObject(obj zapcore.ObjectMarshaler) error {
|
|
+ marshaler := enc.clone()
|
|
+ marshaler.namespaces = nil
|
|
+
|
|
+ err := obj.MarshalLogObject(marshaler)
|
|
+ if err == nil {
|
|
+ enc.AppendByteString(marshaler.buf.Bytes())
|
|
+ } else {
|
|
+ enc.AppendByteString(nil)
|
|
+ }
|
|
+ marshaler.buf.Free()
|
|
+ putEncoder(marshaler)
|
|
+ return err
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AppendReflected(value interface{}) error {
|
|
+ switch v := value.(type) {
|
|
+ case nil:
|
|
+ enc.AppendString("null")
|
|
+ case error:
|
|
+ enc.AppendString(v.Error())
|
|
+ case []byte:
|
|
+ enc.AppendByteString(v)
|
|
+ case fmt.Stringer:
|
|
+ enc.AppendString(v.String())
|
|
+ case encoding.TextMarshaler:
|
|
+ b, err := v.MarshalText()
|
|
+ if err != nil {
|
|
+ return err
|
|
+ }
|
|
+ enc.AppendString(string(b))
|
|
+ case json.Marshaler:
|
|
+ b, err := v.MarshalJSON()
|
|
+ if err != nil {
|
|
+ return err
|
|
+ }
|
|
+ enc.AppendString(string(b))
|
|
+ default:
|
|
+ rvalue := reflect.ValueOf(value)
|
|
+ switch rvalue.Kind() {
|
|
+ case reflect.Bool:
|
|
+ enc.AppendBool(rvalue.Bool())
|
|
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
+ enc.AppendInt64(rvalue.Int())
|
|
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
+ enc.AppendUint64(rvalue.Uint())
|
|
+ case reflect.Float32:
|
|
+ enc.appendFloat(rvalue.Float(), 32)
|
|
+ case reflect.Float64:
|
|
+ enc.AppendFloat64(rvalue.Float())
|
|
+ case reflect.String:
|
|
+ enc.AppendString(rvalue.String())
|
|
+ case reflect.Complex64, reflect.Complex128:
|
|
+ enc.AppendComplex128(rvalue.Complex())
|
|
+ case reflect.Chan, reflect.Func:
|
|
+ enc.AppendString(fmt.Sprintf("%T(%p)", value, value))
|
|
+ case reflect.Map, reflect.Struct:
|
|
+ enc.AppendString(fmt.Sprint(value))
|
|
+ case reflect.Array, reflect.Slice:
|
|
+ enc.AppendArray(zapcore.ArrayMarshalerFunc(func(ae zapcore.ArrayEncoder) error {
|
|
+ for i := 0; i < rvalue.Len(); i++ {
|
|
+ ae.AppendReflected(rvalue.Index(i).Interface())
|
|
+ }
|
|
+ return nil
|
|
+ }))
|
|
+ case reflect.Interface, reflect.Ptr:
|
|
+ return enc.AppendReflected(rvalue.Elem().Interface())
|
|
+ }
|
|
+ }
|
|
+ return nil
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AppendString(value string) {
|
|
+ enc.addSeparator()
|
|
+
|
|
+ needsQuotes := strings.IndexFunc(value, needsQuotedValueRune) != -1
|
|
+ if needsQuotes {
|
|
+ enc.buf.AppendByte('"')
|
|
+ }
|
|
+ enc.safeAddString(value)
|
|
+ if needsQuotes {
|
|
+ enc.buf.AppendByte('"')
|
|
+ }
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AppendTime(value time.Time) {
|
|
+ cur := enc.buf.Len()
|
|
+ if enc.EncodeTime != nil {
|
|
+ enc.EncodeTime(value, enc)
|
|
+ }
|
|
+ if cur == enc.buf.Len() {
|
|
+ enc.AppendInt64(value.UnixNano())
|
|
+ }
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) AppendUint(v uint) { enc.AppendUint64(uint64(v)) }
|
|
+func (enc *logfmtEncoder) AppendUint8(v uint8) { enc.AppendUint64(uint64(v)) }
|
|
+func (enc *logfmtEncoder) AppendUint16(v uint16) { enc.AppendUint64(uint64(v)) }
|
|
+func (enc *logfmtEncoder) AppendUint32(v uint32) { enc.AppendUint64(uint64(v)) }
|
|
+func (enc *logfmtEncoder) AppendUintptr(v uintptr) { enc.AppendUint64(uint64(v)) }
|
|
+func (enc *logfmtEncoder) AppendUint64(value uint64) {
|
|
+ enc.addSeparator()
|
|
+ enc.buf.AppendUint(value)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) Clone() zapcore.Encoder {
|
|
+ clone := enc.clone()
|
|
+ clone.buf.Write(enc.buf.Bytes())
|
|
+ return clone
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) clone() *logfmtEncoder {
|
|
+ clone := getEncoder()
|
|
+ clone.EncoderConfig = enc.EncoderConfig
|
|
+ clone.buf = bufferpool.Get()
|
|
+ clone.namespaces = enc.namespaces
|
|
+ return clone
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) OpenNamespace(key string) {
|
|
+ key = strings.Map(keyRuneFilter, key)
|
|
+ enc.namespaces = append(enc.namespaces, key)
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
|
|
+ final := enc.clone()
|
|
+ if final.TimeKey != "" {
|
|
+ final.AddTime(final.TimeKey, ent.Time)
|
|
+ }
|
|
+ if final.LevelKey != "" {
|
|
+ final.addKey(final.LevelKey)
|
|
+ cur := final.buf.Len()
|
|
+ if final.EncodeLevel != nil {
|
|
+ final.EncodeLevel(ent.Level, final)
|
|
+ }
|
|
+ if cur == final.buf.Len() {
|
|
+ // User-supplied EncodeLevel was a no-op. Fall back to strings to keep
|
|
+ // output valid.
|
|
+ final.AppendString(ent.Level.String())
|
|
+ }
|
|
+ }
|
|
+ if ent.LoggerName != "" && final.NameKey != "" {
|
|
+ final.addKey(final.NameKey)
|
|
+ cur := final.buf.Len()
|
|
+ if final.EncodeName != nil {
|
|
+ final.EncodeName(ent.LoggerName, final)
|
|
+ }
|
|
+ if cur == final.buf.Len() {
|
|
+ // User-supplied EncodeName was a no-op. Fall back to strings to
|
|
+ // keep output valid.
|
|
+ final.AppendString(ent.LoggerName)
|
|
+ }
|
|
+ }
|
|
+ if ent.Caller.Defined && final.CallerKey != "" {
|
|
+ final.addKey(final.CallerKey)
|
|
+ cur := final.buf.Len()
|
|
+ if final.EncodeCaller != nil {
|
|
+ final.EncodeCaller(ent.Caller, final)
|
|
+ }
|
|
+ if cur == final.buf.Len() {
|
|
+ // User-supplied EncodeCaller was a no-op. Fall back to strings to
|
|
+ // keep output valid.
|
|
+ final.AppendString(ent.Caller.String())
|
|
+ }
|
|
+ }
|
|
+ if final.MessageKey != "" {
|
|
+ final.addKey(enc.MessageKey)
|
|
+ final.AppendString(ent.Message)
|
|
+ }
|
|
+ if enc.buf.Len() > 0 {
|
|
+ if final.buf.Len() > 0 {
|
|
+ final.buf.AppendByte(' ')
|
|
+ }
|
|
+ final.buf.Write(enc.buf.Bytes())
|
|
+ }
|
|
+ addFields(final, fields)
|
|
+ if ent.Stack != "" && final.StacktraceKey != "" {
|
|
+ final.AddString(final.StacktraceKey, ent.Stack)
|
|
+ }
|
|
+ if final.LineEnding != "" {
|
|
+ final.buf.AppendString(final.LineEnding)
|
|
+ } else {
|
|
+ final.buf.AppendString(zapcore.DefaultLineEnding)
|
|
+ }
|
|
+
|
|
+ ret := final.buf
|
|
+ putEncoder(final)
|
|
+ return ret, nil
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) addSeparator() {
|
|
+ if !enc.arrayLiteral {
|
|
+ return
|
|
+ }
|
|
+
|
|
+ last := enc.buf.Len() - 1
|
|
+ if last >= 0 && enc.buf.Bytes()[last] != '[' {
|
|
+ enc.buf.AppendByte(',')
|
|
+ }
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) addKey(key string) {
|
|
+ key = strings.Map(keyRuneFilter, key)
|
|
+ if enc.buf.Len() > 0 {
|
|
+ enc.buf.AppendByte(' ')
|
|
+ }
|
|
+ for _, ns := range enc.namespaces {
|
|
+ enc.safeAddString(ns)
|
|
+ enc.buf.AppendByte('.')
|
|
+ }
|
|
+ enc.safeAddString(key)
|
|
+ enc.buf.AppendByte('=')
|
|
+}
|
|
+
|
|
+// safeAddString JSON-escapes a string and appends it to the internal buffer.
|
|
+// Unlike the standard library's encoder, it doesn't attempt to protect the
|
|
+// user from browser vulnerabilities or JSONP-related problems.
|
|
+func (enc *logfmtEncoder) safeAddString(s string) {
|
|
+ for i := 0; i < len(s); {
|
|
+ if enc.tryAddRuneSelf(s[i]) {
|
|
+ i++
|
|
+ continue
|
|
+ }
|
|
+ r, size := utf8.DecodeRuneInString(s[i:])
|
|
+ if enc.tryAddRuneError(r, size) {
|
|
+ i++
|
|
+ continue
|
|
+ }
|
|
+ enc.buf.AppendString(s[i : i+size])
|
|
+ i += size
|
|
+ }
|
|
+}
|
|
+
|
|
+// safeAddByteString is no-alloc equivalent of safeAddString(string(s)) for s []byte.
|
|
+func (enc *logfmtEncoder) safeAddByteString(s []byte) {
|
|
+ for i := 0; i < len(s); {
|
|
+ if enc.tryAddRuneSelf(s[i]) {
|
|
+ i++
|
|
+ continue
|
|
+ }
|
|
+ r, size := utf8.DecodeRune(s[i:])
|
|
+ if enc.tryAddRuneError(r, size) {
|
|
+ i++
|
|
+ continue
|
|
+ }
|
|
+ enc.buf.Write(s[i : i+size])
|
|
+ i += size
|
|
+ }
|
|
+}
|
|
+
|
|
+// tryAddRuneSelf appends b if it is valid UTF-8 character represented in a single byte.
|
|
+func (enc *logfmtEncoder) tryAddRuneSelf(b byte) bool {
|
|
+ if b >= utf8.RuneSelf {
|
|
+ return false
|
|
+ }
|
|
+ if 0x20 <= b && b != '\\' && b != '"' {
|
|
+ enc.buf.AppendByte(b)
|
|
+ return true
|
|
+ }
|
|
+ switch b {
|
|
+ case '\\', '"':
|
|
+ enc.buf.AppendByte('\\')
|
|
+ enc.buf.AppendByte(b)
|
|
+ case '\n':
|
|
+ enc.buf.AppendByte('\\')
|
|
+ enc.buf.AppendByte('n')
|
|
+ case '\r':
|
|
+ enc.buf.AppendByte('\\')
|
|
+ enc.buf.AppendByte('r')
|
|
+ case '\t':
|
|
+ enc.buf.AppendByte('\\')
|
|
+ enc.buf.AppendByte('t')
|
|
+ default:
|
|
+ // Encode bytes < 0x20, except for the escape sequences above.
|
|
+ const _hex = "0123456789abcdef"
|
|
+ enc.buf.AppendString(`\u00`)
|
|
+ enc.buf.AppendByte(_hex[b>>4])
|
|
+ enc.buf.AppendByte(_hex[b&0xF])
|
|
+ }
|
|
+ return true
|
|
+}
|
|
+
|
|
+func (enc *logfmtEncoder) tryAddRuneError(r rune, size int) bool {
|
|
+ if r == utf8.RuneError && size == 1 {
|
|
+ enc.buf.AppendString(`\ufffd`)
|
|
+ return true
|
|
+ }
|
|
+ return false
|
|
+}
|
|
+
|
|
+func needsQuotedValueRune(r rune) bool {
|
|
+ return r <= ' ' || r == '=' || r == '"' || r == utf8.RuneError
|
|
+}
|
|
+
|
|
+func keyRuneFilter(r rune) rune {
|
|
+ if needsQuotedValueRune(r) {
|
|
+ return -1
|
|
+ }
|
|
+ return r
|
|
+}
|
|
+
|
|
+func addFields(enc zapcore.ObjectEncoder, fields []zapcore.Field) {
|
|
+ for i := range fields {
|
|
+ fields[i].AddTo(enc)
|
|
+ }
|
|
+}
|
|
diff --git a/vendor/modules.txt b/vendor/modules.txt
|
|
index c6048c9..67935ef 100644
|
|
--- a/vendor/modules.txt
|
|
+++ b/vendor/modules.txt
|
|
@@ -245,6 +245,9 @@ github.com/spf13/pflag
|
|
## explicit; go 1.13
|
|
github.com/stretchr/testify/assert
|
|
github.com/stretchr/testify/require
|
|
+# github.com/sykesm/zap-logfmt v0.0.4
|
|
+## explicit; go 1.13
|
|
+github.com/sykesm/zap-logfmt
|
|
# github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca
|
|
## explicit
|
|
github.com/xlab/treeprint
|
|
--
|
|
2.34.1
|
|
|