Upgrade k8s package verison (#5358)

* upgrade k8s package version

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

* Script upgrade and code formatting.

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

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

23
vendor/go.uber.org/zap/.travis.yml generated vendored
View File

@@ -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
View File

@@ -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

View File

@@ -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
View File

@@ -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
View File

@@ -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
View File

@@ -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

View File

@@ -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
View File

@@ -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
View File

@@ -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
View File

@@ -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.

View File

@@ -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: &current})
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
View File

@@ -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
View File

@@ -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
View File

@@ -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
View File

@@ -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
View File

@@ -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
View File

@@ -0,0 +1,188 @@
// Copyright (c) 2021 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package zapcore
import (
"bufio"
"sync"
"time"
"go.uber.org/multierr"
)
const (
// _defaultBufferSize specifies the default size used by Buffer.
_defaultBufferSize = 256 * 1024 // 256 kB
// _defaultFlushInterval specifies the default flush interval for
// Buffer.
_defaultFlushInterval = 30 * time.Second
)
// A BufferedWriteSyncer is a WriteSyncer that buffers writes in-memory before
// flushing them to a wrapped WriteSyncer after reaching some limit, or at some
// fixed interval--whichever comes first.
//
// BufferedWriteSyncer is safe for concurrent use. You don't need to use
// zapcore.Lock for WriteSyncers with BufferedWriteSyncer.
type BufferedWriteSyncer struct {
// WS is the WriteSyncer around which BufferedWriteSyncer will buffer
// writes.
//
// This field is required.
WS WriteSyncer
// Size specifies the maximum amount of data the writer will buffered
// before flushing.
//
// Defaults to 256 kB if unspecified.
Size int
// FlushInterval specifies how often the writer should flush data if
// there have been no writes.
//
// Defaults to 30 seconds if unspecified.
FlushInterval time.Duration
// Clock, if specified, provides control of the source of time for the
// writer.
//
// Defaults to the system clock.
Clock Clock
// unexported fields for state
mu sync.Mutex
initialized bool // whether initialize() has run
stopped bool // whether Stop() has run
writer *bufio.Writer
ticker *time.Ticker
stop chan struct{} // closed when flushLoop should stop
done chan struct{} // closed when flushLoop has stopped
}
func (s *BufferedWriteSyncer) initialize() {
size := s.Size
if size == 0 {
size = _defaultBufferSize
}
flushInterval := s.FlushInterval
if flushInterval == 0 {
flushInterval = _defaultFlushInterval
}
if s.Clock == nil {
s.Clock = DefaultClock
}
s.ticker = s.Clock.NewTicker(flushInterval)
s.writer = bufio.NewWriterSize(s.WS, size)
s.stop = make(chan struct{})
s.done = make(chan struct{})
s.initialized = true
go s.flushLoop()
}
// Write writes log data into buffer syncer directly, multiple Write calls will be batched,
// and log data will be flushed to disk when the buffer is full or periodically.
func (s *BufferedWriteSyncer) Write(bs []byte) (int, error) {
s.mu.Lock()
defer s.mu.Unlock()
if !s.initialized {
s.initialize()
}
// To avoid partial writes from being flushed, we manually flush the existing buffer if:
// * The current write doesn't fit into the buffer fully, and
// * The buffer is not empty (since bufio will not split large writes when the buffer is empty)
if len(bs) > s.writer.Available() && s.writer.Buffered() > 0 {
if err := s.writer.Flush(); err != nil {
return 0, err
}
}
return s.writer.Write(bs)
}
// Sync flushes buffered log data into disk directly.
func (s *BufferedWriteSyncer) Sync() error {
s.mu.Lock()
defer s.mu.Unlock()
var err error
if s.initialized {
err = s.writer.Flush()
}
return multierr.Append(err, s.WS.Sync())
}
// flushLoop flushes the buffer at the configured interval until Stop is
// called.
func (s *BufferedWriteSyncer) flushLoop() {
defer close(s.done)
for {
select {
case <-s.ticker.C:
// we just simply ignore error here
// because the underlying bufio writer stores any errors
// and we return any error from Sync() as part of the close
_ = s.Sync()
case <-s.stop:
return
}
}
}
// Stop closes the buffer, cleans up background goroutines, and flushes
// remaining unwritten data.
func (s *BufferedWriteSyncer) Stop() (err error) {
var stopped bool
// Critical section.
func() {
s.mu.Lock()
defer s.mu.Unlock()
if !s.initialized {
return
}
stopped = s.stopped
if stopped {
return
}
s.stopped = true
s.ticker.Stop()
close(s.stop) // tell flushLoop to stop
<-s.done // and wait until it has
}()
// Don't call Sync on consecutive Stops.
if !stopped {
err = s.Sync()
}
return err
}

View File

@@ -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)
}

View File

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

View File

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

View File

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

View File

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

View File

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

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

@@ -0,0 +1,66 @@
// Copyright (c) 2020 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package zapcore
import "fmt"
type levelFilterCore struct {
core Core
level LevelEnabler
}
// NewIncreaseLevelCore creates a core that can be used to increase the level of
// an existing Core. It cannot be used to decrease the logging level, as it acts
// as a filter before calling the underlying core. If level decreases the log level,
// an error is returned.
func NewIncreaseLevelCore(core Core, level LevelEnabler) (Core, error) {
for l := _maxLevel; l >= _minLevel; l-- {
if !core.Enabled(l) && level.Enabled(l) {
return nil, fmt.Errorf("invalid increase level, as level %q is allowed by increased level, but not by existing core", l)
}
}
return &levelFilterCore{core, level}, nil
}
func (c *levelFilterCore) Enabled(lvl Level) bool {
return c.level.Enabled(lvl)
}
func (c *levelFilterCore) With(fields []Field) Core {
return &levelFilterCore{c.core.With(fields), c.level}
}
func (c *levelFilterCore) Check(ent Entry, ce *CheckedEntry) *CheckedEntry {
if !c.Enabled(ent.Level) {
return ce
}
return c.core.Check(ent, ce)
}
func (c *levelFilterCore) Write(ent Entry, fields []Field) error {
return c.core.Write(ent, fields)
}
func (c *levelFilterCore) Sync() error {
return c.core.Sync()
}

View File

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

View File

@@ -23,6 +23,10 @@ package zapcore
// ObjectMarshaler allows user-defined types to efficiently add themselves to the
// logging context, and to selectively omit information which shouldn't be
// included in logs (e.g., passwords).
//
// Note: ObjectMarshaler is only used when zap.Object is used or when
// passed directly to zap.Any. It is not used when reflection-based
// encoding is used.
type ObjectMarshaler interface {
MarshalLogObject(ObjectEncoder) error
}
@@ -39,6 +43,10 @@ func (f ObjectMarshalerFunc) MarshalLogObject(enc ObjectEncoder) error {
// ArrayMarshaler allows user-defined types to efficiently add themselves to the
// logging context, and to selectively omit information which shouldn't be
// included in logs (e.g., passwords).
//
// Note: ArrayMarshaler is only used when zap.Array is used or when
// passed directly to zap.Any. It is not used when reflection-based
// encoding is used.
type ArrayMarshaler interface {
MarshalLogArray(ArrayEncoder) error
}

View File

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

View File

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

241
vendor/go.uber.org/zap/zapgrpc/zapgrpc.go generated vendored Normal file
View 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]
}