From 7eac6bd4976b66c29230c0d88643e037bde5b4bd Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 11 Aug 2020 20:55:29 -0700 Subject: [PATCH] *: upgrade zap logger to 1.15, replace global logger Signed-off-by: Gyuho Lee --- embed/config_logging.go | 2 + etcdserver/api/membership/cluster_test.go | 3 +- etcdserver/api/membership/downgrade_test.go | 7 +- etcdserver/api/snap/snapshotter_test.go | 3 +- go.mod | 2 +- go.sum | 6 +- integration/embed/embed_test.go | 2 +- integration/v3_barrier_test.go | 2 +- integration/v3_double_barrier_test.go | 2 +- integration/v3_queue_test.go | 2 +- vendor/go.uber.org/zap/.travis.yml | 2 +- vendor/go.uber.org/zap/CHANGELOG.md | 20 ++++ vendor/go.uber.org/zap/config.go | 24 ++++- vendor/go.uber.org/zap/field.go | 8 ++ vendor/go.uber.org/zap/options.go | 11 ++- vendor/go.uber.org/zap/zapcore/field.go | 7 +- .../go.uber.org/zap/zapcore/increase_level.go | 17 +++- vendor/go.uber.org/zap/zapcore/sampler.go | 94 +++++++++++++++++-- vendor/modules.txt | 2 +- 19 files changed, 178 insertions(+), 38 deletions(-) diff --git a/embed/config_logging.go b/embed/config_logging.go index b0201615b..edb7d224a 100644 --- a/embed/config_logging.go +++ b/embed/config_logging.go @@ -98,6 +98,7 @@ func (cfg *Config) setupLogging() error { if err != nil { return err } + zap.ReplaceGlobals(c.logger) c.loggerMu.Lock() defer c.loggerMu.Unlock() c.loggerConfig = &copied @@ -145,6 +146,7 @@ func (cfg *Config) setupLogging() error { if cfg.ZapLoggerBuilder == nil { cfg.ZapLoggerBuilder = func(c *Config) error { c.logger = zap.New(cr, zap.AddCaller(), zap.ErrorOutput(syncer)) + zap.ReplaceGlobals(c.logger) c.loggerMu.Lock() defer c.loggerMu.Unlock() c.loggerConfig = nil diff --git a/etcdserver/api/membership/cluster_test.go b/etcdserver/api/membership/cluster_test.go index dade2c0b6..affb10e1d 100644 --- a/etcdserver/api/membership/cluster_test.go +++ b/etcdserver/api/membership/cluster_test.go @@ -17,11 +17,12 @@ package membership import ( "encoding/json" "fmt" - "github.com/coreos/go-semver/semver" "path" "reflect" "testing" + "github.com/coreos/go-semver/semver" + "go.etcd.io/etcd/v3/etcdserver/api/v2store" "go.etcd.io/etcd/v3/pkg/mock/mockstore" "go.etcd.io/etcd/v3/pkg/testutil" diff --git a/etcdserver/api/membership/downgrade_test.go b/etcdserver/api/membership/downgrade_test.go index 8163a2ec3..cbe7e7e5f 100644 --- a/etcdserver/api/membership/downgrade_test.go +++ b/etcdserver/api/membership/downgrade_test.go @@ -17,15 +17,16 @@ package membership import ( "bytes" "fmt" - "github.com/coreos/go-semver/semver" - "go.etcd.io/etcd/v3/version" - "go.uber.org/zap" "io/ioutil" "os" "os/exec" "path/filepath" "strconv" "testing" + + "github.com/coreos/go-semver/semver" + "go.etcd.io/etcd/v3/version" + "go.uber.org/zap" ) func TestMustDetectDowngrade(t *testing.T) { diff --git a/etcdserver/api/snap/snapshotter_test.go b/etcdserver/api/snap/snapshotter_test.go index 542305b56..16d98d83f 100644 --- a/etcdserver/api/snap/snapshotter_test.go +++ b/etcdserver/api/snap/snapshotter_test.go @@ -16,7 +16,6 @@ package snap import ( "fmt" - "go.etcd.io/etcd/v3/pkg/fileutil" "hash/crc32" "io/ioutil" "os" @@ -24,9 +23,9 @@ import ( "reflect" "testing" + "go.etcd.io/etcd/v3/pkg/fileutil" "go.etcd.io/etcd/v3/raft/raftpb" "go.etcd.io/etcd/v3/wal/walpb" - "go.uber.org/zap" ) diff --git a/go.mod b/go.mod index 69723c32b..e76166500 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( github.com/urfave/cli v1.20.0 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 go.etcd.io/bbolt v1.3.5 - go.uber.org/zap v1.14.1 + go.uber.org/zap v1.15.0 golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 diff --git a/go.sum b/go.sum index 3491e1397..b1e97105b 100644 --- a/go.sum +++ b/go.sum @@ -17,8 +17,6 @@ github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazu github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -159,8 +157,8 @@ go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo= -go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= diff --git a/integration/embed/embed_test.go b/integration/embed/embed_test.go index 06723852f..4791e29f9 100644 --- a/integration/embed/embed_test.go +++ b/integration/embed/embed_test.go @@ -22,7 +22,6 @@ package embed_test import ( "context" "fmt" - "go.etcd.io/etcd/c/v3/pkg/transport" "net/url" "os" "path/filepath" @@ -32,6 +31,7 @@ import ( "go.etcd.io/etcd/v3/clientv3" "go.etcd.io/etcd/v3/embed" + "go.etcd.io/etcd/v3/pkg/transport" ) var ( diff --git a/integration/v3_barrier_test.go b/integration/v3_barrier_test.go index a91d2299d..a85a2f997 100644 --- a/integration/v3_barrier_test.go +++ b/integration/v3_barrier_test.go @@ -19,7 +19,7 @@ import ( "time" "go.etcd.io/etcd/v3/clientv3" - "go.etcd.io/etcd/v3/contrib/recipes" + recipe "go.etcd.io/etcd/v3/contrib/recipes" "go.etcd.io/etcd/v3/pkg/testutil" ) diff --git a/integration/v3_double_barrier_test.go b/integration/v3_double_barrier_test.go index cafaa01ed..77f12f2e6 100644 --- a/integration/v3_double_barrier_test.go +++ b/integration/v3_double_barrier_test.go @@ -19,7 +19,7 @@ import ( "time" "go.etcd.io/etcd/v3/clientv3/concurrency" - "go.etcd.io/etcd/v3/contrib/recipes" + recipe "go.etcd.io/etcd/v3/contrib/recipes" ) func TestDoubleBarrier(t *testing.T) { diff --git a/integration/v3_queue_test.go b/integration/v3_queue_test.go index 74ed0b012..0dc2af258 100644 --- a/integration/v3_queue_test.go +++ b/integration/v3_queue_test.go @@ -20,7 +20,7 @@ import ( "sync/atomic" "testing" - "go.etcd.io/etcd/v3/contrib/recipes" + recipe "go.etcd.io/etcd/v3/contrib/recipes" ) const ( diff --git a/vendor/go.uber.org/zap/.travis.yml b/vendor/go.uber.org/zap/.travis.yml index 647b4ee43..cfdc69f41 100644 --- a/vendor/go.uber.org/zap/.travis.yml +++ b/vendor/go.uber.org/zap/.travis.yml @@ -9,8 +9,8 @@ env: matrix: include: - - go: 1.12.x - go: 1.13.x + - go: 1.14.x env: LINT=1 script: diff --git a/vendor/go.uber.org/zap/CHANGELOG.md b/vendor/go.uber.org/zap/CHANGELOG.md index 6e28b6ea4..aeff90e4e 100644 --- a/vendor/go.uber.org/zap/CHANGELOG.md +++ b/vendor/go.uber.org/zap/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## 1.15.0 (23 Apr 2020) + +Bugfixes: +* [#804][]: Fix handling of `Time` values out of `UnixNano` range. +* [#812][]: Fix `IncreaseLevel` being reset after a call to `With`. + +Enhancements: +* [#806][]: Add `WithCaller` option to supersede the `AddCaller` option. This + allows disabling annotation of log entries with caller information if + previously enabled with `AddCaller`. +* [#813][]: Deprecate `NewSampler` constructor in favor of + `NewSamplerWithOptions` which supports a `SamplerHook` option. This option + adds support for monitoring sampling decisions through a hook. + +Thanks to @danielbprice for their contributions to this release. + ## 1.14.1 (14 Mar 2020) Bugfixes: @@ -379,3 +395,7 @@ upgrade to the upcoming stable release. [#791]: https://github.com/uber-go/zap/pull/791 [#795]: https://github.com/uber-go/zap/pull/795 [#799]: https://github.com/uber-go/zap/pull/799 +[#804]: https://github.com/uber-go/zap/pull/804 +[#812]: https://github.com/uber-go/zap/pull/812 +[#806]: https://github.com/uber-go/zap/pull/806 +[#813]: https://github.com/uber-go/zap/pull/813 diff --git a/vendor/go.uber.org/zap/config.go b/vendor/go.uber.org/zap/config.go index eae1d237f..192fd1a94 100644 --- a/vendor/go.uber.org/zap/config.go +++ b/vendor/go.uber.org/zap/config.go @@ -32,10 +32,14 @@ import ( // global CPU and I/O load that logging puts on your process while attempting // to preserve a representative subset of your logs. // -// Values configured here are per-second. See zapcore.NewSampler for details. +// If specified, the Sampler will invoke the Hook after each decision. +// +// Values configured here are per-second. See zapcore.NewSamplerWithOptions for +// details. type SamplingConfig struct { - Initial int `json:"initial" yaml:"initial"` - Thereafter int `json:"thereafter" yaml:"thereafter"` + Initial int `json:"initial" yaml:"initial"` + Thereafter int `json:"thereafter" yaml:"thereafter"` + Hook func(zapcore.Entry, zapcore.SamplingDecision) `json:"-" yaml:"-"` } // Config offers a declarative way to construct a logger. It doesn't do @@ -208,9 +212,19 @@ func (cfg Config) buildOptions(errSink zapcore.WriteSyncer) []Option { opts = append(opts, AddStacktrace(stackLevel)) } - if cfg.Sampling != nil { + if scfg := cfg.Sampling; scfg != nil { opts = append(opts, WrapCore(func(core zapcore.Core) zapcore.Core { - return zapcore.NewSampler(core, time.Second, int(cfg.Sampling.Initial), int(cfg.Sampling.Thereafter)) + var samplerOpts []zapcore.SamplerOption + if scfg.Hook != nil { + samplerOpts = append(samplerOpts, zapcore.SamplerHook(scfg.Hook)) + } + return zapcore.NewSamplerWithOptions( + core, + time.Second, + cfg.Sampling.Initial, + cfg.Sampling.Thereafter, + samplerOpts..., + ) })) } diff --git a/vendor/go.uber.org/zap/field.go b/vendor/go.uber.org/zap/field.go index 83c1ea245..dd558fc23 100644 --- a/vendor/go.uber.org/zap/field.go +++ b/vendor/go.uber.org/zap/field.go @@ -32,6 +32,11 @@ import ( // improves the navigability of this package's API documentation. type Field = zapcore.Field +var ( + _minTimeInt64 = time.Unix(0, math.MinInt64) + _maxTimeInt64 = time.Unix(0, math.MaxInt64) +) + // Skip constructs a no-op field, which is often useful when handling invalid // inputs in other Field constructors. func Skip() Field { @@ -339,6 +344,9 @@ func Stringer(key string, val fmt.Stringer) Field { // Time constructs a Field with the given key and value. The encoder // controls how the time is serialized. func Time(key string, val time.Time) Field { + if val.Before(_minTimeInt64) || val.After(_maxTimeInt64) { + return Field{Key: key, Type: zapcore.TimeFullType, Interface: val} + } return Field{Key: key, Type: zapcore.TimeType, Integer: val.UnixNano(), Interface: val.Location()} } diff --git a/vendor/go.uber.org/zap/options.go b/vendor/go.uber.org/zap/options.go index dd3b6b2b2..59f1b54a0 100644 --- a/vendor/go.uber.org/zap/options.go +++ b/vendor/go.uber.org/zap/options.go @@ -87,10 +87,17 @@ func Development() Option { } // AddCaller configures the Logger to annotate each message with the filename -// and line number of zap's caller. +// and line number of zap's caller. See also WithCaller. func AddCaller() Option { + return WithCaller(true) +} + +// WithCaller configures the Logger to annotate each message with the filename +// and line number of zap's caller, or not, depending on the value of enabled. +// This is a generalized form of AddCaller. +func WithCaller(enabled bool) Option { return optionFunc(func(log *Logger) { - log.addCaller = true + log.addCaller = enabled }) } diff --git a/vendor/go.uber.org/zap/zapcore/field.go b/vendor/go.uber.org/zap/zapcore/field.go index ae772e4a1..6e05f831f 100644 --- a/vendor/go.uber.org/zap/zapcore/field.go +++ b/vendor/go.uber.org/zap/zapcore/field.go @@ -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. @@ -145,6 +148,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: diff --git a/vendor/go.uber.org/zap/zapcore/increase_level.go b/vendor/go.uber.org/zap/zapcore/increase_level.go index a42135c15..5a1749261 100644 --- a/vendor/go.uber.org/zap/zapcore/increase_level.go +++ b/vendor/go.uber.org/zap/zapcore/increase_level.go @@ -23,8 +23,7 @@ package zapcore import "fmt" type levelFilterCore struct { - Core - + core Core level LevelEnabler } @@ -46,10 +45,22 @@ 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) + 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() } diff --git a/vendor/go.uber.org/zap/zapcore/sampler.go b/vendor/go.uber.org/zap/zapcore/sampler.go index e31641863..25f10ca1d 100644 --- a/vendor/go.uber.org/zap/zapcore/sampler.go +++ b/vendor/go.uber.org/zap/zapcore/sampler.go @@ -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, } } @@ -128,7 +200,9 @@ func (s *sampler) Check(ent Entry, ce *CheckedEntry) *CheckedEntry { 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) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 498345f73..734fc87f2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -140,7 +140,7 @@ go.etcd.io/bbolt go.uber.org/atomic # go.uber.org/multierr v1.5.0 go.uber.org/multierr -# go.uber.org/zap v1.14.1 +# go.uber.org/zap v1.15.0 ## explicit go.uber.org/zap go.uber.org/zap/buffer