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:
23
vendor/go.uber.org/zap/.travis.yml
generated
vendored
23
vendor/go.uber.org/zap/.travis.yml
generated
vendored
@@ -1,23 +0,0 @@
|
||||
language: go
|
||||
sudo: false
|
||||
|
||||
go_import_path: go.uber.org/zap
|
||||
env:
|
||||
global:
|
||||
- TEST_TIMEOUT_SCALE=10
|
||||
- GO111MODULE=on
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- go: 1.12.x
|
||||
- go: 1.13.x
|
||||
env: LINT=1
|
||||
|
||||
script:
|
||||
- test -z "$LINT" || make lint
|
||||
- make test
|
||||
- make bench
|
||||
|
||||
after_success:
|
||||
- make cover
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
164
vendor/go.uber.org/zap/CHANGELOG.md
generated
vendored
164
vendor/go.uber.org/zap/CHANGELOG.md
generated
vendored
@@ -1,4 +1,138 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## 1.19.1 (8 Sep 2021)
|
||||
|
||||
### Fixed
|
||||
* [#1001][]: JSON: Fix complex number encoding with negative imaginary part. Thanks to @hemantjadon.
|
||||
* [#1003][]: JSON: Fix inaccurate precision when encoding float32.
|
||||
|
||||
[#1001]: https://github.com/uber-go/zap/pull/1001
|
||||
[#1003]: https://github.com/uber-go/zap/pull/1003
|
||||
|
||||
## 1.19.0 (9 Aug 2021)
|
||||
|
||||
Enhancements:
|
||||
* [#975][]: Avoid panicking in Sampler core if the level is out of bounds.
|
||||
* [#984][]: Reduce the size of BufferedWriteSyncer by aligning the fields
|
||||
better.
|
||||
|
||||
[#975]: https://github.com/uber-go/zap/pull/975
|
||||
[#984]: https://github.com/uber-go/zap/pull/984
|
||||
|
||||
Thanks to @lancoLiu and @thockin for their contributions to this release.
|
||||
|
||||
## 1.18.1 (28 Jun 2021)
|
||||
|
||||
Bugfixes:
|
||||
* [#974][]: Fix nil dereference in logger constructed by `zap.NewNop`.
|
||||
|
||||
[#974]: https://github.com/uber-go/zap/pull/974
|
||||
|
||||
## 1.18.0 (28 Jun 2021)
|
||||
|
||||
Enhancements:
|
||||
* [#961][]: Add `zapcore.BufferedWriteSyncer`, a new `WriteSyncer` that buffers
|
||||
messages in-memory and flushes them periodically.
|
||||
* [#971][]: Add `zapio.Writer` to use a Zap logger as an `io.Writer`.
|
||||
* [#897][]: Add `zap.WithClock` option to control the source of time via the
|
||||
new `zapcore.Clock` interface.
|
||||
* [#949][]: Avoid panicking in `zap.SugaredLogger` when arguments of `*w`
|
||||
methods don't match expectations.
|
||||
* [#943][]: Add support for filtering by level or arbitrary matcher function to
|
||||
`zaptest/observer`.
|
||||
* [#691][]: Comply with `io.StringWriter` and `io.ByteWriter` in Zap's
|
||||
`buffer.Buffer`.
|
||||
|
||||
Thanks to @atrn0, @ernado, @heyanfu, @hnlq715, @zchee
|
||||
for their contributions to this release.
|
||||
|
||||
[#691]: https://github.com/uber-go/zap/pull/691
|
||||
[#897]: https://github.com/uber-go/zap/pull/897
|
||||
[#943]: https://github.com/uber-go/zap/pull/943
|
||||
[#949]: https://github.com/uber-go/zap/pull/949
|
||||
[#961]: https://github.com/uber-go/zap/pull/961
|
||||
[#971]: https://github.com/uber-go/zap/pull/971
|
||||
|
||||
## 1.17.0 (25 May 2021)
|
||||
|
||||
Bugfixes:
|
||||
* [#867][]: Encode `<nil>` for nil `error` instead of a panic.
|
||||
* [#931][], [#936][]: Update minimum version constraints to address
|
||||
vulnerabilities in dependencies.
|
||||
|
||||
Enhancements:
|
||||
* [#865][]: Improve alignment of fields of the Logger struct, reducing its
|
||||
size from 96 to 80 bytes.
|
||||
* [#881][]: Support `grpclog.LoggerV2` in zapgrpc.
|
||||
* [#903][]: Support URL-encoded POST requests to the AtomicLevel HTTP handler
|
||||
with the `application/x-www-form-urlencoded` content type.
|
||||
* [#912][]: Support multi-field encoding with `zap.Inline`.
|
||||
* [#913][]: Speed up SugaredLogger for calls with a single string.
|
||||
* [#928][]: Add support for filtering by field name to `zaptest/observer`.
|
||||
|
||||
Thanks to @ash2k, @FMLS, @jimmystewpot, @Oncilla, @tsoslow, @tylitianrui, @withshubh, and @wziww for their contributions to this release.
|
||||
|
||||
## 1.16.0 (1 Sep 2020)
|
||||
|
||||
Bugfixes:
|
||||
* [#828][]: Fix missing newline in IncreaseLevel error messages.
|
||||
* [#835][]: Fix panic in JSON encoder when encoding times or durations
|
||||
without specifying a time or duration encoder.
|
||||
* [#843][]: Honor CallerSkip when taking stack traces.
|
||||
* [#862][]: Fix the default file permissions to use `0666` and rely on the umask instead.
|
||||
* [#854][]: Encode `<nil>` for nil `Stringer` instead of a panic error log.
|
||||
|
||||
Enhancements:
|
||||
* [#629][]: Added `zapcore.TimeEncoderOfLayout` to easily create time encoders
|
||||
for custom layouts.
|
||||
* [#697][]: Added support for a configurable delimiter in the console encoder.
|
||||
* [#852][]: Optimize console encoder by pooling the underlying JSON encoder.
|
||||
* [#844][]: Add ability to include the calling function as part of logs.
|
||||
* [#843][]: Add `StackSkip` for including truncated stacks as a field.
|
||||
* [#861][]: Add options to customize Fatal behaviour for better testability.
|
||||
|
||||
Thanks to @SteelPhase, @tmshn, @lixingwang, @wyxloading, @moul, @segevfiner, @andy-retailnext and @jcorbin for their contributions to this release.
|
||||
|
||||
## 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:
|
||||
* [#791][]: Fix panic on attempting to build a logger with an invalid Config.
|
||||
* [#795][]: Vendoring Zap with `go mod vendor` no longer includes Zap's
|
||||
development-time dependencies.
|
||||
* [#799][]: Fix issue introduced in 1.14.0 that caused invalid JSON output to
|
||||
be generated for arrays of `time.Time` objects when using string-based time
|
||||
formats.
|
||||
|
||||
Thanks to @YashishDua for their contributions to this release.
|
||||
|
||||
## 1.14.0 (20 Feb 2020)
|
||||
|
||||
Enhancements:
|
||||
* [#771][]: Optimize calls for disabled log levels.
|
||||
* [#773][]: Add millisecond duration encoder.
|
||||
* [#775][]: Add option to increase the level of a logger.
|
||||
* [#786][]: Optimize time formatters using `Time.AppendFormat` where possible.
|
||||
|
||||
Thanks to @caibirdme for their contributions to this release.
|
||||
|
||||
## 1.13.0 (13 Nov 2019)
|
||||
|
||||
@@ -350,3 +484,33 @@ upgrade to the upcoming stable release.
|
||||
[#736]: https://github.com/uber-go/zap/pull/736
|
||||
[#751]: https://github.com/uber-go/zap/pull/751
|
||||
[#758]: https://github.com/uber-go/zap/pull/758
|
||||
[#771]: https://github.com/uber-go/zap/pull/771
|
||||
[#773]: https://github.com/uber-go/zap/pull/773
|
||||
[#775]: https://github.com/uber-go/zap/pull/775
|
||||
[#786]: https://github.com/uber-go/zap/pull/786
|
||||
[#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
|
||||
[#629]: https://github.com/uber-go/zap/pull/629
|
||||
[#697]: https://github.com/uber-go/zap/pull/697
|
||||
[#828]: https://github.com/uber-go/zap/pull/828
|
||||
[#835]: https://github.com/uber-go/zap/pull/835
|
||||
[#843]: https://github.com/uber-go/zap/pull/843
|
||||
[#844]: https://github.com/uber-go/zap/pull/844
|
||||
[#852]: https://github.com/uber-go/zap/pull/852
|
||||
[#854]: https://github.com/uber-go/zap/pull/854
|
||||
[#861]: https://github.com/uber-go/zap/pull/861
|
||||
[#862]: https://github.com/uber-go/zap/pull/862
|
||||
[#865]: https://github.com/uber-go/zap/pull/865
|
||||
[#867]: https://github.com/uber-go/zap/pull/867
|
||||
[#881]: https://github.com/uber-go/zap/pull/881
|
||||
[#903]: https://github.com/uber-go/zap/pull/903
|
||||
[#912]: https://github.com/uber-go/zap/pull/912
|
||||
[#913]: https://github.com/uber-go/zap/pull/913
|
||||
[#928]: https://github.com/uber-go/zap/pull/928
|
||||
[#931]: https://github.com/uber-go/zap/pull/931
|
||||
[#936]: https://github.com/uber-go/zap/pull/936
|
||||
|
||||
6
vendor/go.uber.org/zap/CONTRIBUTING.md
generated
vendored
6
vendor/go.uber.org/zap/CONTRIBUTING.md
generated
vendored
@@ -25,12 +25,6 @@ git remote add upstream https://github.com/uber-go/zap.git
|
||||
git fetch upstream
|
||||
```
|
||||
|
||||
Install zap's dependencies:
|
||||
|
||||
```
|
||||
make dependencies
|
||||
```
|
||||
|
||||
Make sure that the tests and the linters pass:
|
||||
|
||||
```
|
||||
|
||||
9
vendor/go.uber.org/zap/FAQ.md
generated
vendored
9
vendor/go.uber.org/zap/FAQ.md
generated
vendored
@@ -27,6 +27,13 @@ abstraction, and it lets us add methods without introducing breaking changes.
|
||||
Your applications should define and depend upon an interface that includes
|
||||
just the methods you use.
|
||||
|
||||
### Why are some of my logs missing?
|
||||
|
||||
Logs are dropped intentionally by zap when sampling is enabled. The production
|
||||
configuration (as returned by `NewProductionConfig()` enables sampling which will
|
||||
cause repeated logs within a second to be sampled. See more details on why sampling
|
||||
is enabled in [Why sample application logs](https://github.com/uber-go/zap/blob/master/FAQ.md#why-sample-application-logs).
|
||||
|
||||
### Why sample application logs?
|
||||
|
||||
Applications often experience runs of errors, either because of a bug or
|
||||
@@ -149,6 +156,8 @@ We're aware of the following extensions, but haven't used them ourselves:
|
||||
| `github.com/tchap/zapext` | Sentry, syslog |
|
||||
| `github.com/fgrosse/zaptest` | Ginkgo |
|
||||
| `github.com/blendle/zapdriver` | Stackdriver |
|
||||
| `github.com/moul/zapgorm` | Gorm |
|
||||
| `github.com/moul/zapfilter` | Advanced filtering rules |
|
||||
|
||||
[go-proverbs]: https://go-proverbs.github.io/
|
||||
[import-path]: https://golang.org/cmd/go/#hdr-Remote_import_paths
|
||||
|
||||
22
vendor/go.uber.org/zap/Makefile
generated
vendored
22
vendor/go.uber.org/zap/Makefile
generated
vendored
@@ -1,12 +1,13 @@
|
||||
export GOBIN ?= $(shell pwd)/bin
|
||||
|
||||
GOLINT = $(GOBIN)/golint
|
||||
STATICCHECK = $(GOBIN)/staticcheck
|
||||
BENCH_FLAGS ?= -cpuprofile=cpu.pprof -memprofile=mem.pprof -benchmem
|
||||
|
||||
# Directories containing independent Go modules.
|
||||
#
|
||||
# We track coverage only for the main module.
|
||||
MODULE_DIRS = . ./benchmarks
|
||||
MODULE_DIRS = . ./benchmarks ./zapgrpc/internal/test
|
||||
|
||||
# Many Go tools take file globs or directories as arguments instead of packages.
|
||||
GO_FILES := $(shell \
|
||||
@@ -17,7 +18,7 @@ GO_FILES := $(shell \
|
||||
all: lint test
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(GOLINT)
|
||||
lint: $(GOLINT) $(STATICCHECK)
|
||||
@rm -rf lint.log
|
||||
@echo "Checking formatting..."
|
||||
@gofmt -d -s $(GO_FILES) 2>&1 | tee lint.log
|
||||
@@ -25,14 +26,25 @@ lint: $(GOLINT)
|
||||
@$(foreach dir,$(MODULE_DIRS),(cd $(dir) && go vet ./... 2>&1) &&) true | tee -a lint.log
|
||||
@echo "Checking lint..."
|
||||
@$(foreach dir,$(MODULE_DIRS),(cd $(dir) && $(GOLINT) ./... 2>&1) &&) true | tee -a lint.log
|
||||
@echo "Checking staticcheck..."
|
||||
@$(foreach dir,$(MODULE_DIRS),(cd $(dir) && $(STATICCHECK) ./... 2>&1) &&) true | tee -a lint.log
|
||||
@echo "Checking for unresolved FIXMEs..."
|
||||
@git grep -i fixme | grep -v -e Makefile | tee -a lint.log
|
||||
@echo "Checking for license headers..."
|
||||
@./checklicense.sh | tee -a lint.log
|
||||
@[ ! -s lint.log ]
|
||||
@echo "Checking 'go mod tidy'..."
|
||||
@make tidy
|
||||
@if ! git diff --quiet; then \
|
||||
echo "'go mod tidy' resulted in changes or working tree is dirty:"; \
|
||||
git --no-pager diff; \
|
||||
fi
|
||||
|
||||
$(GOLINT):
|
||||
go install golang.org/x/lint/golint
|
||||
cd tools && go install golang.org/x/lint/golint
|
||||
|
||||
$(STATICCHECK):
|
||||
cd tools && go install honnef.co/go/tools/cmd/staticcheck
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
@@ -55,3 +67,7 @@ bench:
|
||||
updatereadme:
|
||||
rm -f README.md
|
||||
cat .readme.tmpl | go run internal/readme/readme.go > README.md
|
||||
|
||||
.PHONY: tidy
|
||||
tidy:
|
||||
@$(foreach dir,$(MODULE_DIRS),(cd $(dir) && go mod tidy) &&) true
|
||||
|
||||
8
vendor/go.uber.org/zap/README.md
generated
vendored
8
vendor/go.uber.org/zap/README.md
generated
vendored
@@ -123,10 +123,10 @@ Released under the [MIT License](LICENSE.txt).
|
||||
benchmarking against slightly older versions of other packages. Versions are
|
||||
pinned in the [benchmarks/go.mod][] file. [↩](#anchor-versions)
|
||||
|
||||
[doc-img]: https://godoc.org/go.uber.org/zap?status.svg
|
||||
[doc]: https://godoc.org/go.uber.org/zap
|
||||
[ci-img]: https://travis-ci.com/uber-go/zap.svg?branch=master
|
||||
[ci]: https://travis-ci.com/uber-go/zap
|
||||
[doc-img]: https://pkg.go.dev/badge/go.uber.org/zap
|
||||
[doc]: https://pkg.go.dev/go.uber.org/zap
|
||||
[ci-img]: https://github.com/uber-go/zap/actions/workflows/go.yml/badge.svg
|
||||
[ci]: https://github.com/uber-go/zap/actions/workflows/go.yml
|
||||
[cov-img]: https://codecov.io/gh/uber-go/zap/branch/master/graph/badge.svg
|
||||
[cov]: https://codecov.io/gh/uber-go/zap
|
||||
[benchmarking suite]: https://github.com/uber-go/zap/tree/master/benchmarks
|
||||
|
||||
28
vendor/go.uber.org/zap/buffer/buffer.go
generated
vendored
28
vendor/go.uber.org/zap/buffer/buffer.go
generated
vendored
@@ -23,7 +23,10 @@
|
||||
// package's zero-allocation formatters.
|
||||
package buffer // import "go.uber.org/zap/buffer"
|
||||
|
||||
import "strconv"
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const _size = 1024 // by default, create 1 KiB buffers
|
||||
|
||||
@@ -49,6 +52,11 @@ func (b *Buffer) AppendInt(i int64) {
|
||||
b.bs = strconv.AppendInt(b.bs, i, 10)
|
||||
}
|
||||
|
||||
// AppendTime appends the time formatted using the specified layout.
|
||||
func (b *Buffer) AppendTime(t time.Time, layout string) {
|
||||
b.bs = t.AppendFormat(b.bs, layout)
|
||||
}
|
||||
|
||||
// AppendUint appends an unsigned integer to the underlying buffer (assuming
|
||||
// base 10).
|
||||
func (b *Buffer) AppendUint(i uint64) {
|
||||
@@ -98,6 +106,24 @@ func (b *Buffer) Write(bs []byte) (int, error) {
|
||||
return len(bs), nil
|
||||
}
|
||||
|
||||
// WriteByte writes a single byte to the Buffer.
|
||||
//
|
||||
// Error returned is always nil, function signature is compatible
|
||||
// with bytes.Buffer and bufio.Writer
|
||||
func (b *Buffer) WriteByte(v byte) error {
|
||||
b.AppendByte(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteString writes a string to the Buffer.
|
||||
//
|
||||
// Error returned is always nil, function signature is compatible
|
||||
// with bytes.Buffer and bufio.Writer
|
||||
func (b *Buffer) WriteString(s string) (int, error) {
|
||||
b.AppendString(s)
|
||||
return len(s), nil
|
||||
}
|
||||
|
||||
// TrimNewline trims any final "\n" byte from the end of the buffer.
|
||||
func (b *Buffer) TrimNewline() {
|
||||
if i := len(b.bs) - 1; i >= 0 {
|
||||
|
||||
31
vendor/go.uber.org/zap/config.go
generated
vendored
31
vendor/go.uber.org/zap/config.go
generated
vendored
@@ -21,6 +21,7 @@
|
||||
package zap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
@@ -31,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
|
||||
@@ -96,6 +101,7 @@ func NewProductionEncoderConfig() zapcore.EncoderConfig {
|
||||
LevelKey: "level",
|
||||
NameKey: "logger",
|
||||
CallerKey: "caller",
|
||||
FunctionKey: zapcore.OmitKey,
|
||||
MessageKey: "msg",
|
||||
StacktraceKey: "stacktrace",
|
||||
LineEnding: zapcore.DefaultLineEnding,
|
||||
@@ -135,6 +141,7 @@ func NewDevelopmentEncoderConfig() zapcore.EncoderConfig {
|
||||
LevelKey: "L",
|
||||
NameKey: "N",
|
||||
CallerKey: "C",
|
||||
FunctionKey: zapcore.OmitKey,
|
||||
MessageKey: "M",
|
||||
StacktraceKey: "S",
|
||||
LineEnding: zapcore.DefaultLineEnding,
|
||||
@@ -174,6 +181,10 @@ func (cfg Config) Build(opts ...Option) (*Logger, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cfg.Level == (AtomicLevel{}) {
|
||||
return nil, fmt.Errorf("missing Level")
|
||||
}
|
||||
|
||||
log := New(
|
||||
zapcore.NewCore(enc, sink, cfg.Level),
|
||||
cfg.buildOptions(errSink)...,
|
||||
@@ -203,9 +214,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...,
|
||||
)
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
4
vendor/go.uber.org/zap/encoder.go
generated
vendored
4
vendor/go.uber.org/zap/encoder.go
generated
vendored
@@ -62,6 +62,10 @@ func RegisterEncoder(name string, constructor func(zapcore.EncoderConfig) (zapco
|
||||
}
|
||||
|
||||
func newEncoder(name string, encoderConfig zapcore.EncoderConfig) (zapcore.Encoder, error) {
|
||||
if encoderConfig.TimeKey != "" && encoderConfig.EncodeTime == nil {
|
||||
return nil, fmt.Errorf("missing EncodeTime in EncoderConfig")
|
||||
}
|
||||
|
||||
_encoderMutex.RLock()
|
||||
defer _encoderMutex.RUnlock()
|
||||
if name == "" {
|
||||
|
||||
26
vendor/go.uber.org/zap/field.go
generated
vendored
26
vendor/go.uber.org/zap/field.go
generated
vendored
@@ -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()}
|
||||
}
|
||||
|
||||
@@ -356,11 +364,17 @@ func Timep(key string, val *time.Time) Field {
|
||||
// expensive (relatively speaking); this function both makes an allocation and
|
||||
// takes about two microseconds.
|
||||
func Stack(key string) Field {
|
||||
return StackSkip(key, 1) // skip Stack
|
||||
}
|
||||
|
||||
// StackSkip constructs a field similarly to Stack, but also skips the given
|
||||
// number of frames from the top of the stacktrace.
|
||||
func StackSkip(key string, skip int) Field {
|
||||
// Returning the stacktrace as a string costs an allocation, but saves us
|
||||
// from expanding the zapcore.Field union struct to include a byte slice. Since
|
||||
// taking a stacktrace is already so expensive (~10us), the extra allocation
|
||||
// is okay.
|
||||
return String(key, takeStacktrace())
|
||||
return String(key, takeStacktrace(skip+1)) // skip StackSkip
|
||||
}
|
||||
|
||||
// Duration constructs a field with the given key and value. The encoder
|
||||
@@ -386,6 +400,16 @@ func Object(key string, val zapcore.ObjectMarshaler) Field {
|
||||
return Field{Key: key, Type: zapcore.ObjectMarshalerType, Interface: val}
|
||||
}
|
||||
|
||||
// Inline constructs a Field that is similar to Object, but it
|
||||
// will add the elements of the provided ObjectMarshaler to the
|
||||
// current namespace.
|
||||
func Inline(val zapcore.ObjectMarshaler) Field {
|
||||
return zapcore.Field{
|
||||
Type: zapcore.InlineMarshalerType,
|
||||
Interface: val,
|
||||
}
|
||||
}
|
||||
|
||||
// Any takes a key and an arbitrary value and chooses the best way to represent
|
||||
// them as a field, falling back to a reflection-based approach only if
|
||||
// necessary.
|
||||
|
||||
99
vendor/go.uber.org/zap/http_handler.go
generated
vendored
99
vendor/go.uber.org/zap/http_handler.go
generated
vendored
@@ -23,6 +23,7 @@ package zap
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"go.uber.org/zap/zapcore"
|
||||
@@ -31,47 +32,63 @@ import (
|
||||
// ServeHTTP is a simple JSON endpoint that can report on or change the current
|
||||
// logging level.
|
||||
//
|
||||
// GET requests return a JSON description of the current logging level. PUT
|
||||
// requests change the logging level and expect a payload like:
|
||||
// GET
|
||||
//
|
||||
// The GET request returns a JSON description of the current logging level like:
|
||||
// {"level":"info"}
|
||||
//
|
||||
// It's perfectly safe to change the logging level while a program is running.
|
||||
// PUT
|
||||
//
|
||||
// The PUT request changes the logging level. It is perfectly safe to change the
|
||||
// logging level while a program is running. Two content types are supported:
|
||||
//
|
||||
// Content-Type: application/x-www-form-urlencoded
|
||||
//
|
||||
// With this content type, the level can be provided through the request body or
|
||||
// a query parameter. The log level is URL encoded like:
|
||||
//
|
||||
// level=debug
|
||||
//
|
||||
// The request body takes precedence over the query parameter, if both are
|
||||
// specified.
|
||||
//
|
||||
// This content type is the default for a curl PUT request. Following are two
|
||||
// example curl requests that both set the logging level to debug.
|
||||
//
|
||||
// curl -X PUT localhost:8080/log/level?level=debug
|
||||
// curl -X PUT localhost:8080/log/level -d level=debug
|
||||
//
|
||||
// For any other content type, the payload is expected to be JSON encoded and
|
||||
// look like:
|
||||
//
|
||||
// {"level":"info"}
|
||||
//
|
||||
// An example curl request could look like this:
|
||||
//
|
||||
// curl -X PUT localhost:8080/log/level -H "Content-Type: application/json" -d '{"level":"debug"}'
|
||||
//
|
||||
func (lvl AtomicLevel) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
type errorResponse struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
type payload struct {
|
||||
Level *zapcore.Level `json:"level"`
|
||||
Level zapcore.Level `json:"level"`
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(w)
|
||||
|
||||
switch r.Method {
|
||||
|
||||
case http.MethodGet:
|
||||
current := lvl.Level()
|
||||
enc.Encode(payload{Level: ¤t})
|
||||
|
||||
enc.Encode(payload{Level: lvl.Level()})
|
||||
case http.MethodPut:
|
||||
var req payload
|
||||
|
||||
if errmess := func() string {
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
return fmt.Sprintf("Request body must be well-formed JSON: %v", err)
|
||||
}
|
||||
if req.Level == nil {
|
||||
return "Must specify a logging level."
|
||||
}
|
||||
return ""
|
||||
}(); errmess != "" {
|
||||
requestedLvl, err := decodePutRequest(r.Header.Get("Content-Type"), r)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
enc.Encode(errorResponse{Error: errmess})
|
||||
enc.Encode(errorResponse{Error: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
lvl.SetLevel(*req.Level)
|
||||
enc.Encode(req)
|
||||
|
||||
lvl.SetLevel(requestedLvl)
|
||||
enc.Encode(payload{Level: lvl.Level()})
|
||||
default:
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
enc.Encode(errorResponse{
|
||||
@@ -79,3 +96,37 @@ func (lvl AtomicLevel) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Decodes incoming PUT requests and returns the requested logging level.
|
||||
func decodePutRequest(contentType string, r *http.Request) (zapcore.Level, error) {
|
||||
if contentType == "application/x-www-form-urlencoded" {
|
||||
return decodePutURL(r)
|
||||
}
|
||||
return decodePutJSON(r.Body)
|
||||
}
|
||||
|
||||
func decodePutURL(r *http.Request) (zapcore.Level, error) {
|
||||
lvl := r.FormValue("level")
|
||||
if lvl == "" {
|
||||
return 0, fmt.Errorf("must specify logging level")
|
||||
}
|
||||
var l zapcore.Level
|
||||
if err := l.UnmarshalText([]byte(lvl)); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func decodePutJSON(body io.Reader) (zapcore.Level, error) {
|
||||
var pld struct {
|
||||
Level *zapcore.Level `json:"level"`
|
||||
}
|
||||
if err := json.NewDecoder(body).Decode(&pld); err != nil {
|
||||
return 0, fmt.Errorf("malformed request body: %v", err)
|
||||
}
|
||||
if pld.Level == nil {
|
||||
return 0, fmt.Errorf("must specify logging level")
|
||||
}
|
||||
return *pld.Level, nil
|
||||
|
||||
}
|
||||
|
||||
61
vendor/go.uber.org/zap/logger.go
generated
vendored
61
vendor/go.uber.org/zap/logger.go
generated
vendored
@@ -26,7 +26,6 @@ import (
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
@@ -42,13 +41,17 @@ type Logger struct {
|
||||
core zapcore.Core
|
||||
|
||||
development bool
|
||||
addCaller bool
|
||||
onFatal zapcore.CheckWriteAction // default is WriteThenFatal
|
||||
|
||||
name string
|
||||
errorOutput zapcore.WriteSyncer
|
||||
|
||||
addCaller bool
|
||||
addStack zapcore.LevelEnabler
|
||||
addStack zapcore.LevelEnabler
|
||||
|
||||
callerSkip int
|
||||
|
||||
clock zapcore.Clock
|
||||
}
|
||||
|
||||
// New constructs a new Logger from the provided zapcore.Core and Options. If
|
||||
@@ -69,6 +72,7 @@ func New(core zapcore.Core, options ...Option) *Logger {
|
||||
core: core,
|
||||
errorOutput: zapcore.Lock(os.Stderr),
|
||||
addStack: zapcore.FatalLevel + 1,
|
||||
clock: zapcore.DefaultClock,
|
||||
}
|
||||
return log.WithOptions(options...)
|
||||
}
|
||||
@@ -83,6 +87,7 @@ func NewNop() *Logger {
|
||||
core: zapcore.NewNopCore(),
|
||||
errorOutput: zapcore.AddSync(ioutil.Discard),
|
||||
addStack: zapcore.FatalLevel + 1,
|
||||
clock: zapcore.DefaultClock,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,11 +263,17 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry {
|
||||
// (e.g., Check, Info, Fatal).
|
||||
const callerSkipOffset = 2
|
||||
|
||||
// Check the level first to reduce the cost of disabled log calls.
|
||||
// Since Panic and higher may exit, we skip the optimization for those levels.
|
||||
if lvl < zapcore.DPanicLevel && !log.core.Enabled(lvl) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create basic checked entry thru the core; this will be non-nil if the
|
||||
// log message will actually be written somewhere.
|
||||
ent := zapcore.Entry{
|
||||
LoggerName: log.name,
|
||||
Time: time.Now(),
|
||||
Time: log.clock.Now(),
|
||||
Level: lvl,
|
||||
Message: msg,
|
||||
}
|
||||
@@ -274,7 +285,13 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry {
|
||||
case zapcore.PanicLevel:
|
||||
ce = ce.Should(ent, zapcore.WriteThenPanic)
|
||||
case zapcore.FatalLevel:
|
||||
ce = ce.Should(ent, zapcore.WriteThenFatal)
|
||||
onFatal := log.onFatal
|
||||
// Noop is the default value for CheckWriteAction, and it leads to
|
||||
// continued execution after a Fatal which is unexpected.
|
||||
if onFatal == zapcore.WriteThenNoop {
|
||||
onFatal = zapcore.WriteThenFatal
|
||||
}
|
||||
ce = ce.Should(ent, onFatal)
|
||||
case zapcore.DPanicLevel:
|
||||
if log.development {
|
||||
ce = ce.Should(ent, zapcore.WriteThenPanic)
|
||||
@@ -291,15 +308,41 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry {
|
||||
// Thread the error output through to the CheckedEntry.
|
||||
ce.ErrorOutput = log.errorOutput
|
||||
if log.addCaller {
|
||||
ce.Entry.Caller = zapcore.NewEntryCaller(runtime.Caller(log.callerSkip + callerSkipOffset))
|
||||
if !ce.Entry.Caller.Defined {
|
||||
fmt.Fprintf(log.errorOutput, "%v Logger.check error: failed to get caller\n", time.Now().UTC())
|
||||
frame, defined := getCallerFrame(log.callerSkip + callerSkipOffset)
|
||||
if !defined {
|
||||
fmt.Fprintf(log.errorOutput, "%v Logger.check error: failed to get caller\n", ent.Time.UTC())
|
||||
log.errorOutput.Sync()
|
||||
}
|
||||
|
||||
ce.Entry.Caller = zapcore.EntryCaller{
|
||||
Defined: defined,
|
||||
PC: frame.PC,
|
||||
File: frame.File,
|
||||
Line: frame.Line,
|
||||
Function: frame.Function,
|
||||
}
|
||||
}
|
||||
if log.addStack.Enabled(ce.Entry.Level) {
|
||||
ce.Entry.Stack = Stack("").String
|
||||
ce.Entry.Stack = StackSkip("", log.callerSkip+callerSkipOffset).String
|
||||
}
|
||||
|
||||
return ce
|
||||
}
|
||||
|
||||
// getCallerFrame gets caller frame. The argument skip is the number of stack
|
||||
// frames to ascend, with 0 identifying the caller of getCallerFrame. The
|
||||
// boolean ok is false if it was not possible to recover the information.
|
||||
//
|
||||
// Note: This implementation is similar to runtime.Caller, but it returns the whole frame.
|
||||
func getCallerFrame(skip int) (frame runtime.Frame, ok bool) {
|
||||
const skipOffset = 2 // skip getCallerFrame and Callers
|
||||
|
||||
pc := make([]uintptr, 1)
|
||||
numFrames := runtime.Callers(skip+skipOffset, pc)
|
||||
if numFrames < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
frame, _ = runtime.CallersFrames(pc).Next()
|
||||
return frame, frame.PC != 0
|
||||
}
|
||||
|
||||
47
vendor/go.uber.org/zap/options.go
generated
vendored
47
vendor/go.uber.org/zap/options.go
generated
vendored
@@ -20,7 +20,11 @@
|
||||
|
||||
package zap
|
||||
|
||||
import "go.uber.org/zap/zapcore"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// An Option configures a Logger.
|
||||
type Option interface {
|
||||
@@ -82,11 +86,18 @@ func Development() Option {
|
||||
})
|
||||
}
|
||||
|
||||
// AddCaller configures the Logger to annotate each message with the filename
|
||||
// and line number of zap's caller.
|
||||
// AddCaller configures the Logger to annotate each message with the filename,
|
||||
// line number, and function name of zap's caller. See also WithCaller.
|
||||
func AddCaller() Option {
|
||||
return WithCaller(true)
|
||||
}
|
||||
|
||||
// WithCaller configures the Logger to annotate each message with the filename,
|
||||
// line number, and function name 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
|
||||
})
|
||||
}
|
||||
|
||||
@@ -107,3 +118,31 @@ func AddStacktrace(lvl zapcore.LevelEnabler) Option {
|
||||
log.addStack = lvl
|
||||
})
|
||||
}
|
||||
|
||||
// IncreaseLevel increase the level of the logger. It has no effect if
|
||||
// the passed in level tries to decrease the level of the logger.
|
||||
func IncreaseLevel(lvl zapcore.LevelEnabler) Option {
|
||||
return optionFunc(func(log *Logger) {
|
||||
core, err := zapcore.NewIncreaseLevelCore(log.core, lvl)
|
||||
if err != nil {
|
||||
fmt.Fprintf(log.errorOutput, "failed to IncreaseLevel: %v\n", err)
|
||||
} else {
|
||||
log.core = core
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// OnFatal sets the action to take on fatal logs.
|
||||
func OnFatal(action zapcore.CheckWriteAction) Option {
|
||||
return optionFunc(func(log *Logger) {
|
||||
log.onFatal = action
|
||||
})
|
||||
}
|
||||
|
||||
// WithClock specifies the clock used by the logger to determine the current
|
||||
// time for logged entries. Defaults to the system clock with time.Now.
|
||||
func WithClock(clock zapcore.Clock) Option {
|
||||
return optionFunc(func(log *Logger) {
|
||||
log.clock = clock
|
||||
})
|
||||
}
|
||||
|
||||
2
vendor/go.uber.org/zap/sink.go
generated
vendored
2
vendor/go.uber.org/zap/sink.go
generated
vendored
@@ -136,7 +136,7 @@ func newFileSink(u *url.URL) (Sink, error) {
|
||||
case "stderr":
|
||||
return nopCloserSink{os.Stderr}, nil
|
||||
}
|
||||
return os.OpenFile(u.Path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
|
||||
return os.OpenFile(u.Path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
|
||||
}
|
||||
|
||||
func normalizeScheme(s string) (string, error) {
|
||||
|
||||
47
vendor/go.uber.org/zap/stacktrace.go
generated
vendored
47
vendor/go.uber.org/zap/stacktrace.go
generated
vendored
@@ -22,28 +22,20 @@ package zap
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"go.uber.org/zap/internal/bufferpool"
|
||||
)
|
||||
|
||||
const _zapPackage = "go.uber.org/zap"
|
||||
|
||||
var (
|
||||
_stacktracePool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return newProgramCounters(64)
|
||||
},
|
||||
}
|
||||
|
||||
// We add "." and "/" suffixes to the package name to ensure we only match
|
||||
// the exact package and not any package with the same prefix.
|
||||
_zapStacktracePrefixes = addPrefix(_zapPackage, ".", "/")
|
||||
_zapStacktraceVendorContains = addPrefix("/vendor/", _zapStacktracePrefixes...)
|
||||
)
|
||||
|
||||
func takeStacktrace() string {
|
||||
func takeStacktrace(skip int) string {
|
||||
buffer := bufferpool.Get()
|
||||
defer buffer.Free()
|
||||
programCounters := _stacktracePool.Get().(*programCounters)
|
||||
@@ -51,9 +43,9 @@ func takeStacktrace() string {
|
||||
|
||||
var numFrames int
|
||||
for {
|
||||
// Skip the call to runtime.Counters and takeStacktrace so that the
|
||||
// Skip the call to runtime.Callers and takeStacktrace so that the
|
||||
// program counters start at the caller of takeStacktrace.
|
||||
numFrames = runtime.Callers(2, programCounters.pcs)
|
||||
numFrames = runtime.Callers(skip+2, programCounters.pcs)
|
||||
if numFrames < len(programCounters.pcs) {
|
||||
break
|
||||
}
|
||||
@@ -63,19 +55,12 @@ func takeStacktrace() string {
|
||||
}
|
||||
|
||||
i := 0
|
||||
skipZapFrames := true // skip all consecutive zap frames at the beginning.
|
||||
frames := runtime.CallersFrames(programCounters.pcs[:numFrames])
|
||||
|
||||
// Note: On the last iteration, frames.Next() returns false, with a valid
|
||||
// frame, but we ignore this frame. The last frame is a a runtime frame which
|
||||
// adds noise, since it's only either runtime.main or runtime.goexit.
|
||||
for frame, more := frames.Next(); more; frame, more = frames.Next() {
|
||||
if skipZapFrames && isZapFrame(frame.Function) {
|
||||
continue
|
||||
} else {
|
||||
skipZapFrames = false
|
||||
}
|
||||
|
||||
if i != 0 {
|
||||
buffer.AppendByte('\n')
|
||||
}
|
||||
@@ -91,24 +76,6 @@ func takeStacktrace() string {
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
func isZapFrame(function string) bool {
|
||||
for _, prefix := range _zapStacktracePrefixes {
|
||||
if strings.HasPrefix(function, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// We can't use a prefix match here since the location of the vendor
|
||||
// directory affects the prefix. Instead we do a contains match.
|
||||
for _, contains := range _zapStacktraceVendorContains {
|
||||
if strings.Contains(function, contains) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
type programCounters struct {
|
||||
pcs []uintptr
|
||||
}
|
||||
@@ -116,11 +83,3 @@ type programCounters struct {
|
||||
func newProgramCounters(size int) *programCounters {
|
||||
return &programCounters{make([]uintptr, size)}
|
||||
}
|
||||
|
||||
func addPrefix(prefix string, ss ...string) []string {
|
||||
withPrefix := make([]string, len(ss))
|
||||
for i, s := range ss {
|
||||
withPrefix[i] = prefix + s
|
||||
}
|
||||
return withPrefix
|
||||
}
|
||||
|
||||
31
vendor/go.uber.org/zap/sugar.go
generated
vendored
31
vendor/go.uber.org/zap/sugar.go
generated
vendored
@@ -222,19 +222,30 @@ func (s *SugaredLogger) log(lvl zapcore.Level, template string, fmtArgs []interf
|
||||
return
|
||||
}
|
||||
|
||||
// Format with Sprint, Sprintf, or neither.
|
||||
msg := template
|
||||
if msg == "" && len(fmtArgs) > 0 {
|
||||
msg = fmt.Sprint(fmtArgs...)
|
||||
} else if msg != "" && len(fmtArgs) > 0 {
|
||||
msg = fmt.Sprintf(template, fmtArgs...)
|
||||
}
|
||||
|
||||
msg := getMessage(template, fmtArgs)
|
||||
if ce := s.base.Check(lvl, msg); ce != nil {
|
||||
ce.Write(s.sweetenFields(context)...)
|
||||
}
|
||||
}
|
||||
|
||||
// getMessage format with Sprint, Sprintf, or neither.
|
||||
func getMessage(template string, fmtArgs []interface{}) string {
|
||||
if len(fmtArgs) == 0 {
|
||||
return template
|
||||
}
|
||||
|
||||
if template != "" {
|
||||
return fmt.Sprintf(template, fmtArgs...)
|
||||
}
|
||||
|
||||
if len(fmtArgs) == 1 {
|
||||
if str, ok := fmtArgs[0].(string); ok {
|
||||
return str
|
||||
}
|
||||
}
|
||||
return fmt.Sprint(fmtArgs...)
|
||||
}
|
||||
|
||||
func (s *SugaredLogger) sweetenFields(args []interface{}) []Field {
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
@@ -255,7 +266,7 @@ func (s *SugaredLogger) sweetenFields(args []interface{}) []Field {
|
||||
|
||||
// Make sure this element isn't a dangling key.
|
||||
if i == len(args)-1 {
|
||||
s.base.DPanic(_oddNumberErrMsg, Any("ignored", args[i]))
|
||||
s.base.Error(_oddNumberErrMsg, Any("ignored", args[i]))
|
||||
break
|
||||
}
|
||||
|
||||
@@ -276,7 +287,7 @@ func (s *SugaredLogger) sweetenFields(args []interface{}) []Field {
|
||||
|
||||
// If we encountered any invalid key-value pairs, log an error.
|
||||
if len(invalid) > 0 {
|
||||
s.base.DPanic(_nonStringKeyErrMsg, Array("invalid", invalid))
|
||||
s.base.Error(_nonStringKeyErrMsg, Array("invalid", invalid))
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
188
vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go
generated
vendored
Normal file
188
vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go
generated
vendored
Normal 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
|
||||
}
|
||||
34
vendor/go.uber.org/zap/tools.go → vendor/go.uber.org/zap/zapcore/clock.go
generated
vendored
34
vendor/go.uber.org/zap/tools.go → vendor/go.uber.org/zap/zapcore/clock.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2019 Uber Technologies, Inc.
|
||||
// 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
|
||||
@@ -18,11 +18,33 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
// +build tools
|
||||
|
||||
package zap
|
||||
package zapcore
|
||||
|
||||
import (
|
||||
// Tools we use during development.
|
||||
_ "golang.org/x/lint/golint"
|
||||
"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)
|
||||
}
|
||||
30
vendor/go.uber.org/zap/zapcore/console_encoder.go
generated
vendored
30
vendor/go.uber.org/zap/zapcore/console_encoder.go
generated
vendored
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
78
vendor/go.uber.org/zap/zapcore/encoder.go
generated
vendored
78
vendor/go.uber.org/zap/zapcore/encoder.go
generated
vendored
@@ -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
|
||||
|
||||
24
vendor/go.uber.org/zap/zapcore/entry.go
generated
vendored
24
vendor/go.uber.org/zap/zapcore/entry.go
generated
vendored
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
26
vendor/go.uber.org/zap/zapcore/error.go
generated
vendored
26
vendor/go.uber.org/zap/zapcore/error.go
generated
vendored
@@ -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.
|
||||
|
||||
|
||||
33
vendor/go.uber.org/zap/zapcore/field.go
generated
vendored
33
vendor/go.uber.org/zap/zapcore/field.go
generated
vendored
@@ -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
66
vendor/go.uber.org/zap/zapcore/increase_level.go
generated
vendored
Normal 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()
|
||||
}
|
||||
49
vendor/go.uber.org/zap/zapcore/json_encoder.go
generated
vendored
49
vendor/go.uber.org/zap/zapcore/json_encoder.go
generated
vendored
@@ -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 != "" {
|
||||
|
||||
8
vendor/go.uber.org/zap/zapcore/marshaler.go
generated
vendored
8
vendor/go.uber.org/zap/zapcore/marshaler.go
generated
vendored
@@ -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
|
||||
}
|
||||
|
||||
104
vendor/go.uber.org/zap/zapcore/sampler.go
generated
vendored
104
vendor/go.uber.org/zap/zapcore/sampler.go
generated
vendored
@@ -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)
|
||||
}
|
||||
|
||||
3
vendor/go.uber.org/zap/zapcore/write_syncer.go
generated
vendored
3
vendor/go.uber.org/zap/zapcore/write_syncer.go
generated
vendored
@@ -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
|
||||
|
||||
241
vendor/go.uber.org/zap/zapgrpc/zapgrpc.go
generated
vendored
Normal file
241
vendor/go.uber.org/zap/zapgrpc/zapgrpc.go
generated
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
// Copyright (c) 2016 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 zapgrpc provides a logger that is compatible with grpclog.
|
||||
package zapgrpc // import "go.uber.org/zap/zapgrpc"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// See https://github.com/grpc/grpc-go/blob/v1.35.0/grpclog/loggerv2.go#L77-L86
|
||||
const (
|
||||
grpcLvlInfo = 0
|
||||
grpcLvlWarn = 1
|
||||
grpcLvlError = 2
|
||||
grpcLvlFatal = 3
|
||||
)
|
||||
|
||||
var (
|
||||
// _grpcToZapLevel maps gRPC log levels to zap log levels.
|
||||
// See https://pkg.go.dev/go.uber.org/zap@v1.16.0/zapcore#Level
|
||||
_grpcToZapLevel = map[int]zapcore.Level{
|
||||
grpcLvlInfo: zapcore.InfoLevel,
|
||||
grpcLvlWarn: zapcore.WarnLevel,
|
||||
grpcLvlError: zapcore.ErrorLevel,
|
||||
grpcLvlFatal: zapcore.FatalLevel,
|
||||
}
|
||||
)
|
||||
|
||||
// An Option overrides a Logger's default configuration.
|
||||
type Option interface {
|
||||
apply(*Logger)
|
||||
}
|
||||
|
||||
type optionFunc func(*Logger)
|
||||
|
||||
func (f optionFunc) apply(log *Logger) {
|
||||
f(log)
|
||||
}
|
||||
|
||||
// WithDebug configures a Logger to print at zap's DebugLevel instead of
|
||||
// InfoLevel.
|
||||
// It only affects the Printf, Println and Print methods, which are only used in the gRPC v1 grpclog.Logger API.
|
||||
// Deprecated: use grpclog.SetLoggerV2() for v2 API.
|
||||
func WithDebug() Option {
|
||||
return optionFunc(func(logger *Logger) {
|
||||
logger.print = &printer{
|
||||
enab: logger.levelEnabler,
|
||||
level: zapcore.DebugLevel,
|
||||
print: logger.delegate.Debug,
|
||||
printf: logger.delegate.Debugf,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// withWarn redirects the fatal level to the warn level, which makes testing
|
||||
// easier. This is intentionally unexported.
|
||||
func withWarn() Option {
|
||||
return optionFunc(func(logger *Logger) {
|
||||
logger.fatal = &printer{
|
||||
enab: logger.levelEnabler,
|
||||
level: zapcore.WarnLevel,
|
||||
print: logger.delegate.Warn,
|
||||
printf: logger.delegate.Warnf,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// NewLogger returns a new Logger.
|
||||
func NewLogger(l *zap.Logger, options ...Option) *Logger {
|
||||
logger := &Logger{
|
||||
delegate: l.Sugar(),
|
||||
levelEnabler: l.Core(),
|
||||
}
|
||||
logger.print = &printer{
|
||||
enab: logger.levelEnabler,
|
||||
level: zapcore.InfoLevel,
|
||||
print: logger.delegate.Info,
|
||||
printf: logger.delegate.Infof,
|
||||
}
|
||||
logger.fatal = &printer{
|
||||
enab: logger.levelEnabler,
|
||||
level: zapcore.FatalLevel,
|
||||
print: logger.delegate.Fatal,
|
||||
printf: logger.delegate.Fatalf,
|
||||
}
|
||||
for _, option := range options {
|
||||
option.apply(logger)
|
||||
}
|
||||
return logger
|
||||
}
|
||||
|
||||
// printer implements Print, Printf, and Println operations for a Zap level.
|
||||
//
|
||||
// We use it to customize Debug vs Info, and Warn vs Fatal for Print and Fatal
|
||||
// respectively.
|
||||
type printer struct {
|
||||
enab zapcore.LevelEnabler
|
||||
level zapcore.Level
|
||||
print func(...interface{})
|
||||
printf func(string, ...interface{})
|
||||
}
|
||||
|
||||
func (v *printer) Print(args ...interface{}) {
|
||||
v.print(args...)
|
||||
}
|
||||
|
||||
func (v *printer) Printf(format string, args ...interface{}) {
|
||||
v.printf(format, args...)
|
||||
}
|
||||
|
||||
func (v *printer) Println(args ...interface{}) {
|
||||
if v.enab.Enabled(v.level) {
|
||||
v.print(sprintln(args))
|
||||
}
|
||||
}
|
||||
|
||||
// Logger adapts zap's Logger to be compatible with grpclog.LoggerV2 and the deprecated grpclog.Logger.
|
||||
type Logger struct {
|
||||
delegate *zap.SugaredLogger
|
||||
levelEnabler zapcore.LevelEnabler
|
||||
print *printer
|
||||
fatal *printer
|
||||
// printToDebug bool
|
||||
// fatalToWarn bool
|
||||
}
|
||||
|
||||
// Print implements grpclog.Logger.
|
||||
// Deprecated: use Info().
|
||||
func (l *Logger) Print(args ...interface{}) {
|
||||
l.print.Print(args...)
|
||||
}
|
||||
|
||||
// Printf implements grpclog.Logger.
|
||||
// Deprecated: use Infof().
|
||||
func (l *Logger) Printf(format string, args ...interface{}) {
|
||||
l.print.Printf(format, args...)
|
||||
}
|
||||
|
||||
// Println implements grpclog.Logger.
|
||||
// Deprecated: use Info().
|
||||
func (l *Logger) Println(args ...interface{}) {
|
||||
l.print.Println(args...)
|
||||
}
|
||||
|
||||
// Info implements grpclog.LoggerV2.
|
||||
func (l *Logger) Info(args ...interface{}) {
|
||||
l.delegate.Info(args...)
|
||||
}
|
||||
|
||||
// Infoln implements grpclog.LoggerV2.
|
||||
func (l *Logger) Infoln(args ...interface{}) {
|
||||
if l.levelEnabler.Enabled(zapcore.InfoLevel) {
|
||||
l.delegate.Info(sprintln(args))
|
||||
}
|
||||
}
|
||||
|
||||
// Infof implements grpclog.LoggerV2.
|
||||
func (l *Logger) Infof(format string, args ...interface{}) {
|
||||
l.delegate.Infof(format, args...)
|
||||
}
|
||||
|
||||
// Warning implements grpclog.LoggerV2.
|
||||
func (l *Logger) Warning(args ...interface{}) {
|
||||
l.delegate.Warn(args...)
|
||||
}
|
||||
|
||||
// Warningln implements grpclog.LoggerV2.
|
||||
func (l *Logger) Warningln(args ...interface{}) {
|
||||
if l.levelEnabler.Enabled(zapcore.WarnLevel) {
|
||||
l.delegate.Warn(sprintln(args))
|
||||
}
|
||||
}
|
||||
|
||||
// Warningf implements grpclog.LoggerV2.
|
||||
func (l *Logger) Warningf(format string, args ...interface{}) {
|
||||
l.delegate.Warnf(format, args...)
|
||||
}
|
||||
|
||||
// Error implements grpclog.LoggerV2.
|
||||
func (l *Logger) Error(args ...interface{}) {
|
||||
l.delegate.Error(args...)
|
||||
}
|
||||
|
||||
// Errorln implements grpclog.LoggerV2.
|
||||
func (l *Logger) Errorln(args ...interface{}) {
|
||||
if l.levelEnabler.Enabled(zapcore.ErrorLevel) {
|
||||
l.delegate.Error(sprintln(args))
|
||||
}
|
||||
}
|
||||
|
||||
// Errorf implements grpclog.LoggerV2.
|
||||
func (l *Logger) Errorf(format string, args ...interface{}) {
|
||||
l.delegate.Errorf(format, args...)
|
||||
}
|
||||
|
||||
// Fatal implements grpclog.LoggerV2.
|
||||
func (l *Logger) Fatal(args ...interface{}) {
|
||||
l.fatal.Print(args...)
|
||||
}
|
||||
|
||||
// Fatalln implements grpclog.LoggerV2.
|
||||
func (l *Logger) Fatalln(args ...interface{}) {
|
||||
l.fatal.Println(args...)
|
||||
}
|
||||
|
||||
// Fatalf implements grpclog.LoggerV2.
|
||||
func (l *Logger) Fatalf(format string, args ...interface{}) {
|
||||
l.fatal.Printf(format, args...)
|
||||
}
|
||||
|
||||
// V implements grpclog.LoggerV2.
|
||||
func (l *Logger) V(level int) bool {
|
||||
return l.levelEnabler.Enabled(_grpcToZapLevel[level])
|
||||
}
|
||||
|
||||
func sprintln(args []interface{}) string {
|
||||
s := fmt.Sprintln(args...)
|
||||
// Drop the new line character added by Sprintln
|
||||
return s[:len(s)-1]
|
||||
}
|
||||
Reference in New Issue
Block a user