Upgrade k8s package verison (#5358)

* upgrade k8s package version

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>

* Script upgrade and code formatting.

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
This commit is contained in:
hongzhouzi
2022-11-15 14:56:38 +08:00
committed by GitHub
parent 5f91c1663a
commit 44167aa47a
3106 changed files with 321340 additions and 172080 deletions

188
vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go generated vendored Normal file
View File

@@ -0,0 +1,188 @@
// Copyright (c) 2021 Uber Technologies, Inc.
//
// 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.
package zapcore
import (
"bufio"
"sync"
"time"
"go.uber.org/multierr"
)
const (
// _defaultBufferSize specifies the default size used by Buffer.
_defaultBufferSize = 256 * 1024 // 256 kB
// _defaultFlushInterval specifies the default flush interval for
// Buffer.
_defaultFlushInterval = 30 * time.Second
)
// A BufferedWriteSyncer is a WriteSyncer that buffers writes in-memory before
// flushing them to a wrapped WriteSyncer after reaching some limit, or at some
// fixed interval--whichever comes first.
//
// BufferedWriteSyncer is safe for concurrent use. You don't need to use
// zapcore.Lock for WriteSyncers with BufferedWriteSyncer.
type BufferedWriteSyncer struct {
// WS is the WriteSyncer around which BufferedWriteSyncer will buffer
// writes.
//
// This field is required.
WS WriteSyncer
// Size specifies the maximum amount of data the writer will buffered
// before flushing.
//
// Defaults to 256 kB if unspecified.
Size int
// FlushInterval specifies how often the writer should flush data if
// there have been no writes.
//
// Defaults to 30 seconds if unspecified.
FlushInterval time.Duration
// Clock, if specified, provides control of the source of time for the
// writer.
//
// Defaults to the system clock.
Clock Clock
// unexported fields for state
mu sync.Mutex
initialized bool // whether initialize() has run
stopped bool // whether Stop() has run
writer *bufio.Writer
ticker *time.Ticker
stop chan struct{} // closed when flushLoop should stop
done chan struct{} // closed when flushLoop has stopped
}
func (s *BufferedWriteSyncer) initialize() {
size := s.Size
if size == 0 {
size = _defaultBufferSize
}
flushInterval := s.FlushInterval
if flushInterval == 0 {
flushInterval = _defaultFlushInterval
}
if s.Clock == nil {
s.Clock = DefaultClock
}
s.ticker = s.Clock.NewTicker(flushInterval)
s.writer = bufio.NewWriterSize(s.WS, size)
s.stop = make(chan struct{})
s.done = make(chan struct{})
s.initialized = true
go s.flushLoop()
}
// Write writes log data into buffer syncer directly, multiple Write calls will be batched,
// and log data will be flushed to disk when the buffer is full or periodically.
func (s *BufferedWriteSyncer) Write(bs []byte) (int, error) {
s.mu.Lock()
defer s.mu.Unlock()
if !s.initialized {
s.initialize()
}
// To avoid partial writes from being flushed, we manually flush the existing buffer if:
// * The current write doesn't fit into the buffer fully, and
// * The buffer is not empty (since bufio will not split large writes when the buffer is empty)
if len(bs) > s.writer.Available() && s.writer.Buffered() > 0 {
if err := s.writer.Flush(); err != nil {
return 0, err
}
}
return s.writer.Write(bs)
}
// Sync flushes buffered log data into disk directly.
func (s *BufferedWriteSyncer) Sync() error {
s.mu.Lock()
defer s.mu.Unlock()
var err error
if s.initialized {
err = s.writer.Flush()
}
return multierr.Append(err, s.WS.Sync())
}
// flushLoop flushes the buffer at the configured interval until Stop is
// called.
func (s *BufferedWriteSyncer) flushLoop() {
defer close(s.done)
for {
select {
case <-s.ticker.C:
// we just simply ignore error here
// because the underlying bufio writer stores any errors
// and we return any error from Sync() as part of the close
_ = s.Sync()
case <-s.stop:
return
}
}
}
// Stop closes the buffer, cleans up background goroutines, and flushes
// remaining unwritten data.
func (s *BufferedWriteSyncer) Stop() (err error) {
var stopped bool
// Critical section.
func() {
s.mu.Lock()
defer s.mu.Unlock()
if !s.initialized {
return
}
stopped = s.stopped
if stopped {
return
}
s.stopped = true
s.ticker.Stop()
close(s.stop) // tell flushLoop to stop
<-s.done // and wait until it has
}()
// Don't call Sync on consecutive Stops.
if !stopped {
err = s.Sync()
}
return err
}

50
vendor/go.uber.org/zap/zapcore/clock.go generated vendored Normal file
View File

@@ -0,0 +1,50 @@
// Copyright (c) 2021 Uber Technologies, Inc.
//
// 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.
package zapcore
import (
"time"
)
// DefaultClock is the default clock used by Zap in operations that require
// time. This clock uses the system clock for all operations.
var DefaultClock = systemClock{}
// Clock is a source of time for logged entries.
type Clock interface {
// Now returns the current local time.
Now() time.Time
// NewTicker returns *time.Ticker that holds a channel
// that delivers "ticks" of a clock.
NewTicker(time.Duration) *time.Ticker
}
// systemClock implements default Clock that uses system time.
type systemClock struct{}
func (systemClock) Now() time.Time {
return time.Now()
}
func (systemClock) NewTicker(duration time.Duration) *time.Ticker {
return time.NewTicker(duration)
}

View File

@@ -56,6 +56,10 @@ type consoleEncoder struct {
// encoder configuration, it will omit any element whose key is set to the empty
// string.
func NewConsoleEncoder(cfg EncoderConfig) Encoder {
if cfg.ConsoleSeparator == "" {
// Use a default delimiter of '\t' for backwards compatibility
cfg.ConsoleSeparator = "\t"
}
return consoleEncoder{newJSONEncoder(cfg, true)}
}
@@ -89,12 +93,17 @@ func (c consoleEncoder) EncodeEntry(ent Entry, fields []Field) (*buffer.Buffer,
nameEncoder(ent.LoggerName, arr)
}
if ent.Caller.Defined && c.CallerKey != "" && c.EncodeCaller != nil {
c.EncodeCaller(ent.Caller, arr)
if ent.Caller.Defined {
if c.CallerKey != "" && c.EncodeCaller != nil {
c.EncodeCaller(ent.Caller, arr)
}
if c.FunctionKey != "" {
arr.AppendString(ent.Caller.Function)
}
}
for i := range arr.elems {
if i > 0 {
line.AppendByte('\t')
line.AppendString(c.ConsoleSeparator)
}
fmt.Fprint(line, arr.elems[i])
}
@@ -102,7 +111,7 @@ func (c consoleEncoder) EncodeEntry(ent Entry, fields []Field) (*buffer.Buffer,
// Add the message itself.
if c.MessageKey != "" {
c.addTabIfNecessary(line)
c.addSeparatorIfNecessary(line)
line.AppendString(ent.Message)
}
@@ -126,7 +135,12 @@ func (c consoleEncoder) EncodeEntry(ent Entry, fields []Field) (*buffer.Buffer,
func (c consoleEncoder) writeContext(line *buffer.Buffer, extra []Field) {
context := c.jsonEncoder.Clone().(*jsonEncoder)
defer context.buf.Free()
defer func() {
// putJSONEncoder assumes the buffer is still used, but we write out the buffer so
// we can free it.
context.buf.Free()
putJSONEncoder(context)
}()
addFields(context, extra)
context.closeOpenNamespaces()
@@ -134,14 +148,14 @@ func (c consoleEncoder) writeContext(line *buffer.Buffer, extra []Field) {
return
}
c.addTabIfNecessary(line)
c.addSeparatorIfNecessary(line)
line.AppendByte('{')
line.Write(context.buf.Bytes())
line.AppendByte('}')
}
func (c consoleEncoder) addTabIfNecessary(line *buffer.Buffer) {
func (c consoleEncoder) addSeparatorIfNecessary(line *buffer.Buffer) {
if line.Len() > 0 {
line.AppendByte('\t')
line.AppendString(c.ConsoleSeparator)
}
}

View File

@@ -21,6 +21,7 @@
package zapcore
import (
"encoding/json"
"time"
"go.uber.org/zap/buffer"
@@ -112,21 +113,51 @@ func EpochNanosTimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
enc.AppendInt64(t.UnixNano())
}
func encodeTimeLayout(t time.Time, layout string, enc PrimitiveArrayEncoder) {
type appendTimeEncoder interface {
AppendTimeLayout(time.Time, string)
}
if enc, ok := enc.(appendTimeEncoder); ok {
enc.AppendTimeLayout(t, layout)
return
}
enc.AppendString(t.Format(layout))
}
// ISO8601TimeEncoder serializes a time.Time to an ISO8601-formatted string
// with millisecond precision.
//
// If enc supports AppendTimeLayout(t time.Time,layout string), it's used
// instead of appending a pre-formatted string value.
func ISO8601TimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006-01-02T15:04:05.000Z0700"))
encodeTimeLayout(t, "2006-01-02T15:04:05.000Z0700", enc)
}
// RFC3339TimeEncoder serializes a time.Time to an RFC3339-formatted string.
//
// If enc supports AppendTimeLayout(t time.Time,layout string), it's used
// instead of appending a pre-formatted string value.
func RFC3339TimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
enc.AppendString(t.Format(time.RFC3339))
encodeTimeLayout(t, time.RFC3339, enc)
}
// RFC3339NanoTimeEncoder serializes a time.Time to an RFC3339-formatted string
// with nanosecond precision.
//
// If enc supports AppendTimeLayout(t time.Time,layout string), it's used
// instead of appending a pre-formatted string value.
func RFC3339NanoTimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
enc.AppendString(t.Format(time.RFC3339Nano))
encodeTimeLayout(t, time.RFC3339Nano, enc)
}
// TimeEncoderOfLayout returns TimeEncoder which serializes a time.Time using
// given layout.
func TimeEncoderOfLayout(layout string) TimeEncoder {
return func(t time.Time, enc PrimitiveArrayEncoder) {
encodeTimeLayout(t, layout, enc)
}
}
// UnmarshalText unmarshals text to a TimeEncoder.
@@ -154,6 +185,35 @@ func (e *TimeEncoder) UnmarshalText(text []byte) error {
return nil
}
// UnmarshalYAML unmarshals YAML to a TimeEncoder.
// If value is an object with a "layout" field, it will be unmarshaled to TimeEncoder with given layout.
// timeEncoder:
// layout: 06/01/02 03:04pm
// If value is string, it uses UnmarshalText.
// timeEncoder: iso8601
func (e *TimeEncoder) UnmarshalYAML(unmarshal func(interface{}) error) error {
var o struct {
Layout string `json:"layout" yaml:"layout"`
}
if err := unmarshal(&o); err == nil {
*e = TimeEncoderOfLayout(o.Layout)
return nil
}
var s string
if err := unmarshal(&s); err != nil {
return err
}
return e.UnmarshalText([]byte(s))
}
// UnmarshalJSON unmarshals JSON to a TimeEncoder as same way UnmarshalYAML does.
func (e *TimeEncoder) UnmarshalJSON(data []byte) error {
return e.UnmarshalYAML(func(v interface{}) error {
return json.Unmarshal(data, v)
})
}
// A DurationEncoder serializes a time.Duration to a primitive type.
type DurationEncoder func(time.Duration, PrimitiveArrayEncoder)
@@ -168,6 +228,12 @@ func NanosDurationEncoder(d time.Duration, enc PrimitiveArrayEncoder) {
enc.AppendInt64(int64(d))
}
// MillisDurationEncoder serializes a time.Duration to an integer number of
// milliseconds elapsed.
func MillisDurationEncoder(d time.Duration, enc PrimitiveArrayEncoder) {
enc.AppendInt64(d.Nanoseconds() / 1e6)
}
// StringDurationEncoder serializes a time.Duration using its built-in String
// method.
func StringDurationEncoder(d time.Duration, enc PrimitiveArrayEncoder) {
@@ -183,6 +249,8 @@ func (e *DurationEncoder) UnmarshalText(text []byte) error {
*e = StringDurationEncoder
case "nanos":
*e = NanosDurationEncoder
case "ms":
*e = MillisDurationEncoder
default:
*e = SecondsDurationEncoder
}
@@ -249,6 +317,7 @@ type EncoderConfig struct {
TimeKey string `json:"timeKey" yaml:"timeKey"`
NameKey string `json:"nameKey" yaml:"nameKey"`
CallerKey string `json:"callerKey" yaml:"callerKey"`
FunctionKey string `json:"functionKey" yaml:"functionKey"`
StacktraceKey string `json:"stacktraceKey" yaml:"stacktraceKey"`
LineEnding string `json:"lineEnding" yaml:"lineEnding"`
// Configure the primitive representations of common complex types. For
@@ -261,6 +330,9 @@ type EncoderConfig struct {
// Unlike the other primitive type encoders, EncodeName is optional. The
// zero value falls back to FullNameEncoder.
EncodeName NameEncoder `json:"nameEncoder" yaml:"nameEncoder"`
// Configures the field separator used by the console encoder. Defaults
// to tab.
ConsoleSeparator string `json:"consoleSeparator" yaml:"consoleSeparator"`
}
// ObjectEncoder is a strongly-typed, encoding-agnostic interface for adding a

View File

@@ -22,6 +22,7 @@ package zapcore
import (
"fmt"
"runtime"
"strings"
"sync"
"time"
@@ -70,10 +71,11 @@ func NewEntryCaller(pc uintptr, file string, line int, ok bool) EntryCaller {
// EntryCaller represents the caller of a logging function.
type EntryCaller struct {
Defined bool
PC uintptr
File string
Line int
Defined bool
PC uintptr
File string
Line int
Function string
}
// String returns the full path and line number of the caller.
@@ -158,6 +160,8 @@ const (
// WriteThenNoop indicates that nothing special needs to be done. It's the
// default behavior.
WriteThenNoop CheckWriteAction = iota
// WriteThenGoexit runs runtime.Goexit after Write.
WriteThenGoexit
// WriteThenPanic causes a panic after Write.
WriteThenPanic
// WriteThenFatal causes a fatal os.Exit after Write.
@@ -204,7 +208,7 @@ func (ce *CheckedEntry) Write(fields ...Field) {
// If the entry is dirty, log an internal error; because the
// CheckedEntry is being used after it was returned to the pool,
// the message may be an amalgamation from multiple call sites.
fmt.Fprintf(ce.ErrorOutput, "%v Unsafe CheckedEntry re-use near Entry %+v.\n", time.Now(), ce.Entry)
fmt.Fprintf(ce.ErrorOutput, "%v Unsafe CheckedEntry re-use near Entry %+v.\n", ce.Time, ce.Entry)
ce.ErrorOutput.Sync()
}
return
@@ -215,11 +219,9 @@ func (ce *CheckedEntry) Write(fields ...Field) {
for i := range ce.cores {
err = multierr.Append(err, ce.cores[i].Write(ce.Entry, fields))
}
if ce.ErrorOutput != nil {
if err != nil {
fmt.Fprintf(ce.ErrorOutput, "%v write error: %v\n", time.Now(), err)
ce.ErrorOutput.Sync()
}
if err != nil && ce.ErrorOutput != nil {
fmt.Fprintf(ce.ErrorOutput, "%v write error: %v\n", ce.Time, err)
ce.ErrorOutput.Sync()
}
should, msg := ce.should, ce.Message
@@ -230,6 +232,8 @@ func (ce *CheckedEntry) Write(fields ...Field) {
panic(msg)
case WriteThenFatal:
exit.Exit()
case WriteThenGoexit:
runtime.Goexit()
}
}

View File

@@ -22,6 +22,7 @@ package zapcore
import (
"fmt"
"reflect"
"sync"
)
@@ -42,7 +43,23 @@ import (
// ...
// ],
// }
func encodeError(key string, err error, enc ObjectEncoder) error {
func encodeError(key string, err error, enc ObjectEncoder) (retErr error) {
// Try to capture panics (from nil references or otherwise) when calling
// the Error() method
defer func() {
if rerr := recover(); rerr != nil {
// If it's a nil pointer, just say "<nil>". The likeliest causes are a
// error that fails to guard against nil or a nil pointer for a
// value receiver, and in either case, "<nil>" is a nice result.
if v := reflect.ValueOf(err); v.Kind() == reflect.Ptr && v.IsNil() {
enc.AddString(key, "<nil>")
return
}
retErr = fmt.Errorf("PANIC=%v", rerr)
}
}()
basic := err.Error()
enc.AddString(key, basic)
@@ -66,12 +83,7 @@ type errorGroup interface {
Errors() []error
}
type causer interface {
// Provides access to the error that caused this error.
Cause() error
}
// Note that errArry and errArrayElem are very similar to the version
// Note that errArray and errArrayElem are very similar to the version
// implemented in the top-level error.go file. We can't re-use this because
// that would require exporting errArray as part of the zapcore API.

View File

@@ -65,8 +65,11 @@ const (
Int8Type
// StringType indicates that the field carries a string.
StringType
// TimeType indicates that the field carries a time.Time.
// TimeType indicates that the field carries a time.Time that is
// representable by a UnixNano() stored as an int64.
TimeType
// TimeFullType indicates that the field carries a time.Time stored as-is.
TimeFullType
// Uint64Type indicates that the field carries a uint64.
Uint64Type
// Uint32Type indicates that the field carries a uint32.
@@ -89,6 +92,10 @@ const (
ErrorType
// SkipType indicates that the field is a no-op.
SkipType
// InlineMarshalerType indicates that the field carries an ObjectMarshaler
// that should be inlined.
InlineMarshalerType
)
// A Field is a marshaling operation used to add a key-value pair to a logger's
@@ -112,6 +119,8 @@ func (f Field) AddTo(enc ObjectEncoder) {
err = enc.AddArray(f.Key, f.Interface.(ArrayMarshaler))
case ObjectMarshalerType:
err = enc.AddObject(f.Key, f.Interface.(ObjectMarshaler))
case InlineMarshalerType:
err = f.Interface.(ObjectMarshaler).MarshalLogObject(enc)
case BinaryType:
enc.AddBinary(f.Key, f.Interface.([]byte))
case BoolType:
@@ -145,6 +154,8 @@ func (f Field) AddTo(enc ObjectEncoder) {
// Fall back to UTC if location is nil.
enc.AddTime(f.Key, time.Unix(0, f.Integer))
}
case TimeFullType:
enc.AddTime(f.Key, f.Interface.(time.Time))
case Uint64Type:
enc.AddUint64(f.Key, uint64(f.Integer))
case Uint32Type:
@@ -162,7 +173,7 @@ func (f Field) AddTo(enc ObjectEncoder) {
case StringerType:
err = encodeStringer(f.Key, f.Interface, enc)
case ErrorType:
encodeError(f.Key, f.Interface.(error), enc)
err = encodeError(f.Key, f.Interface.(error), enc)
case SkipType:
break
default:
@@ -200,13 +211,23 @@ func addFields(enc ObjectEncoder, fields []Field) {
}
}
func encodeStringer(key string, stringer interface{}, enc ObjectEncoder) (err error) {
func encodeStringer(key string, stringer interface{}, enc ObjectEncoder) (retErr error) {
// Try to capture panics (from nil references or otherwise) when calling
// the String() method, similar to https://golang.org/src/fmt/print.go#L540
defer func() {
if v := recover(); v != nil {
err = fmt.Errorf("PANIC=%v", v)
if err := recover(); err != nil {
// If it's a nil pointer, just say "<nil>". The likeliest causes are a
// Stringer that fails to guard against nil or a nil pointer for a
// value receiver, and in either case, "<nil>" is a nice result.
if v := reflect.ValueOf(stringer); v.Kind() == reflect.Ptr && v.IsNil() {
enc.AddString(key, "<nil>")
return
}
retErr = fmt.Errorf("PANIC=%v", err)
}
}()
enc.AddString(key, stringer.(fmt.Stringer).String())
return
return nil
}

66
vendor/go.uber.org/zap/zapcore/increase_level.go generated vendored Normal file
View File

@@ -0,0 +1,66 @@
// Copyright (c) 2020 Uber Technologies, Inc.
//
// 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.
package zapcore
import "fmt"
type levelFilterCore struct {
core Core
level LevelEnabler
}
// NewIncreaseLevelCore creates a core that can be used to increase the level of
// an existing Core. It cannot be used to decrease the logging level, as it acts
// as a filter before calling the underlying core. If level decreases the log level,
// an error is returned.
func NewIncreaseLevelCore(core Core, level LevelEnabler) (Core, error) {
for l := _maxLevel; l >= _minLevel; l-- {
if !core.Enabled(l) && level.Enabled(l) {
return nil, fmt.Errorf("invalid increase level, as level %q is allowed by increased level, but not by existing core", l)
}
}
return &levelFilterCore{core, level}, nil
}
func (c *levelFilterCore) Enabled(lvl Level) bool {
return c.level.Enabled(lvl)
}
func (c *levelFilterCore) With(fields []Field) Core {
return &levelFilterCore{c.core.With(fields), c.level}
}
func (c *levelFilterCore) Check(ent Entry, ce *CheckedEntry) *CheckedEntry {
if !c.Enabled(ent.Level) {
return ce
}
return c.core.Check(ent, ce)
}
func (c *levelFilterCore) Write(ent Entry, fields []Field) error {
return c.core.Write(ent, fields)
}
func (c *levelFilterCore) Sync() error {
return c.core.Sync()
}

View File

@@ -128,6 +128,11 @@ func (enc *jsonEncoder) AddFloat64(key string, val float64) {
enc.AppendFloat64(val)
}
func (enc *jsonEncoder) AddFloat32(key string, val float32) {
enc.addKey(key)
enc.AppendFloat32(val)
}
func (enc *jsonEncoder) AddInt64(key string, val int64) {
enc.addKey(key)
enc.AppendInt64(val)
@@ -228,7 +233,11 @@ func (enc *jsonEncoder) AppendComplex128(val complex128) {
// Because we're always in a quoted string, we can use strconv without
// special-casing NaN and +/-Inf.
enc.buf.AppendFloat(r, 64)
enc.buf.AppendByte('+')
// If imaginary part is less than 0, minus (-) sign is added by default
// by AppendFloat.
if i >= 0 {
enc.buf.AppendByte('+')
}
enc.buf.AppendFloat(i, 64)
enc.buf.AppendByte('i')
enc.buf.AppendByte('"')
@@ -236,7 +245,9 @@ func (enc *jsonEncoder) AppendComplex128(val complex128) {
func (enc *jsonEncoder) AppendDuration(val time.Duration) {
cur := enc.buf.Len()
enc.EncodeDuration(val, enc)
if e := enc.EncodeDuration; e != nil {
e(val, enc)
}
if cur == enc.buf.Len() {
// User-supplied EncodeDuration is a no-op. Fall back to nanoseconds to keep
// JSON valid.
@@ -266,9 +277,18 @@ func (enc *jsonEncoder) AppendString(val string) {
enc.buf.AppendByte('"')
}
func (enc *jsonEncoder) AppendTimeLayout(time time.Time, layout string) {
enc.addElementSeparator()
enc.buf.AppendByte('"')
enc.buf.AppendTime(time, layout)
enc.buf.AppendByte('"')
}
func (enc *jsonEncoder) AppendTime(val time.Time) {
cur := enc.buf.Len()
enc.EncodeTime(val, enc)
if e := enc.EncodeTime; e != nil {
e(val, enc)
}
if cur == enc.buf.Len() {
// User-supplied EncodeTime is a no-op. Fall back to nanos since epoch to keep
// output JSON valid.
@@ -282,7 +302,6 @@ func (enc *jsonEncoder) AppendUint64(val uint64) {
}
func (enc *jsonEncoder) AddComplex64(k string, v complex64) { enc.AddComplex128(k, complex128(v)) }
func (enc *jsonEncoder) AddFloat32(k string, v float32) { enc.AddFloat64(k, float64(v)) }
func (enc *jsonEncoder) AddInt(k string, v int) { enc.AddInt64(k, int64(v)) }
func (enc *jsonEncoder) AddInt32(k string, v int32) { enc.AddInt64(k, int64(v)) }
func (enc *jsonEncoder) AddInt16(k string, v int16) { enc.AddInt64(k, int64(v)) }
@@ -355,14 +374,20 @@ func (enc *jsonEncoder) EncodeEntry(ent Entry, fields []Field) (*buffer.Buffer,
final.AppendString(ent.LoggerName)
}
}
if ent.Caller.Defined && final.CallerKey != "" {
final.addKey(final.CallerKey)
cur := final.buf.Len()
final.EncodeCaller(ent.Caller, final)
if cur == final.buf.Len() {
// User-supplied EncodeCaller was a no-op. Fall back to strings to
// keep output JSON valid.
final.AppendString(ent.Caller.String())
if ent.Caller.Defined {
if final.CallerKey != "" {
final.addKey(final.CallerKey)
cur := final.buf.Len()
final.EncodeCaller(ent.Caller, final)
if cur == final.buf.Len() {
// User-supplied EncodeCaller was a no-op. Fall back to strings to
// keep output JSON valid.
final.AppendString(ent.Caller.String())
}
}
if final.FunctionKey != "" {
final.addKey(final.FunctionKey)
final.AppendString(ent.Caller.Function)
}
}
if final.MessageKey != "" {

View File

@@ -23,6 +23,10 @@ package zapcore
// 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).
//
// Note: ObjectMarshaler is only used when zap.Object is used or when
// passed directly to zap.Any. It is not used when reflection-based
// encoding is used.
type ObjectMarshaler interface {
MarshalLogObject(ObjectEncoder) error
}
@@ -39,6 +43,10 @@ func (f ObjectMarshalerFunc) MarshalLogObject(enc ObjectEncoder) error {
// 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).
//
// Note: ArrayMarshaler is only used when zap.Array is used or when
// passed directly to zap.Any. It is not used when reflection-based
// encoding is used.
type ArrayMarshaler interface {
MarshalLogArray(ArrayEncoder) error
}

View File

@@ -81,17 +81,92 @@ func (c *counter) IncCheckReset(t time.Time, tick time.Duration) uint64 {
return 1
}
// SamplingDecision is a decision represented as a bit field made by sampler.
// More decisions may be added in the future.
type SamplingDecision uint32
const (
// LogDropped indicates that the Sampler dropped a log entry.
LogDropped SamplingDecision = 1 << iota
// LogSampled indicates that the Sampler sampled a log entry.
LogSampled
)
// optionFunc wraps a func so it satisfies the SamplerOption interface.
type optionFunc func(*sampler)
func (f optionFunc) apply(s *sampler) {
f(s)
}
// SamplerOption configures a Sampler.
type SamplerOption interface {
apply(*sampler)
}
// nopSamplingHook is the default hook used by sampler.
func nopSamplingHook(Entry, SamplingDecision) {}
// SamplerHook registers a function which will be called when Sampler makes a
// decision.
//
// This hook may be used to get visibility into the performance of the sampler.
// For example, use it to track metrics of dropped versus sampled logs.
//
// var dropped atomic.Int64
// zapcore.SamplerHook(func(ent zapcore.Entry, dec zapcore.SamplingDecision) {
// if dec&zapcore.LogDropped > 0 {
// dropped.Inc()
// }
// })
func SamplerHook(hook func(entry Entry, dec SamplingDecision)) SamplerOption {
return optionFunc(func(s *sampler) {
s.hook = hook
})
}
// NewSamplerWithOptions creates a Core that samples incoming entries, which
// caps the CPU and I/O load of logging while attempting to preserve a
// representative subset of your logs.
//
// Zap samples by logging the first N entries with a given level and message
// each tick. If more Entries with the same level and message are seen during
// the same interval, every Mth message is logged and the rest are dropped.
//
// Sampler can be configured to report sampling decisions with the SamplerHook
// option.
//
// Keep in mind that zap's sampling implementation is optimized for speed over
// absolute precision; under load, each tick may be slightly over- or
// under-sampled.
func NewSamplerWithOptions(core Core, tick time.Duration, first, thereafter int, opts ...SamplerOption) Core {
s := &sampler{
Core: core,
tick: tick,
counts: newCounters(),
first: uint64(first),
thereafter: uint64(thereafter),
hook: nopSamplingHook,
}
for _, opt := range opts {
opt.apply(s)
}
return s
}
type sampler struct {
Core
counts *counters
tick time.Duration
first, thereafter uint64
hook func(Entry, SamplingDecision)
}
// NewSampler creates a Core that samples incoming entries, which caps the CPU
// and I/O load of logging while attempting to preserve a representative subset
// of your logs.
// NewSampler creates a Core that samples incoming entries, which
// caps the CPU and I/O load of logging while attempting to preserve a
// representative subset of your logs.
//
// Zap samples by logging the first N entries with a given level and message
// each tick. If more Entries with the same level and message are seen during
@@ -100,14 +175,10 @@ type sampler struct {
// Keep in mind that zap's sampling implementation is optimized for speed over
// absolute precision; under load, each tick may be slightly over- or
// under-sampled.
//
// Deprecated: use NewSamplerWithOptions.
func NewSampler(core Core, tick time.Duration, first, thereafter int) Core {
return &sampler{
Core: core,
tick: tick,
counts: newCounters(),
first: uint64(first),
thereafter: uint64(thereafter),
}
return NewSamplerWithOptions(core, tick, first, thereafter)
}
func (s *sampler) With(fields []Field) Core {
@@ -117,6 +188,7 @@ func (s *sampler) With(fields []Field) Core {
counts: s.counts,
first: s.first,
thereafter: s.thereafter,
hook: s.hook,
}
}
@@ -125,10 +197,14 @@ func (s *sampler) Check(ent Entry, ce *CheckedEntry) *CheckedEntry {
return ce
}
counter := s.counts.get(ent.Level, ent.Message)
n := counter.IncCheckReset(ent.Time, s.tick)
if n > s.first && (n-s.first)%s.thereafter != 0 {
return ce
if ent.Level >= _minLevel && ent.Level <= _maxLevel {
counter := s.counts.get(ent.Level, ent.Message)
n := counter.IncCheckReset(ent.Time, s.tick)
if n > s.first && (n-s.first)%s.thereafter != 0 {
s.hook(ent, LogDropped)
return ce
}
s.hook(ent, LogSampled)
}
return s.Core.Check(ent, ce)
}

View File

@@ -91,8 +91,7 @@ func NewMultiWriteSyncer(ws ...WriteSyncer) WriteSyncer {
if len(ws) == 1 {
return ws[0]
}
// Copy to protect against https://github.com/golang/go/issues/7809
return multiWriteSyncer(append([]WriteSyncer(nil), ws...))
return multiWriteSyncer(ws)
}
// See https://golang.org/src/io/multi.go