mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 07:36:27 -04:00
Bump github.com/sirupsen/logrus from 1.9.4 to 1.10.2
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.9.4 to 1.10.2. - [Release notes](https://github.com/sirupsen/logrus/releases) - [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md) - [Commits](https://github.com/sirupsen/logrus/compare/v1.9.4...v1.10.2) --- updated-dependencies: - dependency-name: github.com/sirupsen/logrus dependency-version: 1.10.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
parent
9aa2c0b85a
commit
9182ac9ebc
2
go.mod
2
go.mod
|
|
@ -34,7 +34,7 @@ require (
|
||||||
github.com/samber/lo v1.53.0
|
github.com/samber/lo v1.53.0
|
||||||
github.com/sanity-io/litter v1.5.8
|
github.com/sanity-io/litter v1.5.8
|
||||||
github.com/sasha-s/go-deadlock v0.3.9
|
github.com/sasha-s/go-deadlock v0.3.9
|
||||||
github.com/sirupsen/logrus v1.9.4
|
github.com/sirupsen/logrus v1.10.2
|
||||||
github.com/spf13/afero v1.15.0
|
github.com/spf13/afero v1.15.0
|
||||||
github.com/spkg/bom v1.0.1
|
github.com/spkg/bom v1.0.1
|
||||||
github.com/stefanhaller/git-todo-parser v0.0.7-0.20250905083220-c50528f08304
|
github.com/stefanhaller/git-todo-parser v0.0.7-0.20250905083220-c50528f08304
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -111,8 +111,8 @@ github.com/sanity-io/litter v1.5.8 h1:uM/2lKrWdGbRXDrIq08Lh9XtVYoeGtcQxk9rtQ7+rY
|
||||||
github.com/sanity-io/litter v1.5.8/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U=
|
github.com/sanity-io/litter v1.5.8/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U=
|
||||||
github.com/sasha-s/go-deadlock v0.3.9 h1:fiaT9rB7g5sr5ddNZvlwheclN9IP86eFW9WgqlEQV+w=
|
github.com/sasha-s/go-deadlock v0.3.9 h1:fiaT9rB7g5sr5ddNZvlwheclN9IP86eFW9WgqlEQV+w=
|
||||||
github.com/sasha-s/go-deadlock v0.3.9/go.mod h1:KuZj51ZFmx42q/mPaYbRk0P1xcwe697zsJKE03vD4/Y=
|
github.com/sasha-s/go-deadlock v0.3.9/go.mod h1:KuZj51ZFmx42q/mPaYbRk0P1xcwe697zsJKE03vD4/Y=
|
||||||
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
|
github.com/sirupsen/logrus v1.10.2 h1:G2SED73/qrAu6YwbdxOD6peLkCBI3z7L+ykJFTXJBBo=
|
||||||
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
|
github.com/sirupsen/logrus v1.10.2/go.mod h1:SLEg8TqYulVKKfIGHldVp2K2aYz2DKSVBq4g/H5bR7Q=
|
||||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||||
github.com/spkg/bom v1.0.1 h1:tl8kQ2sufL/wDEJa9me1jnQYEpDB7LqYGNkwCVR5GLs=
|
github.com/spkg/bom v1.0.1 h1:tl8kQ2sufL/wDEJa9me1jnQYEpDB7LqYGNkwCVR5GLs=
|
||||||
|
|
|
||||||
48
vendor/github.com/sirupsen/logrus/.golangci.yml
generated
vendored
48
vendor/github.com/sirupsen/logrus/.golangci.yml
generated
vendored
|
|
@ -1,12 +1,9 @@
|
||||||
version: "2"
|
version: "2"
|
||||||
run:
|
|
||||||
tests: false
|
|
||||||
linters:
|
linters:
|
||||||
enable:
|
enable:
|
||||||
- asasalint
|
- asasalint
|
||||||
- asciicheck
|
- asciicheck
|
||||||
- bidichk
|
- bidichk
|
||||||
- bodyclose
|
|
||||||
- contextcheck
|
- contextcheck
|
||||||
- durationcheck
|
- durationcheck
|
||||||
- errchkjson
|
- errchkjson
|
||||||
|
|
@ -22,46 +19,21 @@ linters:
|
||||||
- nilerr
|
- nilerr
|
||||||
- nilnesserr
|
- nilnesserr
|
||||||
- noctx
|
- noctx
|
||||||
- protogetter
|
|
||||||
- reassign
|
- reassign
|
||||||
- recvcheck
|
- recvcheck
|
||||||
- rowserrcheck
|
|
||||||
- spancheck
|
|
||||||
- sqlclosecheck
|
|
||||||
- testifylint
|
- testifylint
|
||||||
- unparam
|
- unparam
|
||||||
- zerologlint
|
|
||||||
disable:
|
|
||||||
- prealloc
|
|
||||||
settings:
|
|
||||||
errcheck:
|
|
||||||
check-type-assertions: false
|
|
||||||
check-blank: false
|
|
||||||
lll:
|
|
||||||
line-length: 100
|
|
||||||
tab-width: 4
|
|
||||||
prealloc:
|
|
||||||
simple: false
|
|
||||||
range-loops: false
|
|
||||||
for-loops: false
|
|
||||||
whitespace:
|
|
||||||
multi-if: false
|
|
||||||
multi-func: false
|
|
||||||
exclusions:
|
exclusions:
|
||||||
generated: lax
|
|
||||||
presets:
|
presets:
|
||||||
- comments
|
|
||||||
- common-false-positives
|
|
||||||
- legacy
|
- legacy
|
||||||
- std-error-handling
|
- std-error-handling
|
||||||
paths:
|
rules:
|
||||||
- third_party$
|
# Exclude some linters from running on tests files.
|
||||||
- builtin$
|
- path: _test\.go
|
||||||
- examples$
|
linters:
|
||||||
formatters:
|
- gosec
|
||||||
exclusions:
|
- musttag
|
||||||
generated: lax
|
- noctx # TODO: enable once we switch to Go 1.24+.
|
||||||
paths:
|
- linters: # TODO: remove once golangci-lint is updated with https://github.com/golangci/golangci-lint/pull/6584
|
||||||
- third_party$
|
- gocheckcompilerdirectives
|
||||||
- builtin$
|
text: 'compiler directive unrecognized: //go:fix'
|
||||||
- examples$
|
|
||||||
|
|
|
||||||
15
vendor/github.com/sirupsen/logrus/.travis.yml
generated
vendored
15
vendor/github.com/sirupsen/logrus/.travis.yml
generated
vendored
|
|
@ -1,15 +0,0 @@
|
||||||
language: go
|
|
||||||
go_import_path: github.com/sirupsen/logrus
|
|
||||||
git:
|
|
||||||
depth: 1
|
|
||||||
env:
|
|
||||||
- GO111MODULE=on
|
|
||||||
go: 1.15.x
|
|
||||||
os: linux
|
|
||||||
install:
|
|
||||||
- ./travis/install.sh
|
|
||||||
script:
|
|
||||||
- cd ci
|
|
||||||
- go run mage.go -v -w ../ crossBuild
|
|
||||||
- go run mage.go -v -w ../ lint
|
|
||||||
- go run mage.go -v -w ../ test
|
|
||||||
246
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
246
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
|
|
@ -1,90 +1,253 @@
|
||||||
# 1.8.1
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## 1.10.2
|
||||||
|
|
||||||
|
Changed:
|
||||||
|
|
||||||
|
* Update `github.com/stretchr/testify` to v1.12.1, removing the legacy
|
||||||
|
`gopkg.in/yaml.v3` dependency.
|
||||||
|
|
||||||
|
## 1.10.1
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
|
||||||
|
* Fix a regression introduced in v1.10.0 where `TextFormatter` could panic
|
||||||
|
when formatting nil or panicking `error` and `fmt.Stringer` values.
|
||||||
|
* Allow function-backed implementations of `error` as field values.
|
||||||
|
|
||||||
|
## 1.10.0
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
|
||||||
|
* Fix reentrant logging deadlocks in formatter paths.
|
||||||
|
* Fix race conditions in formatter and entry handling.
|
||||||
|
* Fix generic `Log`, `Logf`, `Logln`, and `LogFn` methods unexpectedly
|
||||||
|
panicking when called with `PanicLevel`. Use the corresponding `Panic`
|
||||||
|
methods when panic behavior is desired.
|
||||||
|
* Improve concurrency safety around formatter and hook access.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
|
||||||
|
* Add `slog` hook for forwarding Logrus entries to `log/slog`.
|
||||||
|
* Add `slog.Handler` for forwarding `log/slog` records to a Logrus logger,
|
||||||
|
including levels, fields, groups, context, time, and optional caller
|
||||||
|
reporting. The hook and handler can also be combined to help migrate
|
||||||
|
between Logrus and `log/slog`.
|
||||||
|
* Add minimal, composable logging interfaces for each log level. This enables
|
||||||
|
consumers to depend on narrower interfaces, making it easier to substitute
|
||||||
|
or adapt logging implementations.
|
||||||
|
* Allow `Entry.Caller` to be set explicitly and preserve it across derived
|
||||||
|
entries, enabling custom caller detection without Logrus overwriting
|
||||||
|
caller information when `ReportCaller` is enabled.
|
||||||
|
|
||||||
|
Changed:
|
||||||
|
|
||||||
|
* Raise minimum supported Go version to 1.23.
|
||||||
|
* TextFormatter now renders `[]byte` values as raw/quoted strings instead of slice-of-ints.
|
||||||
|
* TextFormatter now uses distinct dimmed colors for debug and trace output.
|
||||||
|
* TextFormatter now automatically enables colors on Windows terminals with ANSI support,
|
||||||
|
matching the behavior on other platforms.
|
||||||
|
* `Entry.HasCaller` is now deprecated in favor of checking `Entry.Caller` directly.
|
||||||
|
* Deprecated `MutexWrap`, which was unintentionally exposed as public API.
|
||||||
|
It remains available as an alias for compatibility but should not be used
|
||||||
|
directly.
|
||||||
|
|
||||||
|
Performance:
|
||||||
|
|
||||||
|
* Significantly improve TextFormatter performance and reduce allocations.
|
||||||
|
* Optimize common Entry and Logger hot paths.
|
||||||
|
* Reduce allocations in caller reporting.
|
||||||
|
* ~17% lower geomean runtime and ~27% higher formatter throughput overall.
|
||||||
|
* Common enabled logging paths are ~30–44% faster.
|
||||||
|
* TextFormatter paths are up to ~40% faster, with allocation counts reduced
|
||||||
|
by 25–74% across the measured formatter cases.
|
||||||
|
|
||||||
|
|
||||||
|
## 1.9.4
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
|
||||||
|
* Remove uses of deprecated `ioutil` package
|
||||||
|
|
||||||
|
Features:
|
||||||
|
|
||||||
|
* Add GNU/Hurd support
|
||||||
|
* Add WASI wasip1 support
|
||||||
|
|
||||||
Code quality:
|
Code quality:
|
||||||
|
|
||||||
|
* Update minimum supported Go version to 1.17
|
||||||
|
* Documentation updates
|
||||||
|
|
||||||
|
|
||||||
|
## 1.9.3
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
|
||||||
|
* Re-apply fix for potential denial of service in logrus.Writer() when logging >64KB single-line payloads without newlines (#1376)
|
||||||
|
* Fix panic in Writer
|
||||||
|
|
||||||
|
|
||||||
|
## 1.9.2
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
|
||||||
|
* Revert Writer DoS fix (#1376) due to regression
|
||||||
|
|
||||||
|
|
||||||
|
## 1.9.1
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
|
||||||
|
* Fix potential denial of service in logrus.Writer() when logging >64KB single-line payloads without newlines (#1376)
|
||||||
|
|
||||||
|
|
||||||
|
## 1.9.0
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
|
||||||
|
* Multiple concurrency and race condition fixes
|
||||||
|
* Improve Windows terminal and ANSI handling
|
||||||
|
|
||||||
|
Code quality:
|
||||||
|
|
||||||
|
* Internal cleanups and modernization
|
||||||
|
|
||||||
|
|
||||||
|
## 1.8.3
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
|
||||||
|
* Fix potential denial of service in logrus.Writer() when logging >64KB single-line payloads without newlines (#1376)
|
||||||
|
|
||||||
|
|
||||||
|
## 1.8.2
|
||||||
|
|
||||||
|
Features:
|
||||||
|
|
||||||
|
* Add support for the logger private buffer pool (#1253)
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
|
||||||
|
* Fix race condition for SetFormatter and SetReportCaller
|
||||||
|
* Fix data race in hooks test package
|
||||||
|
|
||||||
|
## 1.8.1
|
||||||
|
|
||||||
|
Code quality:
|
||||||
|
|
||||||
* move magefile in its own subdir/submodule to remove magefile dependency on logrus consumer
|
* move magefile in its own subdir/submodule to remove magefile dependency on logrus consumer
|
||||||
* improve timestamp format documentation
|
* improve timestamp format documentation
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
|
|
||||||
* fix race condition on logger hooks
|
* fix race condition on logger hooks
|
||||||
|
|
||||||
|
|
||||||
# 1.8.0
|
## 1.8.0
|
||||||
|
|
||||||
Correct versioning number replacing v1.7.1.
|
Correct versioning number replacing v1.7.1.
|
||||||
|
|
||||||
# 1.7.1
|
## 1.7.1
|
||||||
|
|
||||||
Beware this release has introduced a new public API and its semver is therefore incorrect.
|
Beware this release has introduced a new public API and its semver is therefore incorrect.
|
||||||
|
|
||||||
Code quality:
|
Code quality:
|
||||||
|
|
||||||
* use go 1.15 in travis
|
* use go 1.15 in travis
|
||||||
* use magefile as task runner
|
* use magefile as task runner
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
|
|
||||||
* small fixes about new go 1.13 error formatting system
|
* small fixes about new go 1.13 error formatting system
|
||||||
* Fix for long time race condiction with mutating data hooks
|
* Fix for long time race condiction with mutating data hooks
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
* build support for zos
|
* build support for zos
|
||||||
|
|
||||||
# 1.7.0
|
## 1.7.0
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
|
|
||||||
* the dependency toward a windows terminal library has been removed
|
* the dependency toward a windows terminal library has been removed
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
* a new buffer pool management API has been added
|
* a new buffer pool management API has been added
|
||||||
* a set of `<LogLevel>Fn()` functions have been added
|
* a set of `<LogLevel>Fn()` functions have been added
|
||||||
|
|
||||||
# 1.6.0
|
## 1.6.0
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
|
|
||||||
* end of line cleanup
|
* end of line cleanup
|
||||||
* revert the entry concurrency bug fix which leads to deadlock under some circumstances
|
* revert the entry concurrency bug fix which leads to deadlock under some circumstances
|
||||||
* update dependency on go-windows-terminal-sequences to fix a crash with go 1.14
|
* update dependency on go-windows-terminal-sequences to fix a crash with go 1.14
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
* add an option to the `TextFormatter` to completely disable fields quoting
|
* add an option to the `TextFormatter` to completely disable fields quoting
|
||||||
|
|
||||||
# 1.5.0
|
## 1.5.0
|
||||||
|
|
||||||
Code quality:
|
Code quality:
|
||||||
|
|
||||||
* add golangci linter run on travis
|
* add golangci linter run on travis
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
|
|
||||||
* add mutex for hooks concurrent access on `Entry` data
|
* add mutex for hooks concurrent access on `Entry` data
|
||||||
* caller function field for go1.14
|
* caller function field for go1.14
|
||||||
* fix build issue for gopherjs target
|
* fix build issue for gopherjs target
|
||||||
|
|
||||||
Feature:
|
Feature:
|
||||||
|
|
||||||
* add an hooks/writer sub-package whose goal is to split output on different stream depending on the trace level
|
* add an hooks/writer sub-package whose goal is to split output on different stream depending on the trace level
|
||||||
* add a `DisableHTMLEscape` option in the `JSONFormatter`
|
* add a `DisableHTMLEscape` option in the `JSONFormatter`
|
||||||
* add `ForceQuote` and `PadLevelText` options in the `TextFormatter`
|
* add `ForceQuote` and `PadLevelText` options in the `TextFormatter`
|
||||||
|
|
||||||
# 1.4.2
|
## 1.4.2
|
||||||
|
|
||||||
* Fixes build break for plan9, nacl, solaris
|
* Fixes build break for plan9, nacl, solaris
|
||||||
# 1.4.1
|
|
||||||
|
## 1.4.1
|
||||||
|
|
||||||
This new release introduces:
|
This new release introduces:
|
||||||
|
|
||||||
* Enhance TextFormatter to not print caller information when they are empty (#944)
|
* Enhance TextFormatter to not print caller information when they are empty (#944)
|
||||||
* Remove dependency on golang.org/x/crypto (#932, #943)
|
* Remove dependency on golang.org/x/crypto (#932, #943)
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
|
|
||||||
* Fix Entry.WithContext method to return a copy of the initial entry (#941)
|
* Fix Entry.WithContext method to return a copy of the initial entry (#941)
|
||||||
|
|
||||||
# 1.4.0
|
## 1.4.0
|
||||||
|
|
||||||
This new release introduces:
|
This new release introduces:
|
||||||
|
|
||||||
* Add `DeferExitHandler`, similar to `RegisterExitHandler` but prepending the handler to the list of handlers (semantically like `defer`) (#848).
|
* Add `DeferExitHandler`, similar to `RegisterExitHandler` but prepending the handler to the list of handlers (semantically like `defer`) (#848).
|
||||||
* Add `CallerPrettyfier` to `JSONFormatter` and `TextFormatter` (#909, #911)
|
* Add `CallerPrettyfier` to `JSONFormatter` and `TextFormatter` (#909, #911)
|
||||||
* Add `Entry.WithContext()` and `Entry.Context`, to set a context on entries to be used e.g. in hooks (#919).
|
* Add `Entry.WithContext()` and `Entry.Context`, to set a context on entries to be used e.g. in hooks (#919).
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
|
|
||||||
* Fix wrong method calls `Logger.Print` and `Logger.Warningln` (#893).
|
* Fix wrong method calls `Logger.Print` and `Logger.Warningln` (#893).
|
||||||
* Update `Entry.Logf` to not do string formatting unless the log level is enabled (#903)
|
* Update `Entry.Logf` to not do string formatting unless the log level is enabled (#903)
|
||||||
* Fix infinite recursion on unknown `Level.String()` (#907)
|
* Fix infinite recursion on unknown `Level.String()` (#907)
|
||||||
* Fix race condition in `getCaller` (#916).
|
* Fix race condition in `getCaller` (#916).
|
||||||
|
|
||||||
|
|
||||||
# 1.3.0
|
## 1.3.0
|
||||||
|
|
||||||
This new release introduces:
|
This new release introduces:
|
||||||
|
|
||||||
* Log, Logf, Logln functions for Logger and Entry that take a Level
|
* Log, Logf, Logln functions for Logger and Entry that take a Level
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
|
|
||||||
* Building prometheus node_exporter on AIX (#840)
|
* Building prometheus node_exporter on AIX (#840)
|
||||||
* Race condition in TextFormatter (#468)
|
* Race condition in TextFormatter (#468)
|
||||||
* Travis CI import path (#868)
|
* Travis CI import path (#868)
|
||||||
|
|
@ -92,20 +255,26 @@ Fixes:
|
||||||
* Pointer to func as field in JSONFormatter (#870)
|
* Pointer to func as field in JSONFormatter (#870)
|
||||||
* Properly marshal Levels (#873)
|
* Properly marshal Levels (#873)
|
||||||
|
|
||||||
# 1.2.0
|
## 1.2.0
|
||||||
|
|
||||||
This new release introduces:
|
This new release introduces:
|
||||||
|
|
||||||
* A new method `SetReportCaller` in the `Logger` to enable the file, line and calling function from which the trace has been issued
|
* A new method `SetReportCaller` in the `Logger` to enable the file, line and calling function from which the trace has been issued
|
||||||
* A new trace level named `Trace` whose level is below `Debug`
|
* A new trace level named `Trace` whose level is below `Debug`
|
||||||
* A configurable exit function to be called upon a Fatal trace
|
* A configurable exit function to be called upon a Fatal trace
|
||||||
* The `Level` object now implements `encoding.TextUnmarshaler` interface
|
* The `Level` object now implements `encoding.TextUnmarshaler` interface
|
||||||
|
|
||||||
# 1.1.1
|
## 1.1.1
|
||||||
|
|
||||||
This is a bug fix release.
|
This is a bug fix release.
|
||||||
|
|
||||||
* fix the build break on Solaris
|
* fix the build break on Solaris
|
||||||
* don't drop a whole trace in JSONFormatter when a field param is a function pointer which can not be serialized
|
* don't drop a whole trace in JSONFormatter when a field param is a function pointer which can not be serialized
|
||||||
|
|
||||||
# 1.1.0
|
## 1.1.0
|
||||||
|
|
||||||
This new release introduces:
|
This new release introduces:
|
||||||
|
|
||||||
* several fixes:
|
* several fixes:
|
||||||
* a fix for a race condition on entry formatting
|
* a fix for a race condition on entry formatting
|
||||||
* proper cleanup of previously used entries before putting them back in the pool
|
* proper cleanup of previously used entries before putting them back in the pool
|
||||||
|
|
@ -122,9 +291,10 @@ This new release introduces:
|
||||||
* the field sort function is now configurable for text formatter
|
* the field sort function is now configurable for text formatter
|
||||||
* the CLICOLOR and CLICOLOR\_FORCE environment variable support in text formater
|
* the CLICOLOR and CLICOLOR\_FORCE environment variable support in text formater
|
||||||
|
|
||||||
# 1.0.6
|
## 1.0.6
|
||||||
|
|
||||||
This new release introduces:
|
This new release introduces:
|
||||||
|
|
||||||
* a new api WithTime which allows to easily force the time of the log entry
|
* a new api WithTime which allows to easily force the time of the log entry
|
||||||
which is mostly useful for logger wrapper
|
which is mostly useful for logger wrapper
|
||||||
* a fix reverting the immutability of the entry given as parameter to the hooks
|
* a fix reverting the immutability of the entry given as parameter to the hooks
|
||||||
|
|
@ -134,71 +304,71 @@ This new release introduces:
|
||||||
* a new configuration of the textformatter to configure the name of the default keys
|
* a new configuration of the textformatter to configure the name of the default keys
|
||||||
* a new configuration of the text formatter to disable the level truncation
|
* a new configuration of the text formatter to disable the level truncation
|
||||||
|
|
||||||
# 1.0.5
|
## 1.0.5
|
||||||
|
|
||||||
* Fix hooks race (#707)
|
* Fix hooks race (#707)
|
||||||
* Fix panic deadlock (#695)
|
* Fix panic deadlock (#695)
|
||||||
|
|
||||||
# 1.0.4
|
## 1.0.4
|
||||||
|
|
||||||
* Fix race when adding hooks (#612)
|
* Fix race when adding hooks (#612)
|
||||||
* Fix terminal check in AppEngine (#635)
|
* Fix terminal check in AppEngine (#635)
|
||||||
|
|
||||||
# 1.0.3
|
## 1.0.3
|
||||||
|
|
||||||
* Replace example files with testable examples
|
* Replace example files with testable examples
|
||||||
|
|
||||||
# 1.0.2
|
## 1.0.2
|
||||||
|
|
||||||
* bug: quote non-string values in text formatter (#583)
|
* bug: quote non-string values in text formatter (#583)
|
||||||
* Make (*Logger) SetLevel a public method
|
* Make (*Logger) SetLevel a public method
|
||||||
|
|
||||||
# 1.0.1
|
## 1.0.1
|
||||||
|
|
||||||
* bug: fix escaping in text formatter (#575)
|
* bug: fix escaping in text formatter (#575)
|
||||||
|
|
||||||
# 1.0.0
|
## 1.0.0
|
||||||
|
|
||||||
* Officially changed name to lower-case
|
* Officially changed name to lower-case
|
||||||
* bug: colors on Windows 10 (#541)
|
* bug: colors on Windows 10 (#541)
|
||||||
* bug: fix race in accessing level (#512)
|
* bug: fix race in accessing level (#512)
|
||||||
|
|
||||||
# 0.11.5
|
## 0.11.5
|
||||||
|
|
||||||
* feature: add writer and writerlevel to entry (#372)
|
* feature: add writer and writerlevel to entry (#372)
|
||||||
|
|
||||||
# 0.11.4
|
## 0.11.4
|
||||||
|
|
||||||
* bug: fix undefined variable on solaris (#493)
|
* bug: fix undefined variable on solaris (#493)
|
||||||
|
|
||||||
# 0.11.3
|
## 0.11.3
|
||||||
|
|
||||||
* formatter: configure quoting of empty values (#484)
|
* formatter: configure quoting of empty values (#484)
|
||||||
* formatter: configure quoting character (default is `"`) (#484)
|
* formatter: configure quoting character (default is `"`) (#484)
|
||||||
* bug: fix not importing io correctly in non-linux environments (#481)
|
* bug: fix not importing io correctly in non-linux environments (#481)
|
||||||
|
|
||||||
# 0.11.2
|
## 0.11.2
|
||||||
|
|
||||||
* bug: fix windows terminal detection (#476)
|
* bug: fix windows terminal detection (#476)
|
||||||
|
|
||||||
# 0.11.1
|
## 0.11.1
|
||||||
|
|
||||||
* bug: fix tty detection with custom out (#471)
|
* bug: fix tty detection with custom out (#471)
|
||||||
|
|
||||||
# 0.11.0
|
## 0.11.0
|
||||||
|
|
||||||
* performance: Use bufferpool to allocate (#370)
|
* performance: Use bufferpool to allocate (#370)
|
||||||
* terminal: terminal detection for app-engine (#343)
|
* terminal: terminal detection for app-engine (#343)
|
||||||
* feature: exit handler (#375)
|
* feature: exit handler (#375)
|
||||||
|
|
||||||
# 0.10.0
|
## 0.10.0
|
||||||
|
|
||||||
* feature: Add a test hook (#180)
|
* feature: Add a test hook (#180)
|
||||||
* feature: `ParseLevel` is now case-insensitive (#326)
|
* feature: `ParseLevel` is now case-insensitive (#326)
|
||||||
* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308)
|
* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308)
|
||||||
* performance: avoid re-allocations on `WithFields` (#335)
|
* performance: avoid re-allocations on `WithFields` (#335)
|
||||||
|
|
||||||
# 0.9.0
|
## 0.9.0
|
||||||
|
|
||||||
* logrus/text_formatter: don't emit empty msg
|
* logrus/text_formatter: don't emit empty msg
|
||||||
* logrus/hooks/airbrake: move out of main repository
|
* logrus/hooks/airbrake: move out of main repository
|
||||||
|
|
@ -210,25 +380,25 @@ This new release introduces:
|
||||||
* logrus/core: support `WithError` on logger
|
* logrus/core: support `WithError` on logger
|
||||||
* logrus/core: Solaris support
|
* logrus/core: Solaris support
|
||||||
|
|
||||||
# 0.8.7
|
## 0.8.7
|
||||||
|
|
||||||
* logrus/core: fix possible race (#216)
|
* logrus/core: fix possible race (#216)
|
||||||
* logrus/doc: small typo fixes and doc improvements
|
* logrus/doc: small typo fixes and doc improvements
|
||||||
|
|
||||||
|
|
||||||
# 0.8.6
|
## 0.8.6
|
||||||
|
|
||||||
* hooks/raven: allow passing an initialized client
|
* hooks/raven: allow passing an initialized client
|
||||||
|
|
||||||
# 0.8.5
|
## 0.8.5
|
||||||
|
|
||||||
* logrus/core: revert #208
|
* logrus/core: revert #208
|
||||||
|
|
||||||
# 0.8.4
|
## 0.8.4
|
||||||
|
|
||||||
* formatter/text: fix data race (#218)
|
* formatter/text: fix data race (#218)
|
||||||
|
|
||||||
# 0.8.3
|
## 0.8.3
|
||||||
|
|
||||||
* logrus/core: fix entry log level (#208)
|
* logrus/core: fix entry log level (#208)
|
||||||
* logrus/core: improve performance of text formatter by 40%
|
* logrus/core: improve performance of text formatter by 40%
|
||||||
|
|
@ -236,24 +406,24 @@ This new release introduces:
|
||||||
* logrus/core: add support for DragonflyBSD and NetBSD
|
* logrus/core: add support for DragonflyBSD and NetBSD
|
||||||
* formatter/text: print structs more verbosely
|
* formatter/text: print structs more verbosely
|
||||||
|
|
||||||
# 0.8.2
|
## 0.8.2
|
||||||
|
|
||||||
* logrus: fix more Fatal family functions
|
* logrus: fix more Fatal family functions
|
||||||
|
|
||||||
# 0.8.1
|
## 0.8.1
|
||||||
|
|
||||||
* logrus: fix not exiting on `Fatalf` and `Fatalln`
|
* logrus: fix not exiting on `Fatalf` and `Fatalln`
|
||||||
|
|
||||||
# 0.8.0
|
## 0.8.0
|
||||||
|
|
||||||
* logrus: defaults to stderr instead of stdout
|
* logrus: defaults to stderr instead of stdout
|
||||||
* hooks/sentry: add special field for `*http.Request`
|
* hooks/sentry: add special field for `*http.Request`
|
||||||
* formatter/text: ignore Windows for colors
|
* formatter/text: ignore Windows for colors
|
||||||
|
|
||||||
# 0.7.3
|
## 0.7.3
|
||||||
|
|
||||||
* formatter/\*: allow configuration of timestamp layout
|
* formatter/\*: allow configuration of timestamp layout
|
||||||
|
|
||||||
# 0.7.2
|
## 0.7.2
|
||||||
|
|
||||||
* formatter/text: Add configuration option for time format (#158)
|
* formatter/text: Add configuration option for time format (#158)
|
||||||
|
|
|
||||||
92
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
92
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
|
|
@ -3,13 +3,10 @@
|
||||||
Logrus is a structured logger for Go (golang), completely API compatible with
|
Logrus is a structured logger for Go (golang), completely API compatible with
|
||||||
the standard library logger.
|
the standard library logger.
|
||||||
|
|
||||||
**Logrus is in maintenance-mode.** We will not be introducing new features. It's
|
**Logrus is in maintenance mode.** The project focuses on security, bug fixes,
|
||||||
simply too hard to do in a way that won't break many people's projects, which is
|
and performance improvements. New features are not planned, aside from changes
|
||||||
the last thing you want from your Logging library (again...).
|
required to provide interoperability with other logging ecosystems (e.g., Go's
|
||||||
|
[log/slog](https://pkg.go.dev/log/slog)).
|
||||||
This does not mean Logrus is dead. Logrus will continue to be maintained for
|
|
||||||
security, (backwards compatible) bug fixes, and performance (where we are
|
|
||||||
limited by the interface).
|
|
||||||
|
|
||||||
I believe Logrus' biggest contribution is to have played a part in today's
|
I believe Logrus' biggest contribution is to have played a part in today's
|
||||||
widespread use of structured logging in Golang. There doesn't seem to be a
|
widespread use of structured logging in Golang. There doesn't seem to be a
|
||||||
|
|
@ -23,18 +20,6 @@ about structured logging in Go today. Check out, for example,
|
||||||
[zap]: https://github.com/uber-go/zap
|
[zap]: https://github.com/uber-go/zap
|
||||||
[apex]: https://github.com/apex/log
|
[apex]: https://github.com/apex/log
|
||||||
|
|
||||||
**Seeing weird case-sensitive problems?** It's in the past been possible to
|
|
||||||
import Logrus as both upper- and lower-case. Due to the Go package environment,
|
|
||||||
this caused issues in the community and we needed a standard. Some environments
|
|
||||||
experienced problems with the upper-case variant, so the lower-case was decided.
|
|
||||||
Everything using `logrus` will need to use the lower-case:
|
|
||||||
`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
|
|
||||||
|
|
||||||
To fix Glide, see [these
|
|
||||||
comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
|
|
||||||
For an in-depth explanation of the casing issue, see [this
|
|
||||||
comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276).
|
|
||||||
|
|
||||||
Nicely color-coded in development (when a TTY is attached, otherwise just
|
Nicely color-coded in development (when a TTY is attached, otherwise just
|
||||||
plain text):
|
plain text):
|
||||||
|
|
||||||
|
|
@ -43,35 +28,27 @@ plain text):
|
||||||
With `logrus.SetFormatter(&logrus.JSONFormatter{})`, for easy parsing by logstash
|
With `logrus.SetFormatter(&logrus.JSONFormatter{})`, for easy parsing by logstash
|
||||||
or Splunk:
|
or Splunk:
|
||||||
|
|
||||||
```text
|
```json lines
|
||||||
{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the
|
{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
|
||||||
ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
|
{"level":"warning","msg":"The group's number increased tremendously!","number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"}
|
||||||
|
{"animal":"walrus","level":"info","msg":"A giant walrus appears!","size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"}
|
||||||
{"level":"warning","msg":"The group's number increased tremendously!",
|
{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.","size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"}
|
||||||
"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"}
|
{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,"time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
|
||||||
|
|
||||||
{"animal":"walrus","level":"info","msg":"A giant walrus appears!",
|
|
||||||
"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"}
|
|
||||||
|
|
||||||
{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.",
|
|
||||||
"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"}
|
|
||||||
|
|
||||||
{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,
|
|
||||||
"time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
With the default `logrus.SetFormatter(&logrus.TextFormatter{})` when a TTY is not
|
With the default `logrus.SetFormatter(&logrus.TextFormatter{})` when a TTY is not
|
||||||
attached, the output is compatible with the
|
attached, the output is compatible with the
|
||||||
[logfmt](https://pkg.go.dev/github.com/kr/logfmt) format:
|
[logfmt](https://pkg.go.dev/github.com/kr/logfmt) format:
|
||||||
|
|
||||||
```text
|
```bash
|
||||||
time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
|
time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
|
||||||
time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
|
time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
|
||||||
time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
|
time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
|
||||||
time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
|
time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
|
||||||
time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
|
time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
|
||||||
time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true
|
time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" animal=orca err="It's over 9000!" number=100 omg=true size=9009
|
||||||
```
|
```
|
||||||
|
|
||||||
To ensure this behaviour even if a TTY is attached, set your formatter as follows:
|
To ensure this behaviour even if a TTY is attached, set your formatter as follows:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
|
@ -88,29 +65,32 @@ If you wish to add the calling method as a field, instruct the logger via:
|
||||||
```go
|
```go
|
||||||
logrus.SetReportCaller(true)
|
logrus.SetReportCaller(true)
|
||||||
```
|
```
|
||||||
|
|
||||||
This adds the caller as 'method' like so:
|
This adds the caller as 'method' like so:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by",
|
{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by","time":"2014-03-10 19:57:38.562543129 -0400 EDT"}
|
||||||
"time":"2014-03-10 19:57:38.562543129 -0400 EDT"}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```text
|
```bash
|
||||||
time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcreatures.migrate msg="a penguin swims by" animal=penguin
|
time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcreatures.migrate msg="a penguin swims by" animal=penguin
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that this does add measurable overhead - the cost will depend on the version of Go, but is
|
Note that this does add measurable overhead - the cost will depend on the version of Go, but is
|
||||||
between 20 and 40% in recent tests with 1.6 and 1.7. You can validate this in your
|
between 20 and 40% in recent tests with 1.6 and 1.7. You can validate this in your
|
||||||
environment via benchmarks:
|
environment via benchmarks:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go test -bench=.*CallerTracing
|
go test -bench=ReportCaller
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Case-sensitivity
|
#### Case-sensitivity
|
||||||
|
|
||||||
The organization's name was changed to lower-case--and this will not be changed
|
The organization's name was [changed to lower-case][1]. If you are getting import
|
||||||
back. If you are getting import conflicts due to case sensitivity, please use
|
conflicts due to case sensitivity, please use the lower-case import:
|
||||||
the lower-case import: `github.com/sirupsen/logrus`.
|
`github.com/sirupsen/logrus`.
|
||||||
|
|
||||||
|
[1]: https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
|
|
@ -289,6 +269,7 @@ func init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: Syslog hooks also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md).
|
Note: Syslog hooks also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md).
|
||||||
|
|
||||||
A list of currently known service hooks can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks)
|
A list of currently known service hooks can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks)
|
||||||
|
|
@ -367,18 +348,21 @@ Splunk or Logstash.
|
||||||
|
|
||||||
The built-in logging formatters are:
|
The built-in logging formatters are:
|
||||||
|
|
||||||
* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise
|
* [`logrus.TextFormatter`](https://pkg.go.dev/github.com/sirupsen/logrus#TextFormatter)
|
||||||
without colors.
|
logs the event in colors if the logger output is a TTY, otherwise without colors.
|
||||||
* *Note:* to force colored output when there is no TTY, set the `ForceColors`
|
* To force colored output when there is no TTY, set the `ForceColors`
|
||||||
field to `true`. To force no colored output even if there is a TTY set the
|
field to `true`. To force no colored output even if there is a TTY set the
|
||||||
`DisableColors` field to `true`. For Windows, see
|
`DisableColors` field to `true`.
|
||||||
[github.com/mattn/go-colorable](https://github.com/mattn/go-colorable).
|
* On modern Windows terminals with ANSI (Virtual Terminal) support, TextFormatter
|
||||||
|
automatically enables colored output.
|
||||||
|
* If your environment does not support ANSI escape sequences, wrap the logger output
|
||||||
|
using [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable)
|
||||||
|
and set `ForceColors` (or `CLICOLOR_FORCE=1`) to enable colors through the wrapper.
|
||||||
* When colors are enabled, levels are truncated to 4 characters by default. To disable
|
* When colors are enabled, levels are truncated to 4 characters by default. To disable
|
||||||
truncation set the `DisableLevelTruncation` field to `true`.
|
truncation set the `DisableLevelTruncation` field to `true`.
|
||||||
* When outputting to a TTY, it's often helpful to visually scan down a column where all the levels are the same width. Setting the `PadLevelText` field to `true` enables this behavior, by adding padding to the level text.
|
* When outputting to a TTY, it's often helpful to visually scan down a column where all the levels are the same width. Setting the `PadLevelText` field to `true` enables this behavior, by adding padding to the level text.
|
||||||
* All options are listed in the [generated docs](https://pkg.go.dev/github.com/sirupsen/logrus#TextFormatter).
|
* [`logrus.JSONFormatter`](https://pkg.go.dev/github.com/sirupsen/logrus#JSONFormatter)
|
||||||
* `logrus.JSONFormatter`. Logs fields as JSON.
|
logs fields as JSON.
|
||||||
* All options are listed in the [generated docs](https://pkg.go.dev/github.com/sirupsen/logrus#JSONFormatter).
|
|
||||||
|
|
||||||
Third-party logging formatters:
|
Third-party logging formatters:
|
||||||
|
|
||||||
|
|
@ -390,10 +374,12 @@ Third-party logging formatters:
|
||||||
* [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure.
|
* [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure.
|
||||||
* [`powerful-logrus-formatter`](https://github.com/zput/zxcTool). get fileName, log's line number and the latest function's name when print log; Save log to files.
|
* [`powerful-logrus-formatter`](https://github.com/zput/zxcTool). get fileName, log's line number and the latest function's name when print log; Save log to files.
|
||||||
* [`caption-json-formatter`](https://github.com/nolleh/caption_json_formatter). logrus's message json formatter with human-readable caption added.
|
* [`caption-json-formatter`](https://github.com/nolleh/caption_json_formatter). logrus's message json formatter with human-readable caption added.
|
||||||
|
* [`easy-logrus-formatter`](https://github.com/WeiZhixiong/easy-logrus-formatter). Provide a user-friendly formatter for logrus.
|
||||||
|
* [`redactrus`](https://github.com/ibreakthecloud/redactrus). Redacts sensitive information like password, apikeys, email, etc. from logs.
|
||||||
|
|
||||||
You can define your formatter by implementing the `Formatter` interface,
|
You can define your formatter by implementing the `Formatter` interface,
|
||||||
requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
|
requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
|
||||||
`Fields` type (`map[string]interface{}`) with all your fields as well as the
|
`Fields` type (`map[string]any`) with all your fields as well as the
|
||||||
default ones (see Entries section above):
|
default ones (see Entries section above):
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
|
@ -516,4 +502,4 @@ Situations when locking is not needed include:
|
||||||
|
|
||||||
2) logger.Out is an os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allows multi-thread/multi-process writing)
|
2) logger.Out is an os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allows multi-thread/multi-process writing)
|
||||||
|
|
||||||
(Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/)
|
(Refer to <http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/>)
|
||||||
|
|
|
||||||
4
vendor/github.com/sirupsen/logrus/alt_exit.go
generated
vendored
4
vendor/github.com/sirupsen/logrus/alt_exit.go
generated
vendored
|
|
@ -57,7 +57,7 @@ func Exit(code int) {
|
||||||
//
|
//
|
||||||
// This method is useful when a caller wishes to use logrus to log a fatal
|
// This method is useful when a caller wishes to use logrus to log a fatal
|
||||||
// message but also needs to gracefully shutdown. An example usecase could be
|
// message but also needs to gracefully shutdown. An example usecase could be
|
||||||
// closing database connections, or sending a alert that the application is
|
// closing database connections, or sending an alert that the application is
|
||||||
// closing.
|
// closing.
|
||||||
func RegisterExitHandler(handler func()) {
|
func RegisterExitHandler(handler func()) {
|
||||||
handlers = append(handlers, handler)
|
handlers = append(handlers, handler)
|
||||||
|
|
@ -69,7 +69,7 @@ func RegisterExitHandler(handler func()) {
|
||||||
//
|
//
|
||||||
// This method is useful when a caller wishes to use logrus to log a fatal
|
// This method is useful when a caller wishes to use logrus to log a fatal
|
||||||
// message but also needs to gracefully shutdown. An example usecase could be
|
// message but also needs to gracefully shutdown. An example usecase could be
|
||||||
// closing database connections, or sending a alert that the application is
|
// closing database connections, or sending an alert that the application is
|
||||||
// closing.
|
// closing.
|
||||||
func DeferExitHandler(handler func()) {
|
func DeferExitHandler(handler func()) {
|
||||||
handlers = append([]func(){handler}, handlers...)
|
handlers = append([]func(){handler}, handlers...)
|
||||||
|
|
|
||||||
22
vendor/github.com/sirupsen/logrus/buffer_pool.go
generated
vendored
22
vendor/github.com/sirupsen/logrus/buffer_pool.go
generated
vendored
|
|
@ -5,9 +5,13 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var bufferPool BufferPool = &defaultPool{
|
||||||
bufferPool BufferPool
|
pool: &sync.Pool{
|
||||||
)
|
New: func() any {
|
||||||
|
return new(bytes.Buffer)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
type BufferPool interface {
|
type BufferPool interface {
|
||||||
Put(*bytes.Buffer)
|
Put(*bytes.Buffer)
|
||||||
|
|
@ -27,17 +31,7 @@ func (p *defaultPool) Get() *bytes.Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBufferPool allows to replace the default logrus buffer pool
|
// SetBufferPool allows to replace the default logrus buffer pool
|
||||||
// to better meets the specific needs of an application.
|
// to better meet the specific needs of an application.
|
||||||
func SetBufferPool(bp BufferPool) {
|
func SetBufferPool(bp BufferPool) {
|
||||||
bufferPool = bp
|
bufferPool = bp
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
SetBufferPool(&defaultPool{
|
|
||||||
pool: &sync.Pool{
|
|
||||||
New: func() interface{} {
|
|
||||||
return new(bytes.Buffer)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
||||||
26
vendor/github.com/sirupsen/logrus/doc.go
generated
vendored
26
vendor/github.com/sirupsen/logrus/doc.go
generated
vendored
|
|
@ -1,25 +1,25 @@
|
||||||
/*
|
/*
|
||||||
Package logrus is a structured logger for Go, completely API compatible with the standard library logger.
|
Package logrus is a structured logger for Go, completely API compatible with the standard library logger.
|
||||||
|
|
||||||
|
|
||||||
The simplest way to use Logrus is simply the package-level exported logger:
|
The simplest way to use Logrus is simply the package-level exported logger:
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"animal": "walrus",
|
"animal": "walrus",
|
||||||
"number": 1,
|
"number": 1,
|
||||||
"size": 10,
|
"size": 10,
|
||||||
}).Info("A walrus appears")
|
}).Info("A walrus appears")
|
||||||
}
|
}
|
||||||
|
|
||||||
Output:
|
Output:
|
||||||
time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10
|
|
||||||
|
time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10
|
||||||
|
|
||||||
For a full guide visit https://github.com/sirupsen/logrus
|
For a full guide visit https://github.com/sirupsen/logrus
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
414
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
414
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
|
|
@ -4,9 +4,11 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"maps"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -17,8 +19,10 @@ var (
|
||||||
// qualified package name, cached at first use
|
// qualified package name, cached at first use
|
||||||
logrusPackage string
|
logrusPackage string
|
||||||
|
|
||||||
// Positions in the call stack when tracing to report the calling method
|
// Positions in the call stack when tracing to report the calling method.
|
||||||
minimumCallerDepth int
|
//
|
||||||
|
// Start at the bottom of the stack before the package-name cache is primed.
|
||||||
|
minimumCallerDepth = 1
|
||||||
|
|
||||||
// Used for caller information initialisation
|
// Used for caller information initialisation
|
||||||
callerInitOnce sync.Once
|
callerInitOnce sync.Once
|
||||||
|
|
@ -29,68 +33,116 @@ const (
|
||||||
knownLogrusFrames int = 4
|
knownLogrusFrames int = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
// start at the bottom of the stack before the package-name cache is primed
|
|
||||||
minimumCallerDepth = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrorKey defines the key when adding errors using [WithError], [Logger.WithError].
|
// ErrorKey defines the key when adding errors using [WithError], [Logger.WithError].
|
||||||
var ErrorKey = "error"
|
var ErrorKey = "error"
|
||||||
|
|
||||||
// Entry is the final or intermediate Logrus logging entry. It contains all
|
// Entry represents a single log event. It may be either an intermediate
|
||||||
// the fields passed with WithField{,s}. It's finally logged when Trace, Debug,
|
// entry (created via WithField(s), WithContext, etc.) or a final entry
|
||||||
// Info, Warn, Error, Fatal or Panic is called on it. These objects can be
|
// that is emitted when one of the level methods (Trace, Debug, Info,
|
||||||
// reused and passed around as much as you wish to avoid field duplication.
|
// Warn, Error, Fatal, Panic) is called.
|
||||||
//
|
//
|
||||||
//nolint:recvcheck // the methods of "Entry" use pointer receiver and non-pointer receiver.
|
// An Entry always belongs to a Logger. A nil Logger is invalid and will
|
||||||
|
// cause a panic when the entry is logged. Use [NewEntry] or Logger methods
|
||||||
|
// to construct entries.
|
||||||
|
//
|
||||||
|
// Entries are safe to reuse for adding fields and may be passed around
|
||||||
|
// to avoid field duplication. Each log operation operates on a copy
|
||||||
|
// of the Entry’s data to avoid mutation during formatting.
|
||||||
|
//
|
||||||
|
//nolint:recvcheck // Entry methods intentionally use both pointer and value receivers.
|
||||||
type Entry struct {
|
type Entry struct {
|
||||||
|
// Logger is the Logger that owns this entry and is responsible for
|
||||||
|
// formatting, hooks, and output. It must not be nil. An Entry without
|
||||||
|
// a Logger is invalid and will panic when logged.
|
||||||
Logger *Logger
|
Logger *Logger
|
||||||
|
|
||||||
// Contains all the fields set by the user.
|
// Data contains all user-defined fields attached to this entry.
|
||||||
Data Fields
|
Data Fields
|
||||||
|
|
||||||
// Time at which the log entry was created
|
// Time is the timestamp for the log event. If zero when the entry is
|
||||||
|
// logged, it defaults to the current time.
|
||||||
Time time.Time
|
Time time.Time
|
||||||
|
|
||||||
// Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic
|
// Level is the severity of the log entry. It is set when the entry
|
||||||
// This field will be set on entry firing and the value will be equal to the one in Logger struct field.
|
// is fired and reflects the level used for that log call.
|
||||||
Level Level
|
Level Level
|
||||||
|
|
||||||
// Calling method, with package name
|
// Caller contains the calling method information.
|
||||||
|
//
|
||||||
|
// When [Logger.ReportCaller] is enabled, Caller is populated automatically at
|
||||||
|
// log time if it is nil. Hooks and formatters may inspect Caller.
|
||||||
|
//
|
||||||
|
// Applications generally should not modify Caller unless they intentionally
|
||||||
|
// want to provide custom caller information.
|
||||||
Caller *runtime.Frame
|
Caller *runtime.Frame
|
||||||
|
|
||||||
// Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
|
// Message is the log message supplied to one of the logging methods
|
||||||
|
// (Trace, Debug, Info, Warn, Error, Fatal, or Panic). It is set when
|
||||||
|
// the entry is logged.
|
||||||
Message string
|
Message string
|
||||||
|
|
||||||
// When formatter is called in entry.log(), a Buffer may be set to entry
|
// Buffer is a reusable buffer provided to the formatter. It is set
|
||||||
|
// before formatting in the normal log path; when nil, formatters
|
||||||
|
// allocate their own.
|
||||||
Buffer *bytes.Buffer
|
Buffer *bytes.Buffer
|
||||||
|
|
||||||
// Contains the context set by the user. Useful for hook processing etc.
|
// Context carries user-provided context for hooks and formatters.
|
||||||
Context context.Context
|
Context context.Context
|
||||||
|
|
||||||
// err may contain a field formatting error
|
// err contains internal field-formatting errors.
|
||||||
err string
|
err string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewEntry creates a new [Entry] associated with the provided Logger.
|
||||||
|
// The logger must not be nil. Passing a nil logger results in a
|
||||||
|
// panic when a logging method (e.g., [Entry.Info], [Entry.Error], etc.)
|
||||||
|
// is called.
|
||||||
func NewEntry(logger *Logger) *Entry {
|
func NewEntry(logger *Logger) *Entry {
|
||||||
return &Entry{
|
return &Entry{
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
// Default is three fields, plus one optional. Give a little extra room.
|
// Reserve default predefined fields and a little extra room.
|
||||||
Data: make(Fields, 6),
|
Data: make(Fields, defaultFields+3),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dup creates a copy of the entry for further modification.
|
||||||
|
//
|
||||||
|
// Data is cloned to avoid mutating the original entry. Other fields
|
||||||
|
// (Logger, Time, Context, etc.) are copied by value.
|
||||||
func (entry *Entry) Dup() *Entry {
|
func (entry *Entry) Dup() *Entry {
|
||||||
data := make(Fields, len(entry.Data))
|
dup := entry.dup()
|
||||||
for k, v := range entry.Data {
|
dup.Data = maps.Clone(entry.Data)
|
||||||
data[k] = v
|
return dup
|
||||||
|
}
|
||||||
|
|
||||||
|
// dup copies the entry fields shared by derived entries except Data, which
|
||||||
|
// callers must copy or initialize as appropriate for their use.
|
||||||
|
func (entry *Entry) dup() *Entry {
|
||||||
|
return &Entry{
|
||||||
|
Logger: entry.Logger,
|
||||||
|
Time: entry.Time,
|
||||||
|
Caller: entry.Caller,
|
||||||
|
Context: entry.Context,
|
||||||
|
err: entry.err,
|
||||||
}
|
}
|
||||||
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, Context: entry.Context, err: entry.err}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns the bytes representation of this entry from the formatter.
|
// Bytes returns the bytes representation of this entry from the formatter.
|
||||||
func (entry *Entry) Bytes() ([]byte, error) {
|
func (entry *Entry) Bytes() ([]byte, error) {
|
||||||
return entry.Logger.Formatter.Format(entry)
|
// Snapshot the formatter under the lock to protect against concurrent
|
||||||
|
// SetFormatter calls, then release the lock before formatting.
|
||||||
|
// This avoids a data race and prevents a deadlock if Format() triggers
|
||||||
|
// reentrant logging (e.g., a field's MarshalJSON calls logrus).
|
||||||
|
//
|
||||||
|
// See:
|
||||||
|
//
|
||||||
|
// - https://github.com/sirupsen/logrus/issues/1440
|
||||||
|
// - https://github.com/sirupsen/logrus/issues/1448
|
||||||
|
entry.Logger.mu.Lock()
|
||||||
|
formatter := entry.Logger.Formatter
|
||||||
|
entry.Logger.mu.Unlock()
|
||||||
|
|
||||||
|
return formatter.Format(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the string representation from the reader and ultimately the
|
// String returns the string representation from the reader and ultimately the
|
||||||
|
|
@ -112,58 +164,61 @@ func (entry *Entry) WithError(err error) *Entry {
|
||||||
|
|
||||||
// WithContext adds a context to the Entry.
|
// WithContext adds a context to the Entry.
|
||||||
func (entry *Entry) WithContext(ctx context.Context) *Entry {
|
func (entry *Entry) WithContext(ctx context.Context) *Entry {
|
||||||
dataCopy := make(Fields, len(entry.Data))
|
dup := entry.dup()
|
||||||
for k, v := range entry.Data {
|
dup.Data = maps.Clone(entry.Data)
|
||||||
dataCopy[k] = v
|
dup.Context = ctx
|
||||||
}
|
return dup
|
||||||
return &Entry{Logger: entry.Logger, Data: dataCopy, Time: entry.Time, err: entry.err, Context: ctx}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithField adds a single field to the Entry.
|
// WithField adds a single field to the Entry.
|
||||||
func (entry *Entry) WithField(key string, value interface{}) *Entry {
|
func (entry *Entry) WithField(key string, value any) *Entry {
|
||||||
return entry.WithFields(Fields{key: value})
|
dup := entry.dup()
|
||||||
|
dup.Data = maps.Clone(entry.Data)
|
||||||
|
dup.addField(key, value)
|
||||||
|
return dup
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithFields adds a map of fields to the Entry.
|
// WithFields adds a map of fields to the Entry.
|
||||||
func (entry *Entry) WithFields(fields Fields) *Entry {
|
func (entry *Entry) WithFields(fields Fields) *Entry {
|
||||||
data := make(Fields, len(entry.Data)+len(fields))
|
dup := entry.dup()
|
||||||
for k, v := range entry.Data {
|
dup.Data = make(Fields, len(entry.Data)+len(fields))
|
||||||
data[k] = v
|
maps.Copy(dup.Data, entry.Data)
|
||||||
|
|
||||||
|
for key, value := range fields {
|
||||||
|
dup.addField(key, value)
|
||||||
}
|
}
|
||||||
fieldErr := entry.err
|
return dup
|
||||||
for k, v := range fields {
|
|
||||||
isErrField := false
|
|
||||||
if t := reflect.TypeOf(v); t != nil {
|
|
||||||
switch {
|
|
||||||
case t.Kind() == reflect.Func, t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Func:
|
|
||||||
isErrField = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if isErrField {
|
|
||||||
tmp := fmt.Sprintf("can not add field %q", k)
|
|
||||||
if fieldErr != "" {
|
|
||||||
fieldErr = entry.err + ", " + tmp
|
|
||||||
} else {
|
|
||||||
fieldErr = tmp
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr, Context: entry.Context}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithTime overrides the time of the Entry.
|
// WithTime overrides the time of the Entry.
|
||||||
func (entry *Entry) WithTime(t time.Time) *Entry {
|
func (entry *Entry) WithTime(t time.Time) *Entry {
|
||||||
dataCopy := make(Fields, len(entry.Data))
|
dup := entry.dup()
|
||||||
for k, v := range entry.Data {
|
dup.Data = maps.Clone(entry.Data)
|
||||||
dataCopy[k] = v
|
dup.Time = t
|
||||||
|
return dup
|
||||||
|
}
|
||||||
|
|
||||||
|
func (entry *Entry) addField(key string, value any) {
|
||||||
|
if _, ok := value.(error); !ok {
|
||||||
|
t := reflect.TypeOf(value)
|
||||||
|
if t != nil && (t.Kind() == reflect.Func || t.Kind() == reflect.Pointer && t.Elem().Kind() == reflect.Func) {
|
||||||
|
if entry.err != "" {
|
||||||
|
entry.err += ", skipping unsupported field " + strconv.Quote(key)
|
||||||
|
} else {
|
||||||
|
entry.err = "skipping unsupported field " + strconv.Quote(key)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &Entry{Logger: entry.Logger, Data: dataCopy, Time: t, err: entry.err, Context: entry.Context}
|
|
||||||
|
if entry.Data == nil {
|
||||||
|
entry.Data = make(Fields, 1)
|
||||||
|
}
|
||||||
|
entry.Data[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPackageName reduces a fully qualified function name to the package name
|
// getPackageName reduces a fully qualified function name to the package name
|
||||||
// There really ought to be to be a better way...
|
// There really ought to be a better way...
|
||||||
func getPackageName(f string) string {
|
func getPackageName(f string) string {
|
||||||
for {
|
for {
|
||||||
lastPeriod := strings.LastIndex(f, ".")
|
lastPeriod := strings.LastIndex(f, ".")
|
||||||
|
|
@ -186,7 +241,7 @@ func getCaller() *runtime.Frame {
|
||||||
_ = runtime.Callers(0, pcs)
|
_ = runtime.Callers(0, pcs)
|
||||||
|
|
||||||
// dynamic get the package name and the minimum caller depth
|
// dynamic get the package name and the minimum caller depth
|
||||||
for i := 0; i < maximumCallerDepth; i++ {
|
for i := range maximumCallerDepth {
|
||||||
funcName := runtime.FuncForPC(pcs[i]).Name()
|
funcName := runtime.FuncForPC(pcs[i]).Name()
|
||||||
if strings.Contains(funcName, "getCaller") {
|
if strings.Contains(funcName, "getCaller") {
|
||||||
logrusPackage = getPackageName(funcName)
|
logrusPackage = getPackageName(funcName)
|
||||||
|
|
@ -215,16 +270,47 @@ func getCaller() *runtime.Frame {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry Entry) HasCaller() (has bool) {
|
// HasCaller reports whether this Entry contains caller information.
|
||||||
return entry.Logger != nil &&
|
//
|
||||||
entry.Logger.ReportCaller &&
|
// Caller may be set explicitly, or populated at log time when
|
||||||
entry.Caller != nil
|
// [Logger.ReportCaller] is enabled.
|
||||||
|
//
|
||||||
|
// Deprecated: use [Entry.Caller] != nil instead.
|
||||||
|
//
|
||||||
|
//go:fix inline
|
||||||
|
func (entry Entry) HasCaller() bool {
|
||||||
|
return entry.Caller != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) log(level Level, msg string) {
|
func (entry *Entry) logArgs(level Level, panicAfter bool, args ...any) {
|
||||||
var buffer *bytes.Buffer
|
entry.log(level, panicAfter, sprint(args...))
|
||||||
|
}
|
||||||
|
|
||||||
newEntry := entry.Dup()
|
func (entry *Entry) logf(level Level, panicAfter bool, format string, args ...any) {
|
||||||
|
entry.log(level, panicAfter, fmt.Sprintf(format, args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// logln uses Sprintln for multiple arguments to preserve Println-style
|
||||||
|
// spacing between args, then trims the trailing newline.
|
||||||
|
func (entry *Entry) logln(level Level, panicAfter bool, args ...any) {
|
||||||
|
if len(args) <= 1 {
|
||||||
|
entry.log(level, panicAfter, sprint(args...))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
msg := fmt.Sprintln(args...)
|
||||||
|
msg = msg[:len(msg)-1] // Trim the newline added by Sprintln; logging adds its own.
|
||||||
|
entry.log(level, panicAfter, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// log writes msg at level. If panicAfter is true, it panics with the fully
|
||||||
|
// populated entry after hooks and output have completed.
|
||||||
|
//
|
||||||
|
// The explicit flag keeps panic behavior limited to Panic, Panicf, and
|
||||||
|
// Panicln while avoiding a return value used only as the panic value.
|
||||||
|
// See #1283 and commits f96066e and 5f8c666.
|
||||||
|
func (entry *Entry) log(level Level, panicAfter bool, msg string) {
|
||||||
|
newEntry := entry.dup()
|
||||||
|
newEntry.Data = maps.Clone(entry.Data)
|
||||||
|
|
||||||
if newEntry.Time.IsZero() {
|
if newEntry.Time.IsZero() {
|
||||||
newEntry.Time = time.Now()
|
newEntry.Time = time.Now()
|
||||||
|
|
@ -233,17 +319,24 @@ func (entry *Entry) log(level Level, msg string) {
|
||||||
newEntry.Level = level
|
newEntry.Level = level
|
||||||
newEntry.Message = msg
|
newEntry.Message = msg
|
||||||
|
|
||||||
newEntry.Logger.mu.Lock()
|
logger := newEntry.Logger
|
||||||
reportCaller := newEntry.Logger.ReportCaller
|
logger.mu.Lock()
|
||||||
|
reportCaller := logger.ReportCaller
|
||||||
bufPool := newEntry.getBufferPool()
|
bufPool := newEntry.getBufferPool()
|
||||||
newEntry.Logger.mu.Unlock()
|
logger.mu.Unlock()
|
||||||
|
|
||||||
if reportCaller {
|
// Preserve explicitly set caller information.
|
||||||
|
if reportCaller && newEntry.Caller == nil {
|
||||||
newEntry.Caller = getCaller()
|
newEntry.Caller = getCaller()
|
||||||
}
|
}
|
||||||
|
|
||||||
newEntry.fireHooks()
|
// Select hooks based on the level for this log call. Hooks receive the
|
||||||
buffer = bufPool.Get()
|
// Entry and may mutate it, but that does not affect which hooks are
|
||||||
|
// fired for this event.
|
||||||
|
hooks := logger.hooksForLevel(level)
|
||||||
|
newEntry.fireHooks(hooks)
|
||||||
|
|
||||||
|
buffer := bufPool.Get()
|
||||||
defer func() {
|
defer func() {
|
||||||
newEntry.Buffer = nil
|
newEntry.Buffer = nil
|
||||||
buffer.Reset()
|
buffer.Reset()
|
||||||
|
|
@ -251,15 +344,12 @@ func (entry *Entry) log(level Level, msg string) {
|
||||||
}()
|
}()
|
||||||
buffer.Reset()
|
buffer.Reset()
|
||||||
newEntry.Buffer = buffer
|
newEntry.Buffer = buffer
|
||||||
|
|
||||||
newEntry.write()
|
newEntry.write()
|
||||||
|
|
||||||
newEntry.Buffer = nil
|
newEntry.Buffer = nil
|
||||||
|
|
||||||
// To avoid Entry#log() returning a value that only would make sense for
|
// Panic here so the panic value contains the fully populated entry without
|
||||||
// panic() to use in Entry#Panic(), we avoid the allocation by checking
|
// requiring log to return it to the caller.
|
||||||
// directly here.
|
if panicAfter {
|
||||||
if level <= PanicLevel {
|
|
||||||
panic(newEntry)
|
panic(newEntry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -271,175 +361,207 @@ func (entry *Entry) getBufferPool() (pool BufferPool) {
|
||||||
return bufferPool
|
return bufferPool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) fireHooks() {
|
func (entry *Entry) fireHooks(hooks []Hook) {
|
||||||
var tmpHooks LevelHooks
|
for _, hook := range hooks {
|
||||||
entry.Logger.mu.Lock()
|
if err := hook.Fire(entry); err != nil {
|
||||||
tmpHooks = make(LevelHooks, len(entry.Logger.Hooks))
|
_, _ = fmt.Fprintln(os.Stderr, "Failed to fire hook:", err)
|
||||||
for k, v := range entry.Logger.Hooks {
|
return
|
||||||
tmpHooks[k] = v
|
}
|
||||||
}
|
|
||||||
entry.Logger.mu.Unlock()
|
|
||||||
|
|
||||||
err := tmpHooks.Fire(entry.Level, entry)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) write() {
|
func (entry *Entry) write() {
|
||||||
|
// Snapshot the formatter under the lock to protect against concurrent
|
||||||
|
// SetFormatter calls, then release the lock before formatting.
|
||||||
|
// This avoids a deadlock when Format() triggers reentrant logging (e.g.,
|
||||||
|
// a field's MarshalJSON calls logrus). See #1448, #1440.
|
||||||
entry.Logger.mu.Lock()
|
entry.Logger.mu.Lock()
|
||||||
defer entry.Logger.mu.Unlock()
|
formatter := entry.Logger.Formatter
|
||||||
serialized, err := entry.Logger.Formatter.Format(entry)
|
entry.Logger.mu.Unlock()
|
||||||
|
|
||||||
|
serialized, err := formatter.Format(entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
_, _ = fmt.Fprintln(os.Stderr, "Failed to format entry:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-acquire the lock to serialize writes to the underlying io.Writer.
|
||||||
|
entry.Logger.mu.Lock()
|
||||||
|
defer entry.Logger.mu.Unlock()
|
||||||
if _, err := entry.Logger.Out.Write(serialized); err != nil {
|
if _, err := entry.Logger.Out.Write(serialized); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
_, _ = fmt.Fprintln(os.Stderr, "Failed to write to log:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log will log a message at the level given as parameter.
|
// Log logs a message at the specified level.
|
||||||
// Warning: using Log at Panic or Fatal level will not respectively Panic nor Exit.
|
//
|
||||||
// For this behaviour Entry.Panic or Entry.Fatal should be used instead.
|
// Using Log with [PanicLevel] or [FatalLevel] intentionally does not
|
||||||
func (entry *Entry) Log(level Level, args ...interface{}) {
|
// trigger a panic or exit. Log treats the level as logging severity only;
|
||||||
|
// use [Entry.Panic] or [Entry.Fatal] when those side effects are desired.
|
||||||
|
func (entry *Entry) Log(level Level, args ...any) {
|
||||||
|
const panicAfter = false
|
||||||
if entry.Logger.IsLevelEnabled(level) {
|
if entry.Logger.IsLevelEnabled(level) {
|
||||||
entry.log(level, fmt.Sprint(args...))
|
entry.logArgs(level, panicAfter, args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Trace(args ...interface{}) {
|
func (entry *Entry) Trace(args ...any) {
|
||||||
entry.Log(TraceLevel, args...)
|
entry.Log(TraceLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Debug(args ...interface{}) {
|
func (entry *Entry) Debug(args ...any) {
|
||||||
entry.Log(DebugLevel, args...)
|
entry.Log(DebugLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Print(args ...interface{}) {
|
func (entry *Entry) Print(args ...any) {
|
||||||
entry.Info(args...)
|
entry.Info(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Info(args ...interface{}) {
|
func (entry *Entry) Info(args ...any) {
|
||||||
entry.Log(InfoLevel, args...)
|
entry.Log(InfoLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Warn(args ...interface{}) {
|
func (entry *Entry) Warn(args ...any) {
|
||||||
entry.Log(WarnLevel, args...)
|
entry.Log(WarnLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Warning(args ...interface{}) {
|
func (entry *Entry) Warning(args ...any) {
|
||||||
entry.Warn(args...)
|
entry.Warn(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Error(args ...interface{}) {
|
func (entry *Entry) Error(args ...any) {
|
||||||
entry.Log(ErrorLevel, args...)
|
entry.Log(ErrorLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Fatal(args ...interface{}) {
|
func (entry *Entry) Fatal(args ...any) {
|
||||||
entry.Log(FatalLevel, args...)
|
entry.Log(FatalLevel, args...)
|
||||||
entry.Logger.Exit(1)
|
entry.Logger.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Panic(args ...interface{}) {
|
func (entry *Entry) Panic(args ...any) {
|
||||||
entry.Log(PanicLevel, args...)
|
const panicAfter = true
|
||||||
|
if entry.Logger.IsLevelEnabled(PanicLevel) {
|
||||||
|
entry.logArgs(PanicLevel, panicAfter, args...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entry Printf family functions
|
// Entry Printf family functions
|
||||||
|
|
||||||
func (entry *Entry) Logf(level Level, format string, args ...interface{}) {
|
// Logf logs a formatted message at the specified level.
|
||||||
|
//
|
||||||
|
// Using Logf with [PanicLevel] or [FatalLevel] intentionally does not
|
||||||
|
// trigger a panic or exit. Logf treats the level as logging severity only;
|
||||||
|
// use [Entry.Panicf] or [Entry.Fatalf] when those side effects are desired.
|
||||||
|
func (entry *Entry) Logf(level Level, format string, args ...any) {
|
||||||
|
const panicAfter = false
|
||||||
if entry.Logger.IsLevelEnabled(level) {
|
if entry.Logger.IsLevelEnabled(level) {
|
||||||
entry.Log(level, fmt.Sprintf(format, args...))
|
entry.logf(level, panicAfter, format, args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Tracef(format string, args ...interface{}) {
|
func (entry *Entry) Tracef(format string, args ...any) {
|
||||||
entry.Logf(TraceLevel, format, args...)
|
entry.Logf(TraceLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Debugf(format string, args ...interface{}) {
|
func (entry *Entry) Debugf(format string, args ...any) {
|
||||||
entry.Logf(DebugLevel, format, args...)
|
entry.Logf(DebugLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Infof(format string, args ...interface{}) {
|
func (entry *Entry) Infof(format string, args ...any) {
|
||||||
entry.Logf(InfoLevel, format, args...)
|
entry.Logf(InfoLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Printf(format string, args ...interface{}) {
|
func (entry *Entry) Printf(format string, args ...any) {
|
||||||
entry.Infof(format, args...)
|
entry.Infof(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Warnf(format string, args ...interface{}) {
|
func (entry *Entry) Warnf(format string, args ...any) {
|
||||||
entry.Logf(WarnLevel, format, args...)
|
entry.Logf(WarnLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Warningf(format string, args ...interface{}) {
|
func (entry *Entry) Warningf(format string, args ...any) {
|
||||||
entry.Warnf(format, args...)
|
entry.Warnf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Errorf(format string, args ...interface{}) {
|
func (entry *Entry) Errorf(format string, args ...any) {
|
||||||
entry.Logf(ErrorLevel, format, args...)
|
entry.Logf(ErrorLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Fatalf(format string, args ...interface{}) {
|
func (entry *Entry) Fatalf(format string, args ...any) {
|
||||||
entry.Logf(FatalLevel, format, args...)
|
entry.Logf(FatalLevel, format, args...)
|
||||||
entry.Logger.Exit(1)
|
entry.Logger.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Panicf(format string, args ...interface{}) {
|
func (entry *Entry) Panicf(format string, args ...any) {
|
||||||
entry.Logf(PanicLevel, format, args...)
|
const panicAfter = true
|
||||||
|
if entry.Logger.IsLevelEnabled(PanicLevel) {
|
||||||
|
entry.logf(PanicLevel, panicAfter, format, args...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entry Println family functions
|
// Entry Println family functions
|
||||||
|
|
||||||
func (entry *Entry) Logln(level Level, args ...interface{}) {
|
// Logln logs a message at the specified level with Println-style spacing.
|
||||||
|
//
|
||||||
|
// Using Logln with [PanicLevel] or [FatalLevel] intentionally does not
|
||||||
|
// trigger a panic or exit. Logln treats the level as logging severity only;
|
||||||
|
// use [Entry.Panicln] or [Entry.Fatalln] when those side effects are desired.
|
||||||
|
func (entry *Entry) Logln(level Level, args ...any) {
|
||||||
|
const panicAfter = false
|
||||||
if entry.Logger.IsLevelEnabled(level) {
|
if entry.Logger.IsLevelEnabled(level) {
|
||||||
entry.Log(level, entry.sprintlnn(args...))
|
entry.logln(level, panicAfter, args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Traceln(args ...interface{}) {
|
func (entry *Entry) Traceln(args ...any) {
|
||||||
entry.Logln(TraceLevel, args...)
|
entry.Logln(TraceLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Debugln(args ...interface{}) {
|
func (entry *Entry) Debugln(args ...any) {
|
||||||
entry.Logln(DebugLevel, args...)
|
entry.Logln(DebugLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Infoln(args ...interface{}) {
|
func (entry *Entry) Infoln(args ...any) {
|
||||||
entry.Logln(InfoLevel, args...)
|
entry.Logln(InfoLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Println(args ...interface{}) {
|
func (entry *Entry) Println(args ...any) {
|
||||||
entry.Infoln(args...)
|
entry.Infoln(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Warnln(args ...interface{}) {
|
func (entry *Entry) Warnln(args ...any) {
|
||||||
entry.Logln(WarnLevel, args...)
|
entry.Logln(WarnLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Warningln(args ...interface{}) {
|
func (entry *Entry) Warningln(args ...any) {
|
||||||
entry.Warnln(args...)
|
entry.Warnln(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Errorln(args ...interface{}) {
|
func (entry *Entry) Errorln(args ...any) {
|
||||||
entry.Logln(ErrorLevel, args...)
|
entry.Logln(ErrorLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Fatalln(args ...interface{}) {
|
func (entry *Entry) Fatalln(args ...any) {
|
||||||
entry.Logln(FatalLevel, args...)
|
entry.Logln(FatalLevel, args...)
|
||||||
entry.Logger.Exit(1)
|
entry.Logger.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Panicln(args ...interface{}) {
|
func (entry *Entry) Panicln(args ...any) {
|
||||||
entry.Logln(PanicLevel, args...)
|
const panicAfter = true
|
||||||
|
if entry.Logger.IsLevelEnabled(PanicLevel) {
|
||||||
|
entry.logln(PanicLevel, panicAfter, args...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sprintlnn => Sprint no newline. This is to get the behavior of how
|
// sprint is fmt.Sprint with fast paths for zero or one string argument.
|
||||||
// fmt.Sprintln where spaces are always added between operands, regardless of
|
func sprint(args ...any) string {
|
||||||
// their type. Instead of vendoring the Sprintln implementation to spare a
|
switch len(args) {
|
||||||
// string allocation, we do the simplest thing.
|
case 0:
|
||||||
func (entry *Entry) sprintlnn(args ...interface{}) string {
|
return ""
|
||||||
msg := fmt.Sprintln(args...)
|
case 1:
|
||||||
return msg[:len(msg)-1]
|
if msg, ok := args[0].(string); ok {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Sprint(args...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
169
vendor/github.com/sirupsen/logrus/exported.go
generated
vendored
169
vendor/github.com/sirupsen/logrus/exported.go
generated
vendored
|
|
@ -6,11 +6,12 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// std is the package-level standard logger, similar to the default logger
|
||||||
// std is the name of the standard logger in stdlib `log`
|
// in the stdlib [log] package.
|
||||||
std = New()
|
var std = New()
|
||||||
)
|
|
||||||
|
|
||||||
|
// StandardLogger returns the package-level standard logger used by
|
||||||
|
// the top-level logging functions.
|
||||||
func StandardLogger() *Logger {
|
func StandardLogger() *Logger {
|
||||||
return std
|
return std
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +42,7 @@ func GetLevel() Level {
|
||||||
return std.GetLevel()
|
return std.GetLevel()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsLevelEnabled checks if the log level of the standard logger is greater than the level param
|
// IsLevelEnabled checks if logging for the given level is enabled for the standard logger.
|
||||||
func IsLevelEnabled(level Level) bool {
|
func IsLevelEnabled(level Level) bool {
|
||||||
return std.IsLevelEnabled(level)
|
return std.IsLevelEnabled(level)
|
||||||
}
|
}
|
||||||
|
|
@ -51,9 +52,10 @@ func AddHook(hook Hook) {
|
||||||
std.AddHook(hook)
|
std.AddHook(hook)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
|
// WithError creates an entry from the standard logger and adds an error to it,
|
||||||
|
// using the value defined in [ErrorKey] as key.
|
||||||
func WithError(err error) *Entry {
|
func WithError(err error) *Entry {
|
||||||
return std.WithField(ErrorKey, err)
|
return std.WithError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithContext creates an entry from the standard logger and adds a context to it.
|
// WithContext creates an entry from the standard logger and adds a context to it.
|
||||||
|
|
@ -61,210 +63,203 @@ func WithContext(ctx context.Context) *Entry {
|
||||||
return std.WithContext(ctx)
|
return std.WithContext(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithField creates an entry from the standard logger and adds a field to
|
// WithField creates an entry from the standard logger and adds a single field.
|
||||||
// it. If you want multiple fields, use `WithFields`.
|
// For multiple fields, prefer [WithFields] over chaining WithField calls.
|
||||||
//
|
func WithField(key string, value any) *Entry {
|
||||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
|
||||||
// or Panic on the Entry it returns.
|
|
||||||
func WithField(key string, value interface{}) *Entry {
|
|
||||||
return std.WithField(key, value)
|
return std.WithField(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithFields creates an entry from the standard logger and adds multiple
|
// WithFields creates an entry from the standard logger and adds the fields to it.
|
||||||
// fields to it. This is simply a helper for `WithField`, invoking it
|
|
||||||
// once for each field.
|
|
||||||
//
|
|
||||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
|
||||||
// or Panic on the Entry it returns.
|
|
||||||
func WithFields(fields Fields) *Entry {
|
func WithFields(fields Fields) *Entry {
|
||||||
return std.WithFields(fields)
|
return std.WithFields(fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithTime creates an entry from the standard logger and overrides the time of
|
// WithTime creates an entry from the standard logger and overrides the time
|
||||||
// logs generated with it.
|
// used for logs generated with it.
|
||||||
//
|
|
||||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
|
||||||
// or Panic on the Entry it returns.
|
|
||||||
func WithTime(t time.Time) *Entry {
|
func WithTime(t time.Time) *Entry {
|
||||||
return std.WithTime(t)
|
return std.WithTime(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trace logs a message at level Trace on the standard logger.
|
// Trace logs a message at level [TraceLevel] on the standard logger.
|
||||||
func Trace(args ...interface{}) {
|
func Trace(args ...any) {
|
||||||
std.Trace(args...)
|
std.Trace(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug logs a message at level Debug on the standard logger.
|
// Debug logs a message at level [DebugLevel] on the standard logger.
|
||||||
func Debug(args ...interface{}) {
|
func Debug(args ...any) {
|
||||||
std.Debug(args...)
|
std.Debug(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print logs a message at level Info on the standard logger.
|
// Print logs a message at level [InfoLevel] on the standard logger.
|
||||||
func Print(args ...interface{}) {
|
func Print(args ...any) {
|
||||||
std.Print(args...)
|
std.Print(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Info logs a message at level Info on the standard logger.
|
// Info logs a message at level [InfoLevel] on the standard logger.
|
||||||
func Info(args ...interface{}) {
|
func Info(args ...any) {
|
||||||
std.Info(args...)
|
std.Info(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warn logs a message at level Warn on the standard logger.
|
// Warn logs a message at level [WarnLevel] on the standard logger.
|
||||||
func Warn(args ...interface{}) {
|
func Warn(args ...any) {
|
||||||
std.Warn(args...)
|
std.Warn(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warning logs a message at level Warn on the standard logger.
|
// Warning logs a message at level [WarnLevel] on the standard logger.
|
||||||
func Warning(args ...interface{}) {
|
func Warning(args ...any) {
|
||||||
std.Warning(args...)
|
std.Warning(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error logs a message at level Error on the standard logger.
|
// Error logs a message at level [ErrorLevel] on the standard logger.
|
||||||
func Error(args ...interface{}) {
|
func Error(args ...any) {
|
||||||
std.Error(args...)
|
std.Error(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Panic logs a message at level Panic on the standard logger.
|
// Panic logs a message at level [PanicLevel] on the standard logger.
|
||||||
func Panic(args ...interface{}) {
|
func Panic(args ...any) {
|
||||||
std.Panic(args...)
|
std.Panic(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fatal logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
|
// Fatal logs a message at level [FatalLevel] on the standard logger,
|
||||||
func Fatal(args ...interface{}) {
|
// then exits the process with status 1.
|
||||||
|
func Fatal(args ...any) {
|
||||||
std.Fatal(args...)
|
std.Fatal(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TraceFn logs a message from a func at level Trace on the standard logger.
|
// TraceFn logs a message from a func at level [TraceLevel] on the standard logger.
|
||||||
func TraceFn(fn LogFunction) {
|
func TraceFn(fn LogFunction) {
|
||||||
std.TraceFn(fn)
|
std.TraceFn(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DebugFn logs a message from a func at level Debug on the standard logger.
|
// DebugFn logs a message from a func at level [DebugLevel] on the standard logger.
|
||||||
func DebugFn(fn LogFunction) {
|
func DebugFn(fn LogFunction) {
|
||||||
std.DebugFn(fn)
|
std.DebugFn(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintFn logs a message from a func at level Info on the standard logger.
|
// PrintFn logs a message from a func at level [InfoLevel] on the standard logger.
|
||||||
func PrintFn(fn LogFunction) {
|
func PrintFn(fn LogFunction) {
|
||||||
std.PrintFn(fn)
|
std.PrintFn(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InfoFn logs a message from a func at level Info on the standard logger.
|
// InfoFn logs a message from a func at level [InfoLevel] on the standard logger.
|
||||||
func InfoFn(fn LogFunction) {
|
func InfoFn(fn LogFunction) {
|
||||||
std.InfoFn(fn)
|
std.InfoFn(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WarnFn logs a message from a func at level Warn on the standard logger.
|
// WarnFn logs a message from a func at level [WarnLevel] on the standard logger.
|
||||||
func WarnFn(fn LogFunction) {
|
func WarnFn(fn LogFunction) {
|
||||||
std.WarnFn(fn)
|
std.WarnFn(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WarningFn logs a message from a func at level Warn on the standard logger.
|
// WarningFn logs a message from a func at level [WarnLevel] on the standard logger.
|
||||||
func WarningFn(fn LogFunction) {
|
func WarningFn(fn LogFunction) {
|
||||||
std.WarningFn(fn)
|
std.WarningFn(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrorFn logs a message from a func at level Error on the standard logger.
|
// ErrorFn logs a message from a func at level [ErrorLevel] on the standard logger.
|
||||||
func ErrorFn(fn LogFunction) {
|
func ErrorFn(fn LogFunction) {
|
||||||
std.ErrorFn(fn)
|
std.ErrorFn(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PanicFn logs a message from a func at level Panic on the standard logger.
|
// PanicFn logs a message from a func at level [PanicLevel] on the standard logger.
|
||||||
func PanicFn(fn LogFunction) {
|
func PanicFn(fn LogFunction) {
|
||||||
std.PanicFn(fn)
|
std.PanicFn(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FatalFn logs a message from a func at level Fatal on the standard logger then the process will exit with status set to 1.
|
// FatalFn logs a message from a func at level [FatalLevel] on the standard logger,
|
||||||
|
// then exits the process with status 1.
|
||||||
func FatalFn(fn LogFunction) {
|
func FatalFn(fn LogFunction) {
|
||||||
std.FatalFn(fn)
|
std.FatalFn(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tracef logs a message at level Trace on the standard logger.
|
// Tracef logs a message at level [TraceLevel] on the standard logger.
|
||||||
func Tracef(format string, args ...interface{}) {
|
func Tracef(format string, args ...any) {
|
||||||
std.Tracef(format, args...)
|
std.Tracef(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debugf logs a message at level Debug on the standard logger.
|
// Debugf logs a message at level [DebugLevel] on the standard logger.
|
||||||
func Debugf(format string, args ...interface{}) {
|
func Debugf(format string, args ...any) {
|
||||||
std.Debugf(format, args...)
|
std.Debugf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Printf logs a message at level Info on the standard logger.
|
// Printf logs a message at level [InfoLevel] on the standard logger.
|
||||||
func Printf(format string, args ...interface{}) {
|
func Printf(format string, args ...any) {
|
||||||
std.Printf(format, args...)
|
std.Printf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Infof logs a message at level Info on the standard logger.
|
// Infof logs a message at level [InfoLevel] on the standard logger.
|
||||||
func Infof(format string, args ...interface{}) {
|
func Infof(format string, args ...any) {
|
||||||
std.Infof(format, args...)
|
std.Infof(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warnf logs a message at level Warn on the standard logger.
|
// Warnf logs a message at level [WarnLevel] on the standard logger.
|
||||||
func Warnf(format string, args ...interface{}) {
|
func Warnf(format string, args ...any) {
|
||||||
std.Warnf(format, args...)
|
std.Warnf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warningf logs a message at level Warn on the standard logger.
|
// Warningf logs a message at level [WarnLevel] on the standard logger.
|
||||||
func Warningf(format string, args ...interface{}) {
|
func Warningf(format string, args ...any) {
|
||||||
std.Warningf(format, args...)
|
std.Warningf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Errorf logs a message at level Error on the standard logger.
|
// Errorf logs a message at level [ErrorLevel] on the standard logger.
|
||||||
func Errorf(format string, args ...interface{}) {
|
func Errorf(format string, args ...any) {
|
||||||
std.Errorf(format, args...)
|
std.Errorf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Panicf logs a message at level Panic on the standard logger.
|
// Panicf logs a message at level [PanicLevel] on the standard logger.
|
||||||
func Panicf(format string, args ...interface{}) {
|
func Panicf(format string, args ...any) {
|
||||||
std.Panicf(format, args...)
|
std.Panicf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fatalf logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
|
// Fatalf logs a message at level [FatalLevel] on the standard logger,
|
||||||
func Fatalf(format string, args ...interface{}) {
|
// then exits the process with status 1.
|
||||||
|
func Fatalf(format string, args ...any) {
|
||||||
std.Fatalf(format, args...)
|
std.Fatalf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Traceln logs a message at level Trace on the standard logger.
|
// Traceln logs a message at level [TraceLevel] on the standard logger.
|
||||||
func Traceln(args ...interface{}) {
|
func Traceln(args ...any) {
|
||||||
std.Traceln(args...)
|
std.Traceln(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debugln logs a message at level Debug on the standard logger.
|
// Debugln logs a message at level [DebugLevel] on the standard logger.
|
||||||
func Debugln(args ...interface{}) {
|
func Debugln(args ...any) {
|
||||||
std.Debugln(args...)
|
std.Debugln(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Println logs a message at level Info on the standard logger.
|
// Println logs a message at level [InfoLevel] on the standard logger.
|
||||||
func Println(args ...interface{}) {
|
func Println(args ...any) {
|
||||||
std.Println(args...)
|
std.Println(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Infoln logs a message at level Info on the standard logger.
|
// Infoln logs a message at level [InfoLevel] on the standard logger.
|
||||||
func Infoln(args ...interface{}) {
|
func Infoln(args ...any) {
|
||||||
std.Infoln(args...)
|
std.Infoln(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warnln logs a message at level Warn on the standard logger.
|
// Warnln logs a message at level [WarnLevel] on the standard logger.
|
||||||
func Warnln(args ...interface{}) {
|
func Warnln(args ...any) {
|
||||||
std.Warnln(args...)
|
std.Warnln(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warningln logs a message at level Warn on the standard logger.
|
// Warningln logs a message at level [WarnLevel] on the standard logger.
|
||||||
func Warningln(args ...interface{}) {
|
func Warningln(args ...any) {
|
||||||
std.Warningln(args...)
|
std.Warningln(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Errorln logs a message at level Error on the standard logger.
|
// Errorln logs a message at level [ErrorLevel] on the standard logger.
|
||||||
func Errorln(args ...interface{}) {
|
func Errorln(args ...any) {
|
||||||
std.Errorln(args...)
|
std.Errorln(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Panicln logs a message at level Panic on the standard logger.
|
// Panicln logs a message at level [PanicLevel] on the standard logger.
|
||||||
func Panicln(args ...interface{}) {
|
func Panicln(args ...any) {
|
||||||
std.Panicln(args...)
|
std.Panicln(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fatalln logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
|
// Fatalln logs a message at level [FatalLevel] on the standard logger,
|
||||||
func Fatalln(args ...interface{}) {
|
// then exits the process with status 1.
|
||||||
|
func Fatalln(args ...any) {
|
||||||
std.Fatalln(args...)
|
std.Fatalln(args...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
47
vendor/github.com/sirupsen/logrus/formatter.go
generated
vendored
47
vendor/github.com/sirupsen/logrus/formatter.go
generated
vendored
|
|
@ -2,27 +2,40 @@ package logrus
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
// Default key names for the default fields
|
|
||||||
const (
|
const (
|
||||||
|
// defaultTimestampFormat is the layout used to format entry timestamps
|
||||||
|
// when a formatter has not specified a custom TimestampFormat.
|
||||||
|
// It follows time.RFC3339 and is applied unless timestamps are disabled.
|
||||||
defaultTimestampFormat = time.RFC3339
|
defaultTimestampFormat = time.RFC3339
|
||||||
FieldKeyMsg = "msg"
|
|
||||||
FieldKeyLevel = "level"
|
// defaultFields is the number of commonly included predefined log entry fields
|
||||||
FieldKeyTime = "time"
|
// (msg, level, time). It is used as a capacity hint when constructing
|
||||||
FieldKeyLogrusError = "logrus_error"
|
// intermediate collections during formatting (for example, the fixed key list).
|
||||||
FieldKeyFunc = "func"
|
//
|
||||||
FieldKeyFile = "file"
|
// It does not include the optional "logrus_error", "func", or "file" fields.
|
||||||
|
defaultFields = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// The Formatter interface is used to implement a custom Formatter. It takes an
|
// Default key names for the default fields
|
||||||
// `Entry`. It exposes all the fields, including the default ones:
|
const (
|
||||||
|
FieldKeyMsg = "msg"
|
||||||
|
FieldKeyLevel = "level"
|
||||||
|
FieldKeyTime = "time"
|
||||||
|
FieldKeyLogrusError = "logrus_error"
|
||||||
|
FieldKeyFunc = "func"
|
||||||
|
FieldKeyFile = "file"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Formatter is implemented by types that format log entries. It receives an
|
||||||
|
// [*Entry], which contains:
|
||||||
//
|
//
|
||||||
// * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
|
// - entry.Message: the message passed to logging methods such as [Info], [Warn], [Error]
|
||||||
// * `entry.Data["time"]`. The timestamp.
|
// - entry.Time: the timestamp
|
||||||
// * `entry.Data["level"]. The level the entry was logged at.
|
// - entry.Level: the log level
|
||||||
//
|
//
|
||||||
// Any additional fields added with `WithField` or `WithFields` are also in
|
// Additional fields added with [WithField] or [WithFields] are available in
|
||||||
// `entry.Data`. Format is expected to return an array of bytes which are then
|
// [Entry.Data]. Format should return the formatted log entry as a byte slice,
|
||||||
// logged to `logger.Out`.
|
// which is written to [Logger.Out].
|
||||||
type Formatter interface {
|
type Formatter interface {
|
||||||
Format(*Entry) ([]byte, error)
|
Format(*Entry) ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
@ -30,12 +43,12 @@ type Formatter interface {
|
||||||
// This is to not silently overwrite `time`, `msg`, `func` and `level` fields when
|
// This is to not silently overwrite `time`, `msg`, `func` and `level` fields when
|
||||||
// dumping it. If this code wasn't there doing:
|
// dumping it. If this code wasn't there doing:
|
||||||
//
|
//
|
||||||
// logrus.WithField("level", 1).Info("hello")
|
// logrus.WithField("level", 1).Info("hello")
|
||||||
//
|
//
|
||||||
// Would just silently drop the user provided level. Instead with this code
|
// Would just silently drop the user provided level. Instead with this code
|
||||||
// it'll logged as:
|
// it'll logged as:
|
||||||
//
|
//
|
||||||
// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
|
// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
|
||||||
//
|
//
|
||||||
// It's not exported because it's still using Data in an opinionated way. It's to
|
// It's not exported because it's still using Data in an opinionated way. It's to
|
||||||
// avoid code duplication between the two default formatters.
|
// avoid code duplication between the two default formatters.
|
||||||
|
|
|
||||||
37
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
37
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fieldKey string
|
type fieldKey string
|
||||||
|
|
@ -20,7 +21,13 @@ func (f FieldMap) resolve(key fieldKey) string {
|
||||||
return string(key)
|
return string(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONFormatter formats logs into parsable json
|
// JSONFormatter formats logs into parsable JSON.
|
||||||
|
//
|
||||||
|
// Fields from [Entry.Data] are included in the JSON object together with the
|
||||||
|
// standard fields derived from the entry. If a field conflicts with a standard
|
||||||
|
// field, it is prefixed with "fields.". Standard field names can be customized
|
||||||
|
// through FieldMap. When DataKey is set, fields from [Entry.Data] are nested
|
||||||
|
// under that key instead.
|
||||||
type JSONFormatter struct {
|
type JSONFormatter struct {
|
||||||
// TimestampFormat sets the format used for marshaling timestamps.
|
// TimestampFormat sets the format used for marshaling timestamps.
|
||||||
// The format to use is the same than for time.Format or time.Parse from the standard
|
// The format to use is the same than for time.Format or time.Parse from the standard
|
||||||
|
|
@ -61,7 +68,8 @@ type JSONFormatter struct {
|
||||||
|
|
||||||
// Format renders a single log entry
|
// Format renders a single log entry
|
||||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
data := make(Fields, len(entry.Data)+4)
|
caller := entry.Caller
|
||||||
|
data := make(Fields, len(entry.Data)+defaultFields)
|
||||||
for k, v := range entry.Data {
|
for k, v := range entry.Data {
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
case error:
|
case error:
|
||||||
|
|
@ -73,13 +81,14 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.DataKey != "" {
|
if f.DataKey != "" && len(entry.Data) > 0 {
|
||||||
newData := make(Fields, 4)
|
newData := make(Fields, defaultFields+1)
|
||||||
newData[f.DataKey] = data
|
newData[f.DataKey] = data
|
||||||
data = newData
|
data = newData
|
||||||
}
|
}
|
||||||
|
|
||||||
prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
|
hasCaller := caller != nil
|
||||||
|
prefixFieldClashes(data, f.FieldMap, hasCaller)
|
||||||
|
|
||||||
timestampFormat := f.TimestampFormat
|
timestampFormat := f.TimestampFormat
|
||||||
if timestampFormat == "" {
|
if timestampFormat == "" {
|
||||||
|
|
@ -94,11 +103,13 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
}
|
}
|
||||||
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
|
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
|
||||||
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
|
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
|
||||||
if entry.HasCaller() {
|
if caller != nil {
|
||||||
funcVal := entry.Caller.Function
|
var funcVal, fileVal string
|
||||||
fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
|
|
||||||
if f.CallerPrettyfier != nil {
|
if f.CallerPrettyfier != nil {
|
||||||
funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
|
funcVal, fileVal = f.CallerPrettyfier(caller)
|
||||||
|
} else {
|
||||||
|
funcVal = caller.Function
|
||||||
|
fileVal = caller.File + ":" + strconv.FormatInt(int64(caller.Line), 10)
|
||||||
}
|
}
|
||||||
if funcVal != "" {
|
if funcVal != "" {
|
||||||
data[f.FieldMap.resolve(FieldKeyFunc)] = funcVal
|
data[f.FieldMap.resolve(FieldKeyFunc)] = funcVal
|
||||||
|
|
@ -108,11 +119,9 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var b *bytes.Buffer
|
b := entry.Buffer
|
||||||
if entry.Buffer != nil {
|
if b == nil {
|
||||||
b = entry.Buffer
|
b = new(bytes.Buffer)
|
||||||
} else {
|
|
||||||
b = &bytes.Buffer{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
encoder := json.NewEncoder(b)
|
encoder := json.NewEncoder(b)
|
||||||
|
|
|
||||||
101
vendor/github.com/sirupsen/logrus/level.go
generated
vendored
Normal file
101
vendor/github.com/sirupsen/logrus/level.go
generated
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
package logrus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ansiReset = "\x1b[0m" // reset attributes
|
||||||
|
ansiRed = "\x1b[31m" // red
|
||||||
|
ansiYellow = "\x1b[33m" // yellow
|
||||||
|
ansiCyan = "\x1b[36m" // cyan
|
||||||
|
ansiDimCyan = "\x1b[2;36m" // dim cyan
|
||||||
|
ansiDimWhite = "\x1b[2;37m" // dim white (light gray)
|
||||||
|
)
|
||||||
|
|
||||||
|
type lvlPrefix struct {
|
||||||
|
full string
|
||||||
|
truncated string
|
||||||
|
padded string
|
||||||
|
}
|
||||||
|
|
||||||
|
func colorize(level Level, s string) string {
|
||||||
|
color := ansiCyan
|
||||||
|
switch level {
|
||||||
|
case TraceLevel:
|
||||||
|
color = ansiDimWhite
|
||||||
|
case DebugLevel:
|
||||||
|
color = ansiDimCyan
|
||||||
|
case WarnLevel:
|
||||||
|
color = ansiYellow
|
||||||
|
case ErrorLevel, FatalLevel, PanicLevel:
|
||||||
|
color = ansiRed
|
||||||
|
case InfoLevel:
|
||||||
|
color = ansiCyan
|
||||||
|
}
|
||||||
|
return color + s + ansiReset
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatLevel(level Level, disableTrunc, pad bool, maxLen int) string {
|
||||||
|
upper := strings.ToUpper(level.String())
|
||||||
|
|
||||||
|
if pad && maxLen > len(upper) {
|
||||||
|
upper += strings.Repeat(" ", maxLen-len(upper))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !pad && !disableTrunc && len(upper) > 4 {
|
||||||
|
upper = upper[:4]
|
||||||
|
}
|
||||||
|
|
||||||
|
return colorize(level, upper)
|
||||||
|
}
|
||||||
|
|
||||||
|
var levelPrefixOnce = sync.OnceValues(func() (map[Level]lvlPrefix, lvlPrefix) {
|
||||||
|
var maxLevel Level
|
||||||
|
maxLen := 0
|
||||||
|
for _, lvl := range AllLevels {
|
||||||
|
if lvl > maxLevel {
|
||||||
|
maxLevel = lvl
|
||||||
|
}
|
||||||
|
if l := len(lvl.String()); l > maxLen {
|
||||||
|
maxLen = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix := make(map[Level]lvlPrefix, len(AllLevels))
|
||||||
|
for _, lvl := range AllLevels {
|
||||||
|
prefix[lvl] = lvlPrefix{
|
||||||
|
full: formatLevel(lvl, true, false, maxLen),
|
||||||
|
truncated: formatLevel(lvl, false, false, maxLen),
|
||||||
|
padded: formatLevel(lvl, true, true, maxLen),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unknownLevel := maxLevel + 1
|
||||||
|
unknown := lvlPrefix{
|
||||||
|
full: formatLevel(unknownLevel, true, false, maxLen),
|
||||||
|
truncated: formatLevel(unknownLevel, false, false, maxLen),
|
||||||
|
padded: formatLevel(unknownLevel, true, true, maxLen),
|
||||||
|
}
|
||||||
|
|
||||||
|
return prefix, unknown
|
||||||
|
})
|
||||||
|
|
||||||
|
func levelPrefix(level Level, disableTrunc, pad bool) string {
|
||||||
|
prefix, unknown := levelPrefixOnce()
|
||||||
|
|
||||||
|
p, ok := prefix[level]
|
||||||
|
if !ok {
|
||||||
|
p = unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case pad:
|
||||||
|
return p.padded
|
||||||
|
case !disableTrunc:
|
||||||
|
return p.truncated
|
||||||
|
default:
|
||||||
|
return p.full
|
||||||
|
}
|
||||||
|
}
|
||||||
156
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
156
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
|
|
@ -12,17 +12,19 @@ import (
|
||||||
// LogFunction For big messages, it can be more efficient to pass a function
|
// LogFunction For big messages, it can be more efficient to pass a function
|
||||||
// and only call it if the log level is actually enables rather than
|
// and only call it if the log level is actually enables rather than
|
||||||
// generating the log message and then checking if the level is enabled
|
// generating the log message and then checking if the level is enabled
|
||||||
type LogFunction func() []interface{}
|
type LogFunction func() []any
|
||||||
|
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
|
// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
|
||||||
// file, or leave it default which is `os.Stderr`. You can also set this to
|
// file, or leave it default which is `os.Stderr`. You can also set this to
|
||||||
// something more adventurous, such as logging to Kafka.
|
// something more adventurous, such as logging to Kafka.
|
||||||
Out io.Writer
|
Out io.Writer
|
||||||
|
|
||||||
// Hooks for the logger instance. These allow firing events based on logging
|
// Hooks for the logger instance. These allow firing events based on logging
|
||||||
// levels and log entries. For example, to send errors to an error tracking
|
// levels and log entries. For example, to send errors to an error tracking
|
||||||
// service, log to StatsD or dump the core on fatal errors.
|
// service, log to StatsD or dump the core on fatal errors.
|
||||||
Hooks LevelHooks
|
Hooks LevelHooks
|
||||||
|
|
||||||
// All log entries pass through the formatter before logged to Out. The
|
// All log entries pass through the formatter before logged to Out. The
|
||||||
// included formatters are `TextFormatter` and `JSONFormatter` for which
|
// included formatters are `TextFormatter` and `JSONFormatter` for which
|
||||||
// TextFormatter is the default. In development (when a TTY is attached) it
|
// TextFormatter is the default. In development (when a TTY is attached) it
|
||||||
|
|
@ -38,37 +40,44 @@ type Logger struct {
|
||||||
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
||||||
// logged.
|
// logged.
|
||||||
Level Level
|
Level Level
|
||||||
|
|
||||||
// Used to sync writing to the log. Locking is enabled by Default
|
// Used to sync writing to the log. Locking is enabled by Default
|
||||||
mu MutexWrap
|
mu mutexWrap
|
||||||
|
|
||||||
// Reusable empty entry
|
// Reusable empty entry
|
||||||
entryPool sync.Pool
|
entryPool sync.Pool
|
||||||
|
|
||||||
// Function to exit the application, defaults to `os.Exit()`
|
// Function to exit the application, defaults to `os.Exit()`
|
||||||
ExitFunc exitFunc
|
ExitFunc func(int)
|
||||||
|
|
||||||
// The buffer pool used to format the log. If it is nil, the default global
|
// The buffer pool used to format the log. If it is nil, the default global
|
||||||
// buffer pool will be used.
|
// buffer pool will be used.
|
||||||
BufferPool BufferPool
|
BufferPool BufferPool
|
||||||
}
|
}
|
||||||
|
|
||||||
type exitFunc func(int)
|
// MutexWrap is the mutex implementation used by [Logger].
|
||||||
|
//
|
||||||
|
// Deprecated: MutexWrap is an implementation detail of Logger and should not be used directly.
|
||||||
|
type MutexWrap = mutexWrap
|
||||||
|
|
||||||
type MutexWrap struct {
|
type mutexWrap struct {
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
disabled bool
|
disabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mw *MutexWrap) Lock() {
|
func (mw *mutexWrap) Lock() {
|
||||||
if !mw.disabled {
|
if !mw.disabled {
|
||||||
mw.lock.Lock()
|
mw.lock.Lock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mw *MutexWrap) Unlock() {
|
func (mw *mutexWrap) Unlock() {
|
||||||
if !mw.disabled {
|
if !mw.disabled {
|
||||||
mw.lock.Unlock()
|
mw.lock.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mw *MutexWrap) Disable() {
|
func (mw *mutexWrap) Disable() {
|
||||||
mw.disabled = true
|
mw.disabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,7 +113,7 @@ func (logger *Logger) newEntry() *Entry {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) releaseEntry(entry *Entry) {
|
func (logger *Logger) releaseEntry(entry *Entry) {
|
||||||
entry.Data = map[string]interface{}{}
|
entry.Data = map[string]any{}
|
||||||
logger.entryPool.Put(entry)
|
logger.entryPool.Put(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,7 +121,7 @@ func (logger *Logger) releaseEntry(entry *Entry) {
|
||||||
// Debug, Print, Info, Warn, Error, Fatal or Panic must be then applied to
|
// Debug, Print, Info, Warn, Error, Fatal or Panic must be then applied to
|
||||||
// this new returned entry.
|
// this new returned entry.
|
||||||
// If you want multiple fields, use `WithFields`.
|
// If you want multiple fields, use `WithFields`.
|
||||||
func (logger *Logger) WithField(key string, value interface{}) *Entry {
|
func (logger *Logger) WithField(key string, value any) *Entry {
|
||||||
entry := logger.newEntry()
|
entry := logger.newEntry()
|
||||||
defer logger.releaseEntry(entry)
|
defer logger.releaseEntry(entry)
|
||||||
return entry.WithField(key, value)
|
return entry.WithField(key, value)
|
||||||
|
|
@ -148,7 +157,12 @@ func (logger *Logger) WithTime(t time.Time) *Entry {
|
||||||
return entry.WithTime(t)
|
return entry.WithTime(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Logf(level Level, format string, args ...interface{}) {
|
// Logf logs a formatted message at the specified level.
|
||||||
|
//
|
||||||
|
// Using Logf with [PanicLevel] or [FatalLevel] intentionally does not
|
||||||
|
// trigger a panic or exit. Logf treats the level as logging severity only;
|
||||||
|
// use [Logger.Panicf] or [Logger.Fatalf] when those side effects are desired.
|
||||||
|
func (logger *Logger) Logf(level Level, format string, args ...any) {
|
||||||
if logger.IsLevelEnabled(level) {
|
if logger.IsLevelEnabled(level) {
|
||||||
entry := logger.newEntry()
|
entry := logger.newEntry()
|
||||||
entry.Logf(level, format, args...)
|
entry.Logf(level, format, args...)
|
||||||
|
|
@ -156,49 +170,55 @@ func (logger *Logger) Logf(level Level, format string, args ...interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Tracef(format string, args ...interface{}) {
|
func (logger *Logger) Tracef(format string, args ...any) {
|
||||||
logger.Logf(TraceLevel, format, args...)
|
logger.Logf(TraceLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Debugf(format string, args ...interface{}) {
|
func (logger *Logger) Debugf(format string, args ...any) {
|
||||||
logger.Logf(DebugLevel, format, args...)
|
logger.Logf(DebugLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Infof(format string, args ...interface{}) {
|
func (logger *Logger) Infof(format string, args ...any) {
|
||||||
logger.Logf(InfoLevel, format, args...)
|
logger.Logf(InfoLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Printf(format string, args ...interface{}) {
|
func (logger *Logger) Printf(format string, args ...any) {
|
||||||
entry := logger.newEntry()
|
entry := logger.newEntry()
|
||||||
entry.Printf(format, args...)
|
entry.Printf(format, args...)
|
||||||
logger.releaseEntry(entry)
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warnf(format string, args ...interface{}) {
|
func (logger *Logger) Warnf(format string, args ...any) {
|
||||||
logger.Logf(WarnLevel, format, args...)
|
logger.Logf(WarnLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warningf(format string, args ...interface{}) {
|
func (logger *Logger) Warningf(format string, args ...any) {
|
||||||
logger.Warnf(format, args...)
|
logger.Warnf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Errorf(format string, args ...interface{}) {
|
func (logger *Logger) Errorf(format string, args ...any) {
|
||||||
logger.Logf(ErrorLevel, format, args...)
|
logger.Logf(ErrorLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Fatalf(format string, args ...interface{}) {
|
func (logger *Logger) Fatalf(format string, args ...any) {
|
||||||
logger.Logf(FatalLevel, format, args...)
|
logger.Logf(FatalLevel, format, args...)
|
||||||
logger.Exit(1)
|
logger.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Panicf(format string, args ...interface{}) {
|
func (logger *Logger) Panicf(format string, args ...any) {
|
||||||
logger.Logf(PanicLevel, format, args...)
|
if logger.IsLevelEnabled(PanicLevel) {
|
||||||
|
entry := logger.newEntry()
|
||||||
|
defer logger.releaseEntry(entry)
|
||||||
|
entry.Panicf(format, args...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log will log a message at the level given as parameter.
|
// Log logs a message at the specified level.
|
||||||
// Warning: using Log at Panic or Fatal level will not respectively Panic nor Exit.
|
//
|
||||||
// For this behaviour Logger.Panic or Logger.Fatal should be used instead.
|
// Using Log with [PanicLevel] or [FatalLevel] intentionally does not
|
||||||
func (logger *Logger) Log(level Level, args ...interface{}) {
|
// trigger a panic or exit. Log treats the level as logging severity only;
|
||||||
|
// use [Logger.Panic] or [Logger.Fatal] when those side effects are desired.
|
||||||
|
func (logger *Logger) Log(level Level, args ...any) {
|
||||||
if logger.IsLevelEnabled(level) {
|
if logger.IsLevelEnabled(level) {
|
||||||
entry := logger.newEntry()
|
entry := logger.newEntry()
|
||||||
entry.Log(level, args...)
|
entry.Log(level, args...)
|
||||||
|
|
@ -206,6 +226,11 @@ func (logger *Logger) Log(level Level, args ...interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogFn logs a message returned by fn at the specified level.
|
||||||
|
//
|
||||||
|
// Using LogFn with [PanicLevel] or [FatalLevel] intentionally does not
|
||||||
|
// trigger a panic or exit. LogFn treats the level as logging severity only;
|
||||||
|
// use [Logger.PanicFn] or [Logger.FatalFn] when those side effects are desired.
|
||||||
func (logger *Logger) LogFn(level Level, fn LogFunction) {
|
func (logger *Logger) LogFn(level Level, fn LogFunction) {
|
||||||
if logger.IsLevelEnabled(level) {
|
if logger.IsLevelEnabled(level) {
|
||||||
entry := logger.newEntry()
|
entry := logger.newEntry()
|
||||||
|
|
@ -214,43 +239,47 @@ func (logger *Logger) LogFn(level Level, fn LogFunction) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Trace(args ...interface{}) {
|
func (logger *Logger) Trace(args ...any) {
|
||||||
logger.Log(TraceLevel, args...)
|
logger.Log(TraceLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Debug(args ...interface{}) {
|
func (logger *Logger) Debug(args ...any) {
|
||||||
logger.Log(DebugLevel, args...)
|
logger.Log(DebugLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Info(args ...interface{}) {
|
func (logger *Logger) Info(args ...any) {
|
||||||
logger.Log(InfoLevel, args...)
|
logger.Log(InfoLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Print(args ...interface{}) {
|
func (logger *Logger) Print(args ...any) {
|
||||||
entry := logger.newEntry()
|
entry := logger.newEntry()
|
||||||
entry.Print(args...)
|
entry.Print(args...)
|
||||||
logger.releaseEntry(entry)
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warn(args ...interface{}) {
|
func (logger *Logger) Warn(args ...any) {
|
||||||
logger.Log(WarnLevel, args...)
|
logger.Log(WarnLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warning(args ...interface{}) {
|
func (logger *Logger) Warning(args ...any) {
|
||||||
logger.Warn(args...)
|
logger.Warn(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Error(args ...interface{}) {
|
func (logger *Logger) Error(args ...any) {
|
||||||
logger.Log(ErrorLevel, args...)
|
logger.Log(ErrorLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Fatal(args ...interface{}) {
|
func (logger *Logger) Fatal(args ...any) {
|
||||||
logger.Log(FatalLevel, args...)
|
logger.Log(FatalLevel, args...)
|
||||||
logger.Exit(1)
|
logger.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Panic(args ...interface{}) {
|
func (logger *Logger) Panic(args ...any) {
|
||||||
logger.Log(PanicLevel, args...)
|
if logger.IsLevelEnabled(PanicLevel) {
|
||||||
|
entry := logger.newEntry()
|
||||||
|
defer logger.releaseEntry(entry)
|
||||||
|
entry.Panic(args...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) TraceFn(fn LogFunction) {
|
func (logger *Logger) TraceFn(fn LogFunction) {
|
||||||
|
|
@ -289,10 +318,19 @@ func (logger *Logger) FatalFn(fn LogFunction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) PanicFn(fn LogFunction) {
|
func (logger *Logger) PanicFn(fn LogFunction) {
|
||||||
logger.LogFn(PanicLevel, fn)
|
if logger.IsLevelEnabled(PanicLevel) {
|
||||||
|
entry := logger.newEntry()
|
||||||
|
defer logger.releaseEntry(entry)
|
||||||
|
entry.Panic(fn()...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Logln(level Level, args ...interface{}) {
|
// Logln logs a message at the specified level with Println-style spacing.
|
||||||
|
//
|
||||||
|
// Using Logln with [PanicLevel] or [FatalLevel] intentionally does not
|
||||||
|
// trigger a panic or exit. Logln treats the level as logging severity only;
|
||||||
|
// use [Logger.Panicln] or [Logger.Fatalln] when those side effects are desired.
|
||||||
|
func (logger *Logger) Logln(level Level, args ...any) {
|
||||||
if logger.IsLevelEnabled(level) {
|
if logger.IsLevelEnabled(level) {
|
||||||
entry := logger.newEntry()
|
entry := logger.newEntry()
|
||||||
entry.Logln(level, args...)
|
entry.Logln(level, args...)
|
||||||
|
|
@ -300,43 +338,47 @@ func (logger *Logger) Logln(level Level, args ...interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Traceln(args ...interface{}) {
|
func (logger *Logger) Traceln(args ...any) {
|
||||||
logger.Logln(TraceLevel, args...)
|
logger.Logln(TraceLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Debugln(args ...interface{}) {
|
func (logger *Logger) Debugln(args ...any) {
|
||||||
logger.Logln(DebugLevel, args...)
|
logger.Logln(DebugLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Infoln(args ...interface{}) {
|
func (logger *Logger) Infoln(args ...any) {
|
||||||
logger.Logln(InfoLevel, args...)
|
logger.Logln(InfoLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Println(args ...interface{}) {
|
func (logger *Logger) Println(args ...any) {
|
||||||
entry := logger.newEntry()
|
entry := logger.newEntry()
|
||||||
entry.Println(args...)
|
entry.Println(args...)
|
||||||
logger.releaseEntry(entry)
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warnln(args ...interface{}) {
|
func (logger *Logger) Warnln(args ...any) {
|
||||||
logger.Logln(WarnLevel, args...)
|
logger.Logln(WarnLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warningln(args ...interface{}) {
|
func (logger *Logger) Warningln(args ...any) {
|
||||||
logger.Warnln(args...)
|
logger.Warnln(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Errorln(args ...interface{}) {
|
func (logger *Logger) Errorln(args ...any) {
|
||||||
logger.Logln(ErrorLevel, args...)
|
logger.Logln(ErrorLevel, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Fatalln(args ...interface{}) {
|
func (logger *Logger) Fatalln(args ...any) {
|
||||||
logger.Logln(FatalLevel, args...)
|
logger.Logln(FatalLevel, args...)
|
||||||
logger.Exit(1)
|
logger.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Panicln(args ...interface{}) {
|
func (logger *Logger) Panicln(args ...any) {
|
||||||
logger.Logln(PanicLevel, args...)
|
if logger.IsLevelEnabled(PanicLevel) {
|
||||||
|
entry := logger.newEntry()
|
||||||
|
defer logger.releaseEntry(entry)
|
||||||
|
entry.Panicln(args...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Exit(code int) {
|
func (logger *Logger) Exit(code int) {
|
||||||
|
|
@ -375,7 +417,22 @@ func (logger *Logger) AddHook(hook Hook) {
|
||||||
logger.Hooks.Add(hook)
|
logger.Hooks.Add(hook)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsLevelEnabled checks if the log level of the logger is greater than the level param
|
// hooksForLevel returns a snapshot of the hooks registered for the given level.
|
||||||
|
// The returned slice is a shallow copy and may be used without holding logger.mu.
|
||||||
|
func (logger *Logger) hooksForLevel(level Level) []Hook {
|
||||||
|
logger.mu.Lock()
|
||||||
|
hooks := logger.Hooks[level]
|
||||||
|
if len(hooks) == 0 {
|
||||||
|
logger.mu.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := make([]Hook, len(hooks))
|
||||||
|
copy(out, hooks)
|
||||||
|
logger.mu.Unlock()
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsLevelEnabled checks if logging for the given level is enabled.
|
||||||
func (logger *Logger) IsLevelEnabled(level Level) bool {
|
func (logger *Logger) IsLevelEnabled(level Level) bool {
|
||||||
return logger.level() >= level
|
return logger.level() >= level
|
||||||
}
|
}
|
||||||
|
|
@ -394,6 +451,7 @@ func (logger *Logger) SetOutput(output io.Writer) {
|
||||||
logger.Out = output
|
logger.Out = output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetReportCaller sets whether the caller stack frame must be logged.
|
||||||
func (logger *Logger) SetReportCaller(reportCaller bool) {
|
func (logger *Logger) SetReportCaller(reportCaller bool) {
|
||||||
logger.mu.Lock()
|
logger.mu.Lock()
|
||||||
defer logger.mu.Unlock()
|
defer logger.mu.Unlock()
|
||||||
|
|
@ -403,9 +461,9 @@ func (logger *Logger) SetReportCaller(reportCaller bool) {
|
||||||
// ReplaceHooks replaces the logger hooks and returns the old ones
|
// ReplaceHooks replaces the logger hooks and returns the old ones
|
||||||
func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks {
|
func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks {
|
||||||
logger.mu.Lock()
|
logger.mu.Lock()
|
||||||
|
defer logger.mu.Unlock()
|
||||||
oldHooks := logger.Hooks
|
oldHooks := logger.Hooks
|
||||||
logger.Hooks = hooks
|
logger.Hooks = hooks
|
||||||
logger.mu.Unlock()
|
|
||||||
return oldHooks
|
return oldHooks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
221
vendor/github.com/sirupsen/logrus/logrus.go
generated
vendored
221
vendor/github.com/sirupsen/logrus/logrus.go
generated
vendored
|
|
@ -1,13 +1,13 @@
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Fields type, used to pass to [WithFields].
|
// Fields type, used to pass to [WithFields].
|
||||||
type Fields map[string]interface{}
|
type Fields map[string]any
|
||||||
|
|
||||||
// Level type
|
// Level type
|
||||||
//
|
//
|
||||||
|
|
@ -16,39 +16,56 @@ type Level uint32
|
||||||
|
|
||||||
// Convert the Level to a string. E.g. [PanicLevel] becomes "panic".
|
// Convert the Level to a string. E.g. [PanicLevel] becomes "panic".
|
||||||
func (level Level) String() string {
|
func (level Level) String() string {
|
||||||
if b, err := level.MarshalText(); err == nil {
|
switch level {
|
||||||
return string(b)
|
case TraceLevel:
|
||||||
} else {
|
return "trace"
|
||||||
|
case DebugLevel:
|
||||||
|
return "debug"
|
||||||
|
case InfoLevel:
|
||||||
|
return "info"
|
||||||
|
case WarnLevel:
|
||||||
|
return "warning"
|
||||||
|
case ErrorLevel:
|
||||||
|
return "error"
|
||||||
|
case FatalLevel:
|
||||||
|
return "fatal"
|
||||||
|
case PanicLevel:
|
||||||
|
return "panic"
|
||||||
|
default:
|
||||||
return "unknown"
|
return "unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseLevel takes a string level and returns the Logrus log level constant.
|
// ParseLevel takes a string level and returns the Logrus log level constant.
|
||||||
func ParseLevel(lvl string) (Level, error) {
|
func ParseLevel(lvl string) (Level, error) {
|
||||||
switch strings.ToLower(lvl) {
|
return parseLevel([]byte(lvl))
|
||||||
case "panic":
|
}
|
||||||
return PanicLevel, nil
|
|
||||||
case "fatal":
|
|
||||||
return FatalLevel, nil
|
|
||||||
case "error":
|
|
||||||
return ErrorLevel, nil
|
|
||||||
case "warn", "warning":
|
|
||||||
return WarnLevel, nil
|
|
||||||
case "info":
|
|
||||||
return InfoLevel, nil
|
|
||||||
case "debug":
|
|
||||||
return DebugLevel, nil
|
|
||||||
case "trace":
|
|
||||||
return TraceLevel, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var l Level
|
func parseLevel(b []byte) (Level, error) {
|
||||||
return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
|
switch {
|
||||||
|
case bytes.EqualFold(b, []byte("panic")):
|
||||||
|
return PanicLevel, nil
|
||||||
|
case bytes.EqualFold(b, []byte("fatal")):
|
||||||
|
return FatalLevel, nil
|
||||||
|
case bytes.EqualFold(b, []byte("error")):
|
||||||
|
return ErrorLevel, nil
|
||||||
|
case bytes.EqualFold(b, []byte("warn")),
|
||||||
|
bytes.EqualFold(b, []byte("warning")):
|
||||||
|
return WarnLevel, nil
|
||||||
|
case bytes.EqualFold(b, []byte("info")):
|
||||||
|
return InfoLevel, nil
|
||||||
|
case bytes.EqualFold(b, []byte("debug")):
|
||||||
|
return DebugLevel, nil
|
||||||
|
case bytes.EqualFold(b, []byte("trace")):
|
||||||
|
return TraceLevel, nil
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("not a valid logrus Level: %q", b)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||||
func (level *Level) UnmarshalText(text []byte) error {
|
func (level *Level) UnmarshalText(text []byte) error {
|
||||||
l, err := ParseLevel(string(text))
|
l, err := parseLevel(text)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -60,23 +77,11 @@ func (level *Level) UnmarshalText(text []byte) error {
|
||||||
|
|
||||||
func (level Level) MarshalText() ([]byte, error) {
|
func (level Level) MarshalText() ([]byte, error) {
|
||||||
switch level {
|
switch level {
|
||||||
case TraceLevel:
|
case TraceLevel, DebugLevel, InfoLevel, WarnLevel, ErrorLevel, FatalLevel, PanicLevel:
|
||||||
return []byte("trace"), nil
|
return []byte(level.String()), nil
|
||||||
case DebugLevel:
|
default:
|
||||||
return []byte("debug"), nil
|
return nil, fmt.Errorf("not a valid logrus level %d", level)
|
||||||
case InfoLevel:
|
|
||||||
return []byte("info"), nil
|
|
||||||
case WarnLevel:
|
|
||||||
return []byte("warning"), nil
|
|
||||||
case ErrorLevel:
|
|
||||||
return []byte("error"), nil
|
|
||||||
case FatalLevel:
|
|
||||||
return []byte("fatal"), nil
|
|
||||||
case PanicLevel:
|
|
||||||
return []byte("panic"), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("not a valid logrus level %d", level)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AllLevels exposing all logging levels.
|
// AllLevels exposing all logging levels.
|
||||||
|
|
@ -91,7 +96,7 @@ var AllLevels = []Level{
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are the different logging levels. You can set the logging level to log
|
// These are the different logging levels. You can set the logging level to log
|
||||||
// on your instance of logger, obtained with `logrus.New()`.
|
// on your instance of logger, obtained with [logrus.New].
|
||||||
const (
|
const (
|
||||||
// PanicLevel level, highest level of severity. Logs and then calls panic with the
|
// PanicLevel level, highest level of severity. Logs and then calls panic with the
|
||||||
// message passed to Debug, Info, ...
|
// message passed to Debug, Info, ...
|
||||||
|
|
@ -113,78 +118,110 @@ const (
|
||||||
TraceLevel
|
TraceLevel
|
||||||
)
|
)
|
||||||
|
|
||||||
// Won't compile if StdLogger can't be realized by a log.Logger
|
// Compile-time interface assertions.
|
||||||
var (
|
var (
|
||||||
_ StdLogger = &log.Logger{}
|
_ StdLogger = (*log.Logger)(nil)
|
||||||
_ StdLogger = &Entry{}
|
_ StdLogger = (*Entry)(nil)
|
||||||
_ StdLogger = &Logger{}
|
_ StdLogger = (*Logger)(nil)
|
||||||
|
|
||||||
|
_ FieldLogger = (*Logger)(nil)
|
||||||
|
_ FieldLogger = (*Entry)(nil)
|
||||||
|
_ FieldLogger = Ext1FieldLogger(nil)
|
||||||
|
|
||||||
|
_ DebugLogger = (*Logger)(nil)
|
||||||
|
_ InfoLogger = (*Logger)(nil)
|
||||||
|
_ WarnLogger = (*Logger)(nil)
|
||||||
|
_ ErrorLogger = (*Logger)(nil)
|
||||||
|
_ TraceLogger = (*Logger)(nil)
|
||||||
|
|
||||||
|
_ DebugLogger = (*Entry)(nil)
|
||||||
|
_ InfoLogger = (*Entry)(nil)
|
||||||
|
_ WarnLogger = (*Entry)(nil)
|
||||||
|
_ ErrorLogger = (*Entry)(nil)
|
||||||
|
_ TraceLogger = (*Entry)(nil)
|
||||||
|
|
||||||
|
_ Ext1FieldLogger = (*Logger)(nil)
|
||||||
|
_ Ext1FieldLogger = (*Entry)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
// StdLogger is what your logrus-enabled library should take, that way
|
// StdLogger is what your logrus-enabled library should take, that way
|
||||||
// it'll accept a stdlib logger ([log.Logger]) and a logrus logger.
|
// it'll accept a stdlib logger ([log.Logger]) and a logrus logger.
|
||||||
// There's no standard interface, so this is the closest we get, unfortunately.
|
// There's no standard interface, so this is the closest we get, unfortunately.
|
||||||
type StdLogger interface {
|
type StdLogger interface {
|
||||||
Print(...interface{})
|
Print(args ...any)
|
||||||
Printf(string, ...interface{})
|
Printf(format string, args ...any)
|
||||||
Println(...interface{})
|
Println(args ...any)
|
||||||
|
|
||||||
Fatal(...interface{})
|
Fatal(args ...any)
|
||||||
Fatalf(string, ...interface{})
|
Fatalf(format string, args ...any)
|
||||||
Fatalln(...interface{})
|
Fatalln(args ...any)
|
||||||
|
|
||||||
Panic(...interface{})
|
Panic(args ...any)
|
||||||
Panicf(string, ...interface{})
|
Panicf(format string, args ...any)
|
||||||
Panicln(...interface{})
|
Panicln(args ...any)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FieldLogger extends the [StdLogger] interface, generalizing
|
// FieldLogger extends the [StdLogger] interface, generalizing
|
||||||
// the [Entry] and [Logger] types.
|
// the [Entry] and [Logger] types.
|
||||||
type FieldLogger interface {
|
type FieldLogger interface {
|
||||||
WithField(key string, value interface{}) *Entry
|
WithField(key string, value any) *Entry
|
||||||
WithFields(fields Fields) *Entry
|
WithFields(fields Fields) *Entry
|
||||||
WithError(err error) *Entry
|
WithError(err error) *Entry
|
||||||
|
|
||||||
Debugf(format string, args ...interface{})
|
StdLogger
|
||||||
Infof(format string, args ...interface{})
|
DebugLogger
|
||||||
Printf(format string, args ...interface{})
|
InfoLogger
|
||||||
Warnf(format string, args ...interface{})
|
WarnLogger
|
||||||
Warningf(format string, args ...interface{})
|
ErrorLogger
|
||||||
Errorf(format string, args ...interface{})
|
|
||||||
Fatalf(format string, args ...interface{})
|
|
||||||
Panicf(format string, args ...interface{})
|
|
||||||
|
|
||||||
Debug(args ...interface{})
|
// Legacy warning aliases. These are kept on FieldLogger for backwards
|
||||||
Info(args ...interface{})
|
// compatibility, but are intentionally omitted from [WarnLogger].
|
||||||
Print(args ...interface{})
|
|
||||||
Warn(args ...interface{})
|
|
||||||
Warning(args ...interface{})
|
|
||||||
Error(args ...interface{})
|
|
||||||
Fatal(args ...interface{})
|
|
||||||
Panic(args ...interface{})
|
|
||||||
|
|
||||||
Debugln(args ...interface{})
|
Warning(args ...any)
|
||||||
Infoln(args ...interface{})
|
Warningf(format string, args ...any)
|
||||||
Println(args ...interface{})
|
Warningln(args ...any)
|
||||||
Warnln(args ...interface{})
|
|
||||||
Warningln(args ...interface{})
|
|
||||||
Errorln(args ...interface{})
|
|
||||||
Fatalln(args ...interface{})
|
|
||||||
Panicln(args ...interface{})
|
|
||||||
|
|
||||||
// IsDebugEnabled() bool
|
|
||||||
// IsInfoEnabled() bool
|
|
||||||
// IsWarnEnabled() bool
|
|
||||||
// IsErrorEnabled() bool
|
|
||||||
// IsFatalEnabled() bool
|
|
||||||
// IsPanicEnabled() bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ext1FieldLogger (the first extension to [FieldLogger]) is superfluous, it is
|
// DebugLogger provides convenience functions to log messages at level [DebugLevel].
|
||||||
// here for consistency. Do not use. Use [FieldLogger], [Logger] or [Entry]
|
type DebugLogger interface {
|
||||||
// instead.
|
Debug(args ...any)
|
||||||
|
Debugf(format string, args ...any)
|
||||||
|
Debugln(args ...any)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InfoLogger provides convenience functions to log messages at level [InfoLevel].
|
||||||
|
type InfoLogger interface {
|
||||||
|
Info(args ...any)
|
||||||
|
Infof(format string, args ...any)
|
||||||
|
Infoln(args ...any)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WarnLogger provides convenience functions to log messages at level [WarnLevel].
|
||||||
|
type WarnLogger interface {
|
||||||
|
Warn(args ...any)
|
||||||
|
Warnf(format string, args ...any)
|
||||||
|
Warnln(args ...any)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorLogger provides convenience functions to log messages at level [ErrorLevel].
|
||||||
|
type ErrorLogger interface {
|
||||||
|
Error(args ...any)
|
||||||
|
Errorf(format string, args ...any)
|
||||||
|
Errorln(args ...any)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraceLogger provides convenience functions to log messages at level [TraceLevel].
|
||||||
|
type TraceLogger interface {
|
||||||
|
Trace(args ...any)
|
||||||
|
Tracef(format string, args ...any)
|
||||||
|
Traceln(args ...any)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ext1FieldLogger is FieldLogger extended with Trace-level methods.
|
||||||
|
//
|
||||||
|
// New code should prefer the smallest applicable interface, such as
|
||||||
|
// [FieldLogger] or [TraceLogger], or use [Logger] or [Entry] directly.
|
||||||
type Ext1FieldLogger interface {
|
type Ext1FieldLogger interface {
|
||||||
FieldLogger
|
FieldLogger
|
||||||
Tracef(format string, args ...interface{})
|
TraceLogger
|
||||||
Trace(args ...interface{})
|
|
||||||
Traceln(args ...interface{})
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
vendor/github.com/sirupsen/logrus/terminal_check_appengine.go
generated
vendored
8
vendor/github.com/sirupsen/logrus/terminal_check_appengine.go
generated
vendored
|
|
@ -1,11 +1,7 @@
|
||||||
// +build appengine
|
//go:build appengine
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import (
|
func checkIfTerminal(_ any) bool {
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
func checkIfTerminal(w io.Writer) bool {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3
vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
generated
vendored
3
vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
generated
vendored
|
|
@ -1,5 +1,4 @@
|
||||||
// +build darwin dragonfly freebsd netbsd openbsd hurd
|
//go:build (darwin || dragonfly || freebsd || netbsd || openbsd || hurd) && !tinygo
|
||||||
// +build !js
|
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
|
|
|
||||||
7
vendor/github.com/sirupsen/logrus/terminal_check_js.go
generated
vendored
7
vendor/github.com/sirupsen/logrus/terminal_check_js.go
generated
vendored
|
|
@ -1,7 +0,0 @@
|
||||||
// +build js
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
func isTerminal(fd int) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
8
vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go
generated
vendored
8
vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go
generated
vendored
|
|
@ -1,11 +1,7 @@
|
||||||
// +build js nacl plan9
|
//go:build js || nacl || plan9 || wasi || wasip1 || tinygo
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import (
|
func checkIfTerminal(_ any) bool {
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
func checkIfTerminal(w io.Writer) bool {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
generated
vendored
8
vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
generated
vendored
|
|
@ -1,4 +1,4 @@
|
||||||
// +build !appengine,!js,!windows,!nacl,!plan9
|
//go:build !appengine && !js && !windows && !nacl && !plan9 && !wasi && !wasip1 && !tinygo
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
|
|
@ -10,7 +10,11 @@ import (
|
||||||
func checkIfTerminal(w io.Writer) bool {
|
func checkIfTerminal(w io.Writer) bool {
|
||||||
switch v := w.(type) {
|
switch v := w.(type) {
|
||||||
case *os.File:
|
case *os.File:
|
||||||
return isTerminal(int(v.Fd()))
|
fd := v.Fd()
|
||||||
|
if fd > uintptr(^uint(0)>>1) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return isTerminal(int(fd))
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
vendor/github.com/sirupsen/logrus/terminal_check_solaris.go
generated
vendored
2
vendor/github.com/sirupsen/logrus/terminal_check_solaris.go
generated
vendored
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build solaris && !tinygo
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
5
vendor/github.com/sirupsen/logrus/terminal_check_unix.go
generated
vendored
5
vendor/github.com/sirupsen/logrus/terminal_check_unix.go
generated
vendored
|
|
@ -1,7 +1,4 @@
|
||||||
//go:build (linux || aix || zos) && !js && !wasi
|
//go:build (linux || aix || zos) && !tinygo
|
||||||
// +build linux aix zos
|
|
||||||
// +build !js
|
|
||||||
// +build !wasi
|
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
|
|
|
||||||
8
vendor/github.com/sirupsen/logrus/terminal_check_wasi.go
generated
vendored
8
vendor/github.com/sirupsen/logrus/terminal_check_wasi.go
generated
vendored
|
|
@ -1,8 +0,0 @@
|
||||||
//go:build wasi
|
|
||||||
// +build wasi
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
func isTerminal(fd int) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
8
vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go
generated
vendored
8
vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go
generated
vendored
|
|
@ -1,8 +0,0 @@
|
||||||
//go:build wasip1
|
|
||||||
// +build wasip1
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
func isTerminal(fd int) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
2
vendor/github.com/sirupsen/logrus/terminal_check_windows.go
generated
vendored
2
vendor/github.com/sirupsen/logrus/terminal_check_windows.go
generated
vendored
|
|
@ -1,4 +1,4 @@
|
||||||
// +build !appengine,!js,windows
|
//go:build windows && !appengine
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
|
|
|
||||||
491
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
491
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
|
|
@ -3,30 +3,32 @@ package logrus
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"maps"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
var baseTimestamp = time.Now()
|
||||||
red = 31
|
|
||||||
yellow = 33
|
|
||||||
blue = 36
|
|
||||||
gray = 37
|
|
||||||
)
|
|
||||||
|
|
||||||
var baseTimestamp time.Time
|
// TextFormatter formats logs into text.
|
||||||
|
//
|
||||||
func init() {
|
// Output is logfmt-like: key=value pairs separated by spaces. Fields from
|
||||||
baseTimestamp = time.Now()
|
// [Entry.Data] are included together with the standard fields derived from the
|
||||||
}
|
// entry. If a field conflicts with a standard field, it is prefixed with
|
||||||
|
// "fields.". Standard field names can be customized through FieldMap.
|
||||||
// TextFormatter formats logs into text
|
//
|
||||||
|
// Field keys are written as-is (unquoted and unescaped) in the plain
|
||||||
|
// (non-colored) format; only field values may be quoted depending on
|
||||||
|
// DisableQuote, ForceQuote, QuoteEmptyFields, and the value content.
|
||||||
|
//
|
||||||
|
// When colors are enabled, ANSI escape sequences may be added for presentation.
|
||||||
|
// For fully escaped structured output (including safe keys), use JSONFormatter.
|
||||||
type TextFormatter struct {
|
type TextFormatter struct {
|
||||||
// Set to true to bypass checking for a TTY before outputting colors.
|
// Set to true to bypass checking for a TTY before outputting colors.
|
||||||
ForceColors bool
|
ForceColors bool
|
||||||
|
|
@ -64,7 +66,7 @@ type TextFormatter struct {
|
||||||
// be desired.
|
// be desired.
|
||||||
DisableSorting bool
|
DisableSorting bool
|
||||||
|
|
||||||
// The keys sorting function, when uninitialized it uses sort.Strings.
|
// The keys sorting function, when uninitialized it uses slices.Sort.
|
||||||
SortingFunc func([]string)
|
SortingFunc func([]string)
|
||||||
|
|
||||||
// Disables the truncation of the level text to 4 characters.
|
// Disables the truncation of the level text to 4 characters.
|
||||||
|
|
@ -77,16 +79,22 @@ type TextFormatter struct {
|
||||||
// QuoteEmptyFields will wrap empty fields in quotes if true
|
// QuoteEmptyFields will wrap empty fields in quotes if true
|
||||||
QuoteEmptyFields bool
|
QuoteEmptyFields bool
|
||||||
|
|
||||||
// Whether the logger's out is to a terminal
|
// Whether the logger's out is to a terminal. Don't use this field
|
||||||
isTerminal bool
|
// directly; use TextFormatter.isTerminal instead.
|
||||||
|
terminal bool
|
||||||
|
|
||||||
// FieldMap allows users to customize the names of keys for default fields.
|
// FieldMap allows users to customize the names of keys for default fields.
|
||||||
|
// Mapped keys are written as-is, so they should be safe for plain-text output.
|
||||||
|
//
|
||||||
// As an example:
|
// As an example:
|
||||||
|
//
|
||||||
// formatter := &TextFormatter{
|
// formatter := &TextFormatter{
|
||||||
// FieldMap: FieldMap{
|
// FieldMap: FieldMap{
|
||||||
// FieldKeyTime: "@timestamp",
|
// FieldKeyTime: "@timestamp",
|
||||||
// FieldKeyLevel: "@level",
|
// FieldKeyLevel: "@level",
|
||||||
// FieldKeyMsg: "@message"}}
|
// FieldKeyMsg: "@message",
|
||||||
|
// },
|
||||||
|
// }
|
||||||
FieldMap FieldMap
|
FieldMap FieldMap
|
||||||
|
|
||||||
// CallerPrettyfier can be set by the user to modify the content
|
// CallerPrettyfier can be set by the user to modify the content
|
||||||
|
|
@ -96,54 +104,78 @@ type TextFormatter struct {
|
||||||
CallerPrettyfier func(*runtime.Frame) (function string, file string)
|
CallerPrettyfier func(*runtime.Frame) (function string, file string)
|
||||||
|
|
||||||
terminalInitOnce sync.Once
|
terminalInitOnce sync.Once
|
||||||
|
|
||||||
// The max length of the level text, generated dynamically on init
|
|
||||||
levelTextMaxLength int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) init(entry *Entry) {
|
func (f *TextFormatter) isTerminal(entry *Entry) bool {
|
||||||
if entry.Logger != nil {
|
if entry == nil || entry.Logger == nil {
|
||||||
f.isTerminal = checkIfTerminal(entry.Logger.Out)
|
// Don't run the terminalInitOnce without a logger, otherwise we'd
|
||||||
}
|
// cache the default (false) forever even if a logger is attached
|
||||||
// Get the max length of the level text
|
// later.
|
||||||
for _, level := range AllLevels {
|
return false
|
||||||
levelTextLength := utf8.RuneCount([]byte(level.String()))
|
|
||||||
if levelTextLength > f.levelTextMaxLength {
|
|
||||||
f.levelTextMaxLength = levelTextLength
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f.terminalInitOnce.Do(func() {
|
||||||
|
entry.Logger.mu.Lock()
|
||||||
|
out := entry.Logger.Out
|
||||||
|
entry.Logger.mu.Unlock()
|
||||||
|
|
||||||
|
f.terminal = checkIfTerminal(out)
|
||||||
|
})
|
||||||
|
|
||||||
|
return f.terminal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) isColored() bool {
|
func (f *TextFormatter) isColored(isTerminal bool) bool {
|
||||||
isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows"))
|
if f.DisableColors {
|
||||||
|
return false
|
||||||
if f.EnvironmentOverrideColors {
|
|
||||||
switch force, ok := os.LookupEnv("CLICOLOR_FORCE"); {
|
|
||||||
case ok && force != "0":
|
|
||||||
isColored = true
|
|
||||||
case ok && force == "0", os.Getenv("CLICOLOR") == "0":
|
|
||||||
isColored = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return isColored && !f.DisableColors
|
colored := f.ForceColors || isTerminal
|
||||||
|
if !f.EnvironmentOverrideColors {
|
||||||
|
return colored
|
||||||
|
}
|
||||||
|
if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok {
|
||||||
|
return force != "0"
|
||||||
|
}
|
||||||
|
if os.Getenv("CLICOLOR") == "0" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return colored
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format renders a single log entry
|
// Format renders a single log entry
|
||||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
data := make(Fields)
|
data := make(Fields, len(entry.Data))
|
||||||
for k, v := range entry.Data {
|
maps.Copy(data, entry.Data)
|
||||||
data[k] = v
|
isColored := f.isColored(f.isTerminal(entry))
|
||||||
}
|
|
||||||
prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
|
caller := entry.Caller
|
||||||
|
hasCaller := caller != nil
|
||||||
|
prefixFieldClashes(data, f.FieldMap, hasCaller)
|
||||||
keys := make([]string, 0, len(data))
|
keys := make([]string, 0, len(data))
|
||||||
for k := range data {
|
for k := range data {
|
||||||
keys = append(keys, k)
|
keys = append(keys, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
var funcVal, fileVal string
|
b := entry.Buffer
|
||||||
|
if b == nil {
|
||||||
|
b = new(bytes.Buffer)
|
||||||
|
}
|
||||||
|
|
||||||
fixedKeys := make([]string, 0, 4+len(data))
|
if isColored {
|
||||||
|
f.printColored(b, entry, keys, data)
|
||||||
|
} else {
|
||||||
|
f.printPlain(b, entry, keys, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return b.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *TextFormatter) printPlain(b *bytes.Buffer, entry *Entry, keys []string, data Fields) {
|
||||||
|
caller := entry.Caller
|
||||||
|
hasCaller := caller != nil
|
||||||
|
|
||||||
|
fixedKeys := make([]string, 0, len(keys)+defaultFields)
|
||||||
if !f.DisableTimestamp {
|
if !f.DisableTimestamp {
|
||||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime))
|
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime))
|
||||||
}
|
}
|
||||||
|
|
@ -154,12 +186,14 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
if entry.err != "" {
|
if entry.err != "" {
|
||||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError))
|
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError))
|
||||||
}
|
}
|
||||||
if entry.HasCaller() {
|
|
||||||
|
var funcVal, fileVal string
|
||||||
|
if caller != nil {
|
||||||
if f.CallerPrettyfier != nil {
|
if f.CallerPrettyfier != nil {
|
||||||
funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
|
funcVal, fileVal = f.CallerPrettyfier(caller)
|
||||||
} else {
|
} else {
|
||||||
funcVal = entry.Caller.Function
|
funcVal = caller.Function
|
||||||
fileVal = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
|
fileVal = caller.File + ":" + strconv.FormatInt(int64(caller.Line), 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
if funcVal != "" {
|
if funcVal != "" {
|
||||||
|
|
@ -172,152 +206,108 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
|
|
||||||
if !f.DisableSorting {
|
if !f.DisableSorting {
|
||||||
if f.SortingFunc == nil {
|
if f.SortingFunc == nil {
|
||||||
sort.Strings(keys)
|
// Default sorting does not sort the "fixed keys";
|
||||||
|
// see https://github.com/sirupsen/logrus/commit/73bc94e60c753099e8bae902f81fbd6e7dd95f26
|
||||||
|
slices.Sort(keys)
|
||||||
fixedKeys = append(fixedKeys, keys...)
|
fixedKeys = append(fixedKeys, keys...)
|
||||||
} else {
|
} else {
|
||||||
if !f.isColored() {
|
fixedKeys = append(fixedKeys, keys...)
|
||||||
fixedKeys = append(fixedKeys, keys...)
|
f.SortingFunc(fixedKeys)
|
||||||
f.SortingFunc(fixedKeys)
|
|
||||||
} else {
|
|
||||||
f.SortingFunc(keys)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fixedKeys = append(fixedKeys, keys...)
|
fixedKeys = append(fixedKeys, keys...)
|
||||||
}
|
}
|
||||||
|
|
||||||
var b *bytes.Buffer
|
for _, key := range fixedKeys {
|
||||||
if entry.Buffer != nil {
|
var value any
|
||||||
b = entry.Buffer
|
switch {
|
||||||
} else {
|
case key == f.FieldMap.resolve(FieldKeyTime):
|
||||||
b = &bytes.Buffer{}
|
if f.TimestampFormat == "" {
|
||||||
}
|
value = entry.Time.Format(defaultTimestampFormat)
|
||||||
|
} else {
|
||||||
f.terminalInitOnce.Do(func() { f.init(entry) })
|
value = entry.Time.Format(f.TimestampFormat)
|
||||||
|
|
||||||
timestampFormat := f.TimestampFormat
|
|
||||||
if timestampFormat == "" {
|
|
||||||
timestampFormat = defaultTimestampFormat
|
|
||||||
}
|
|
||||||
if f.isColored() {
|
|
||||||
f.printColored(b, entry, keys, data, timestampFormat)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
for _, key := range fixedKeys {
|
|
||||||
var value interface{}
|
|
||||||
switch {
|
|
||||||
case key == f.FieldMap.resolve(FieldKeyTime):
|
|
||||||
value = entry.Time.Format(timestampFormat)
|
|
||||||
case key == f.FieldMap.resolve(FieldKeyLevel):
|
|
||||||
value = entry.Level.String()
|
|
||||||
case key == f.FieldMap.resolve(FieldKeyMsg):
|
|
||||||
value = entry.Message
|
|
||||||
case key == f.FieldMap.resolve(FieldKeyLogrusError):
|
|
||||||
value = entry.err
|
|
||||||
case key == f.FieldMap.resolve(FieldKeyFunc) && entry.HasCaller():
|
|
||||||
value = funcVal
|
|
||||||
case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller():
|
|
||||||
value = fileVal
|
|
||||||
default:
|
|
||||||
value = data[key]
|
|
||||||
}
|
}
|
||||||
f.appendKeyValue(b, key, value)
|
case key == f.FieldMap.resolve(FieldKeyLevel):
|
||||||
|
value = entry.Level.String()
|
||||||
|
case key == f.FieldMap.resolve(FieldKeyMsg):
|
||||||
|
value = entry.Message
|
||||||
|
case key == f.FieldMap.resolve(FieldKeyLogrusError):
|
||||||
|
value = entry.err
|
||||||
|
case key == f.FieldMap.resolve(FieldKeyFunc) && hasCaller:
|
||||||
|
value = funcVal
|
||||||
|
case key == f.FieldMap.resolve(FieldKeyFile) && hasCaller:
|
||||||
|
value = fileVal
|
||||||
|
default:
|
||||||
|
value = data[key]
|
||||||
}
|
}
|
||||||
|
f.appendKeyValue(b, key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.WriteByte('\n')
|
b.WriteByte('\n')
|
||||||
return b.Bytes(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields, timestampFormat string) {
|
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields) {
|
||||||
var levelColor int
|
|
||||||
switch entry.Level {
|
|
||||||
case DebugLevel, TraceLevel:
|
|
||||||
levelColor = gray
|
|
||||||
case WarnLevel:
|
|
||||||
levelColor = yellow
|
|
||||||
case ErrorLevel, FatalLevel, PanicLevel:
|
|
||||||
levelColor = red
|
|
||||||
case InfoLevel:
|
|
||||||
levelColor = blue
|
|
||||||
default:
|
|
||||||
levelColor = blue
|
|
||||||
}
|
|
||||||
|
|
||||||
levelText := strings.ToUpper(entry.Level.String())
|
|
||||||
if !f.DisableLevelTruncation && !f.PadLevelText {
|
|
||||||
levelText = levelText[0:4]
|
|
||||||
}
|
|
||||||
if f.PadLevelText {
|
|
||||||
// Generates the format string used in the next line, for example "%-6s" or "%-7s".
|
|
||||||
// Based on the max level text length.
|
|
||||||
formatString := "%-" + strconv.Itoa(f.levelTextMaxLength) + "s"
|
|
||||||
// Formats the level text by appending spaces up to the max length, for example:
|
|
||||||
// - "INFO "
|
|
||||||
// - "WARNING"
|
|
||||||
levelText = fmt.Sprintf(formatString, levelText)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove a single newline if it already exists in the message to keep
|
// Remove a single newline if it already exists in the message to keep
|
||||||
// the behavior of logrus text_formatter the same as the stdlib log package
|
// the behavior of logrus text_formatter the same as the stdlib log package
|
||||||
entry.Message = strings.TrimSuffix(entry.Message, "\n")
|
entry.Message = strings.TrimSuffix(entry.Message, "\n")
|
||||||
|
|
||||||
caller := ""
|
var callerText string
|
||||||
if entry.HasCaller() {
|
if caller := entry.Caller; caller != nil {
|
||||||
funcVal := fmt.Sprintf("%s()", entry.Caller.Function)
|
var funcVal, fileVal string
|
||||||
fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
|
|
||||||
|
|
||||||
if f.CallerPrettyfier != nil {
|
if f.CallerPrettyfier != nil {
|
||||||
funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
|
funcVal, fileVal = f.CallerPrettyfier(caller)
|
||||||
|
} else {
|
||||||
|
if caller.Function != "" {
|
||||||
|
funcVal = caller.Function + "()"
|
||||||
|
}
|
||||||
|
fileVal = caller.File + ":" + strconv.FormatInt(int64(caller.Line), 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
if fileVal == "" {
|
if fileVal == "" {
|
||||||
caller = funcVal
|
callerText = funcVal
|
||||||
} else if funcVal == "" {
|
} else if funcVal == "" {
|
||||||
caller = fileVal
|
callerText = fileVal
|
||||||
} else {
|
} else {
|
||||||
caller = fileVal + " " + funcVal
|
callerText = fileVal + " " + funcVal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
levelText := levelPrefix(entry.Level, f.DisableLevelTruncation, f.PadLevelText)
|
||||||
switch {
|
switch {
|
||||||
case f.DisableTimestamp:
|
case f.DisableTimestamp:
|
||||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message)
|
_, _ = fmt.Fprintf(b, "%s%s %-44s ", levelText, callerText, entry.Message)
|
||||||
case !f.FullTimestamp:
|
case !f.FullTimestamp:
|
||||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message)
|
_, _ = fmt.Fprintf(b, "%s[%04d]%s %-44s ", levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), callerText, entry.Message)
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message)
|
timestampFormat := f.TimestampFormat
|
||||||
|
if timestampFormat == "" {
|
||||||
|
timestampFormat = defaultTimestampFormat
|
||||||
|
}
|
||||||
|
_, _ = fmt.Fprintf(b, "%s[%s]%s %-44s ", levelText, entry.Time.Format(timestampFormat), callerText, entry.Message)
|
||||||
}
|
}
|
||||||
for _, k := range keys {
|
|
||||||
v := data[k]
|
|
||||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
|
|
||||||
f.appendValue(b, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *TextFormatter) needsQuoting(text string) bool {
|
if !f.DisableSorting {
|
||||||
if f.ForceQuote {
|
if f.SortingFunc == nil {
|
||||||
return true
|
slices.Sort(keys)
|
||||||
}
|
} else {
|
||||||
if f.QuoteEmptyFields && len(text) == 0 {
|
f.SortingFunc(keys)
|
||||||
return true
|
|
||||||
}
|
|
||||||
if f.DisableQuote {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, ch := range text {
|
|
||||||
//nolint:staticcheck // QF1001: could apply De Morgan's law
|
|
||||||
if !((ch >= 'a' && ch <= 'z') ||
|
|
||||||
(ch >= 'A' && ch <= 'Z') ||
|
|
||||||
(ch >= '0' && ch <= '9') ||
|
|
||||||
ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
|
// Keys use the same color as the level-prefix.
|
||||||
|
for _, k := range keys {
|
||||||
|
b.WriteByte(' ')
|
||||||
|
b.WriteString(colorize(entry.Level, k))
|
||||||
|
b.WriteByte('=')
|
||||||
|
f.appendValue(b, data[k])
|
||||||
|
}
|
||||||
|
|
||||||
|
b.WriteByte('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
// appendKeyValue writes key=value. Keys are written verbatim (unquoted/unescaped);
|
||||||
|
// values are subject to quoting/escaping.
|
||||||
|
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value any) {
|
||||||
if b.Len() > 0 {
|
if b.Len() > 0 {
|
||||||
b.WriteByte(' ')
|
b.WriteByte(' ')
|
||||||
}
|
}
|
||||||
|
|
@ -326,15 +316,168 @@ func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interf
|
||||||
f.appendValue(b, value)
|
f.appendValue(b, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
func (f *TextFormatter) appendValue(b *bytes.Buffer, value any) {
|
||||||
stringVal, ok := value.(string)
|
// Fast paths.
|
||||||
if !ok {
|
switch v := value.(type) {
|
||||||
stringVal = fmt.Sprint(value)
|
case string:
|
||||||
|
f.appendString(b, v)
|
||||||
|
return
|
||||||
|
case []byte:
|
||||||
|
f.appendBytes(b, v)
|
||||||
|
return
|
||||||
|
case bool:
|
||||||
|
var raw [8]byte
|
||||||
|
f.appendBytes(b, strconv.AppendBool(raw[:0], v))
|
||||||
|
return
|
||||||
|
case error:
|
||||||
|
f.appendError(b, v)
|
||||||
|
return
|
||||||
|
case fmt.Stringer:
|
||||||
|
f.appendStringer(b, v)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !f.needsQuoting(stringVal) {
|
// Handle common primitives.
|
||||||
b.WriteString(stringVal)
|
var raw [64]byte
|
||||||
} else {
|
var num []byte
|
||||||
fmt.Fprintf(b, "%q", stringVal)
|
|
||||||
|
switch v := value.(type) {
|
||||||
|
case int:
|
||||||
|
num = strconv.AppendInt(raw[:0], int64(v), 10)
|
||||||
|
case int8:
|
||||||
|
num = strconv.AppendInt(raw[:0], int64(v), 10)
|
||||||
|
case int16:
|
||||||
|
num = strconv.AppendInt(raw[:0], int64(v), 10)
|
||||||
|
case int32:
|
||||||
|
num = strconv.AppendInt(raw[:0], int64(v), 10)
|
||||||
|
case int64:
|
||||||
|
num = strconv.AppendInt(raw[:0], v, 10)
|
||||||
|
|
||||||
|
case uint:
|
||||||
|
num = strconv.AppendUint(raw[:0], uint64(v), 10)
|
||||||
|
case uint8:
|
||||||
|
num = strconv.AppendUint(raw[:0], uint64(v), 10)
|
||||||
|
case uint16:
|
||||||
|
num = strconv.AppendUint(raw[:0], uint64(v), 10)
|
||||||
|
case uint32:
|
||||||
|
num = strconv.AppendUint(raw[:0], uint64(v), 10)
|
||||||
|
case uint64:
|
||||||
|
num = strconv.AppendUint(raw[:0], v, 10)
|
||||||
|
case uintptr:
|
||||||
|
num = strconv.AppendUint(raw[:0], uint64(v), 10)
|
||||||
|
|
||||||
|
case float32:
|
||||||
|
num = strconv.AppendFloat(raw[:0], float64(v), 'g', -1, 32)
|
||||||
|
case float64:
|
||||||
|
num = strconv.AppendFloat(raw[:0], v, 'g', -1, 64)
|
||||||
|
|
||||||
|
default:
|
||||||
|
f.appendString(b, fmt.Sprint(value))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f.appendNumeric(b, num)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *TextFormatter) appendString(b *bytes.Buffer, s string) {
|
||||||
|
quote := f.ForceQuote || (f.QuoteEmptyFields && len(s) == 0) || (!f.DisableQuote && needsQuoting(s))
|
||||||
|
if !quote {
|
||||||
|
b.WriteString(s)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(s) == 0 {
|
||||||
|
b.WriteString(`""`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp [128]byte
|
||||||
|
b.Write(strconv.AppendQuote(tmp[:0], s))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *TextFormatter) appendBytes(b *bytes.Buffer, bs []byte) {
|
||||||
|
quote := f.ForceQuote || (f.QuoteEmptyFields && len(bs) == 0) || (!f.DisableQuote && needsQuotingBytes(bs))
|
||||||
|
if !quote {
|
||||||
|
b.Write(bs)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(bs) == 0 {
|
||||||
|
b.WriteString(`""`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp [128]byte
|
||||||
|
b.Write(strconv.AppendQuote(tmp[:0], string(bs)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *TextFormatter) appendNumeric(b *bytes.Buffer, out []byte) {
|
||||||
|
if f.ForceQuote {
|
||||||
|
var tmp [128]byte
|
||||||
|
b.Write(strconv.AppendQuote(tmp[:0], string(out)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.Write(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *TextFormatter) appendError(b *bytes.Buffer, v error) {
|
||||||
|
defer f.recoverValue(b, v, "Error")
|
||||||
|
|
||||||
|
f.appendString(b, v.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *TextFormatter) appendStringer(b *bytes.Buffer, v fmt.Stringer) {
|
||||||
|
defer f.recoverValue(b, v, "String")
|
||||||
|
|
||||||
|
f.appendString(b, v.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *TextFormatter) recoverValue(b *bytes.Buffer, v any, method string) {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
rv := reflect.ValueOf(v)
|
||||||
|
if rv.Kind() == reflect.Pointer && rv.IsNil() {
|
||||||
|
f.appendString(b, "<nil>")
|
||||||
|
} else {
|
||||||
|
f.appendString(b, fmt.Sprintf("%%!v(PANIC=%s method: %v)", method, r))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// needsQuoting returns true if the string contains any byte that
|
||||||
|
// requires quoting. It returns false when every byte is "safe" according
|
||||||
|
// to isSafeByte.
|
||||||
|
func needsQuoting(s string) bool {
|
||||||
|
// use an index loop (avoid rune decoding).
|
||||||
|
for i := range len(s) {
|
||||||
|
c := s[i]
|
||||||
|
if !isSafeByte(c) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// needsQuotingBytes returns true if the byte slice contains any byte that
|
||||||
|
// requires quoting. It returns false when every byte is "safe" according
|
||||||
|
// to isSafeByte.
|
||||||
|
func needsQuotingBytes(bs []byte) bool {
|
||||||
|
for _, c := range bs {
|
||||||
|
if !isSafeByte(c) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// isSafeByte returns true if the byte is allowed unquoted (ASCII and in the allowlist).
|
||||||
|
// It purposely uses byte arithmetic (no runes) for performance.
|
||||||
|
func isSafeByte(ch byte) bool {
|
||||||
|
ok := ch < 0x80 && ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9'))
|
||||||
|
if ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
switch ch {
|
||||||
|
case '-', '.', '_', '/', '@', '^', '+':
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
vendor/github.com/sirupsen/logrus/writer.go
generated
vendored
6
vendor/github.com/sirupsen/logrus/writer.go
generated
vendored
|
|
@ -30,7 +30,7 @@ func (entry *Entry) Writer() *io.PipeWriter {
|
||||||
func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
|
func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
|
||||||
reader, writer := io.Pipe()
|
reader, writer := io.Pipe()
|
||||||
|
|
||||||
var printFunc func(args ...interface{})
|
printFunc := entry.Print
|
||||||
|
|
||||||
// Determine which log function to use based on the specified log level
|
// Determine which log function to use based on the specified log level
|
||||||
switch level {
|
switch level {
|
||||||
|
|
@ -48,8 +48,6 @@ func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
|
||||||
printFunc = entry.Fatal
|
printFunc = entry.Fatal
|
||||||
case PanicLevel:
|
case PanicLevel:
|
||||||
printFunc = entry.Panic
|
printFunc = entry.Panic
|
||||||
default:
|
|
||||||
printFunc = entry.Print
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start a new goroutine to scan the input and write it to the logger using the specified print function.
|
// Start a new goroutine to scan the input and write it to the logger using the specified print function.
|
||||||
|
|
@ -63,7 +61,7 @@ func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// writerScanner scans the input from the reader and writes it to the logger
|
// writerScanner scans the input from the reader and writes it to the logger
|
||||||
func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
|
func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...any)) {
|
||||||
scanner := bufio.NewScanner(reader)
|
scanner := bufio.NewScanner(reader)
|
||||||
|
|
||||||
// Set the buffer size to the maximum token size to avoid buffer overflows
|
// Set the buffer size to the maximum token size to avoid buffer overflows
|
||||||
|
|
|
||||||
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
|
|
@ -134,8 +134,8 @@ github.com/sanity-io/litter
|
||||||
# github.com/sasha-s/go-deadlock v0.3.9
|
# github.com/sasha-s/go-deadlock v0.3.9
|
||||||
## explicit
|
## explicit
|
||||||
github.com/sasha-s/go-deadlock
|
github.com/sasha-s/go-deadlock
|
||||||
# github.com/sirupsen/logrus v1.9.4
|
# github.com/sirupsen/logrus v1.10.2
|
||||||
## explicit; go 1.17
|
## explicit; go 1.23
|
||||||
github.com/sirupsen/logrus
|
github.com/sirupsen/logrus
|
||||||
# github.com/spf13/afero v1.15.0
|
# github.com/spf13/afero v1.15.0
|
||||||
## explicit; go 1.23.0
|
## explicit; go 1.23.0
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue