chore: set log to main (#23698)
This commit is contained in:
parent
256e3e143b
commit
8abca32b6c
@ -11,29 +11,55 @@ Mention whether you follow Semantic Versioning.
|
||||
|
||||
Usage:
|
||||
|
||||
Change log entries are to be added to the Unreleased section under the
|
||||
appropriate stanza (see below). Each entry should ideally include a tag and
|
||||
the Github issue reference in the following format:
|
||||
Change log entries are to be added to the Unreleased section from newest to oldest.
|
||||
Each entry must include the Github issue reference in the following format:
|
||||
|
||||
* (<tag>) [#<issue-number>] Changelog message.
|
||||
* [#<issue-number>] Changelog message.
|
||||
|
||||
Types of changes (Stanzas):
|
||||
|
||||
"Features" for new features.
|
||||
"Improvements" for changes in existing functionality.
|
||||
"Deprecated" for soon-to-be removed features.
|
||||
"Bug Fixes" for any bug fixes.
|
||||
"API Breaking" for breaking exported APIs used by developers building on SDK.
|
||||
Ref: https://keepachangelog.com/en/1.0.0/
|
||||
-->
|
||||
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Features
|
||||
## [v1.5.0](https://github.com/cosmos/cosmos-sdk/releases/tag/log/v1.4.1) - 2024-11-07
|
||||
|
||||
* [#15956](https://github.com/cosmos/cosmos-sdk/pull/15956) Introduce extra options to configure logger.
|
||||
* [#22466](https://github.com/cosmos/cosmos-sdk/pull/22466) Disable coloring in testing logger.
|
||||
* [#22233](https://github.com/cosmos/cosmos-sdk/pull/22233) Use sonic json library for faster json handling.
|
||||
* [#22347](https://github.com/cosmos/cosmos-sdk/pull/22347) Add `cosmossdk.io/log/slog` to allow using a standard library log/slog-backed logger. This required to bump the minimum go version of `cosmossdk.io/log` to 1.21.
|
||||
|
||||
## [v1.4.1](https://github.com/cosmos/cosmos-sdk/releases/tag/log/v1.4.1) - 2024-08-16
|
||||
|
||||
* [#21326](https://github.com/cosmos/cosmos-sdk/pull/21326) Avoid context key collision.
|
||||
|
||||
## [v1.4.0](https://github.com/cosmos/cosmos-sdk/releases/tag/log/v1.4.0) - 2024-08-07
|
||||
|
||||
* [#21045](https://github.com/cosmos/cosmos-sdk/pull/21045) Add `WithContext` method implementations to make all returned loggers compatible with `cosmossdk.io/core/log.Logger` (v1) without a direct dependency.
|
||||
|
||||
## [v1.3.1](https://github.com/cosmos/cosmos-sdk/releases/tag/log/v1.3.1) - 2024-02-05
|
||||
|
||||
* [#19346](https://github.com/cosmos/cosmos-sdk/pull/19346) Upgrade zerolog to v1.32.0.
|
||||
* [#19346](https://github.com/cosmos/cosmos-sdk/pull/19346) `#15956` now works thanks to the upgrade of `zerolog`.
|
||||
|
||||
## [v1.3.0](https://github.com/cosmos/cosmos-sdk/releases/tag/log/v1.3.0) - 2024-01-10
|
||||
|
||||
* [#18916](https://github.com/cosmos/cosmos-sdk/pull/18916) Introduce an option for setting hooks.
|
||||
* [#18429](https://github.com/cosmos/cosmos-sdk/pull/18429) Support customization of log json marshal.
|
||||
* [#18898](https://github.com/cosmos/cosmos-sdk/pull/18898) Add `WARN` level.
|
||||
|
||||
## [v1.2.1](https://github.com/cosmos/cosmos-sdk/releases/tag/log/v1.2.1) - 2023-08-25
|
||||
|
||||
* [#17532](https://github.com/cosmos/cosmos-sdk/pull/17532) Proper marshalling of `fmt.Stringer` (follow-up of [#17205](https://github.com/cosmos/cosmos-sdk/pull/17205)).
|
||||
|
||||
## [v1.2.0](https://github.com/cosmos/cosmos-sdk/releases/tag/log/v1.2.0) - 2023-07-31
|
||||
|
||||
* [#17194](https://github.com/cosmos/cosmos-sdk/pull/17194) Avoid repeating parse log level in `ParseLogLevel`.
|
||||
* [#17205](https://github.com/cosmos/cosmos-sdk/pull/17205) Fix types that do not implement the `json.Marshaler` interface.
|
||||
* [#15956](https://github.com/cosmos/cosmos-sdk/pull/15956) Introduce an option for enabling error stack trace.
|
||||
|
||||
## [v1.1.0](https://github.com/cosmos/cosmos-sdk/releases/tag/log/v1.1.0) - 2023-04-27
|
||||
|
||||
* [#15956](https://github.com/cosmos/cosmos-sdk/pull/15956) Introduce options to configure logger (enable/disable colored output, customize log timestamps).
|
||||
|
||||
## [v1.0.0](https://github.com/cosmos/cosmos-sdk/releases/tag/log/v1.0.0) - 2023-03-30
|
||||
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
# Log
|
||||
|
||||
The `cosmossdk.io/log` provides a zerolog logging implementation for the Cosmos SDK and Cosmos SDK modules.
|
||||
|
||||
To use a logger wrapping an instance of the standard library's `log/slog` package, use `cosmossdk.io/log/slog`.
|
||||
|
||||
@ -83,7 +83,6 @@ func BenchmarkLoggers(b *testing.B) {
|
||||
// so that real write time is negligible.
|
||||
b.Run("zerolog", func(b *testing.B) {
|
||||
for _, bc := range benchCases {
|
||||
bc := bc
|
||||
b.Run(bc.name, func(b *testing.B) {
|
||||
zl := zerolog.New(io.Discard)
|
||||
logger := log.NewCustomLogger(zl)
|
||||
@ -99,7 +98,6 @@ func BenchmarkLoggers(b *testing.B) {
|
||||
// also useful as a reference for how expensive zerolog is.
|
||||
b.Run("specialized nop logger", func(b *testing.B) {
|
||||
for _, bc := range nopCases {
|
||||
bc := bc
|
||||
b.Run(bc.name, func(b *testing.B) {
|
||||
logger := log.NewNopLogger()
|
||||
|
||||
@ -115,7 +113,6 @@ func BenchmarkLoggers(b *testing.B) {
|
||||
// so we offer the specialized version in the exported API.
|
||||
b.Run("zerolog nop logger", func(b *testing.B) {
|
||||
for _, bc := range nopCases {
|
||||
bc := bc
|
||||
b.Run(bc.name, func(b *testing.B) {
|
||||
logger := log.NewCustomLogger(zerolog.Nop())
|
||||
|
||||
|
||||
15
log/go.mod
15
log/go.mod
@ -3,13 +3,18 @@ module cosmossdk.io/log
|
||||
go 1.23
|
||||
|
||||
require (
|
||||
github.com/rs/zerolog v1.29.1
|
||||
gotest.tools/v3 v3.4.0
|
||||
github.com/bytedance/sonic v1.12.8
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/rs/zerolog v1.33.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.5.5 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.3 // indirect
|
||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
golang.org/x/arch v0.13.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
)
|
||||
|
||||
81
log/go.sum
81
log/go.sum
@ -1,47 +1,52 @@
|
||||
github.com/bytedance/sonic v1.12.8 h1:4xYRVRlXIgvSZ4e8iVTlMF5szgpXd4AfvuWgA8I8lgs=
|
||||
github.com/bytedance/sonic v1.12.8/go.mod h1:uVvFidNmlt9+wa31S1urfwwthTWteBgG0hWuoKAXTx8=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.3 h1:yctD0Q3v2NOGfSWPLPvG2ggA2kV6TS6s4wioyEqssH0=
|
||||
github.com/bytedance/sonic/loader v0.2.3/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
||||
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
|
||||
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
|
||||
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
||||
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
golang.org/x/arch v0.13.0 h1:KCkqVVV1kGg0X87TFysjCJ8MxtZEIU4Ja/yXGeoECdA=
|
||||
golang.org/x/arch v0.13.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
|
||||
gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
|
||||
16
log/level.go
16
log/level.go
@ -35,7 +35,7 @@ func ParseLogLevel(levelStr string) (FilterFunc, error) {
|
||||
}
|
||||
|
||||
// parse and validate the levels
|
||||
filterMap := make(map[string]string)
|
||||
filterMap := make(map[string]zerolog.Level)
|
||||
list := strings.Split(l, ",")
|
||||
for _, item := range list {
|
||||
moduleAndLevel := strings.Split(item, ":")
|
||||
@ -50,18 +50,19 @@ func ParseLogLevel(levelStr string) (FilterFunc, error) {
|
||||
return nil, fmt.Errorf("duplicate module %s in log level list %s", module, list)
|
||||
}
|
||||
|
||||
if _, err := zerolog.ParseLevel(level); err != nil {
|
||||
zllevel, err := zerolog.ParseLevel(level)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid log level %s in log level list %s", level, list)
|
||||
}
|
||||
|
||||
filterMap[module] = level
|
||||
filterMap[module] = zllevel
|
||||
}
|
||||
|
||||
filterFunc := func(key, lvl string) bool {
|
||||
level, ok := filterMap[key]
|
||||
zllevel, ok := filterMap[key]
|
||||
if !ok { // no level filter for this key
|
||||
// check if there is a default level filter
|
||||
level, ok = filterMap[defaultLogLevelKey]
|
||||
zllevel, ok = filterMap[defaultLogLevelKey]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@ -72,11 +73,6 @@ func ParseLogLevel(levelStr string) (FilterFunc, error) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
zllevel, err := zerolog.ParseLevel(level)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return zllvl < zllevel
|
||||
}
|
||||
|
||||
|
||||
@ -3,46 +3,88 @@ package log_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
)
|
||||
|
||||
func TestParseLogLevel(t *testing.T) {
|
||||
_, err := log.ParseLogLevel("")
|
||||
assert.Error(t, err, "empty log level")
|
||||
if err == nil {
|
||||
t.Errorf("expected error for empty log level, got nil")
|
||||
}
|
||||
|
||||
level := "consensus:foo,mempool:debug,*:error"
|
||||
_, err = log.ParseLogLevel(level)
|
||||
assert.Error(t, err, "invalid log level foo in log level list [consensus:foo mempool:debug *:error]")
|
||||
if err == nil {
|
||||
t.Errorf("expected error for invalid log level foo in log level list [consensus:foo mempool:debug *:error], got nil")
|
||||
}
|
||||
|
||||
level = "consensus:debug,mempool:debug,*:error"
|
||||
filter, err := log.ParseLogLevel(level)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, filter != nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if filter == nil {
|
||||
t.Fatalf("expected non-nil filter, got nil")
|
||||
}
|
||||
|
||||
assert.Assert(t, !filter("consensus", "debug"))
|
||||
assert.Assert(t, !filter("consensus", "info"))
|
||||
assert.Assert(t, !filter("consensus", "error"))
|
||||
assert.Assert(t, !filter("mempool", "debug"))
|
||||
assert.Assert(t, !filter("mempool", "info"))
|
||||
assert.Assert(t, !filter("mempool", "error"))
|
||||
assert.Assert(t, !filter("state", "error"))
|
||||
assert.Assert(t, !filter("server", "panic"))
|
||||
if filter("consensus", "debug") {
|
||||
t.Errorf("expected filter to return false for consensus:debug")
|
||||
}
|
||||
if filter("consensus", "info") {
|
||||
t.Errorf("expected filter to return false for consensus:info")
|
||||
}
|
||||
if filter("consensus", "error") {
|
||||
t.Errorf("expected filter to return false for consensus:error")
|
||||
}
|
||||
if filter("mempool", "debug") {
|
||||
t.Errorf("expected filter to return false for mempool:debug")
|
||||
}
|
||||
if filter("mempool", "info") {
|
||||
t.Errorf("expected filter to return false for mempool:info")
|
||||
}
|
||||
if filter("mempool", "error") {
|
||||
t.Errorf("expected filter to return false for mempool:error")
|
||||
}
|
||||
if filter("state", "error") {
|
||||
t.Errorf("expected filter to return false for state:error")
|
||||
}
|
||||
if filter("server", "panic") {
|
||||
t.Errorf("expected filter to return false for server:panic")
|
||||
}
|
||||
|
||||
assert.Assert(t, filter("server", "debug"))
|
||||
assert.Assert(t, filter("state", "debug"))
|
||||
assert.Assert(t, filter("state", "info"))
|
||||
if !filter("server", "debug") {
|
||||
t.Errorf("expected filter to return true for server:debug")
|
||||
}
|
||||
if !filter("state", "debug") {
|
||||
t.Errorf("expected filter to return true for state:debug")
|
||||
}
|
||||
if !filter("state", "info") {
|
||||
t.Errorf("expected filter to return true for state:info")
|
||||
}
|
||||
|
||||
level = "error"
|
||||
filter, err = log.ParseLogLevel(level)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, filter != nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if filter == nil {
|
||||
t.Fatalf("expected non-nil filter, got nil")
|
||||
}
|
||||
|
||||
assert.Assert(t, !filter("state", "error"))
|
||||
assert.Assert(t, !filter("consensus", "error"))
|
||||
if filter("state", "error") {
|
||||
t.Errorf("expected filter to return false for state:error")
|
||||
}
|
||||
if filter("consensus", "error") {
|
||||
t.Errorf("expected filter to return false for consensus:error")
|
||||
}
|
||||
|
||||
assert.Assert(t, filter("consensus", "debug"))
|
||||
assert.Assert(t, filter("consensus", "info"))
|
||||
assert.Assert(t, filter("state", "debug"))
|
||||
if !filter("consensus", "debug") {
|
||||
t.Errorf("expected filter to return true for consensus:debug")
|
||||
}
|
||||
if !filter("consensus", "info") {
|
||||
t.Errorf("expected filter to return true for consensus:info")
|
||||
}
|
||||
if !filter("state", "debug") {
|
||||
t.Errorf("expected filter to return true for state:debug")
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,25 +1,50 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/bytedance/sonic"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/pkgerrors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
zerolog.InterfaceMarshalFunc = func(i any) ([]byte, error) {
|
||||
switch v := i.(type) {
|
||||
case json.Marshaler:
|
||||
return sonic.Marshal(i)
|
||||
case encoding.TextMarshaler:
|
||||
return sonic.Marshal(i)
|
||||
case fmt.Stringer:
|
||||
return sonic.Marshal(v.String())
|
||||
default:
|
||||
return sonic.Marshal(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ModuleKey defines a module logging key.
|
||||
const ModuleKey = "module"
|
||||
|
||||
// ContextKey is used to store the logger in the context.
|
||||
var ContextKey struct{}
|
||||
var ContextKey contextKey
|
||||
|
||||
type contextKey struct{}
|
||||
|
||||
// Logger is the Cosmos SDK logger interface.
|
||||
// It maintains as much backward compatibility with the CometBFT logger as possible.
|
||||
// All functionalities of the logger are available through the Impl() method.
|
||||
type Logger interface {
|
||||
// Info takes a message and a set of key/value pairs and logs with level INFO.
|
||||
// The key of the tuple must be a string.
|
||||
Info(msg string, keyVals ...any)
|
||||
|
||||
// Warn takes a message and a set of key/value pairs and logs with level WARN.
|
||||
// The key of the tuple must be a string.
|
||||
Warn(msg string, keyVals ...any)
|
||||
|
||||
// Error takes a message and a set of key/value pairs and logs with level ERR.
|
||||
// The key of the tuple must be a string.
|
||||
Error(msg string, keyVals ...any)
|
||||
@ -37,6 +62,22 @@ type Logger interface {
|
||||
Impl() any
|
||||
}
|
||||
|
||||
// WithJSONMarshal configures zerolog global json encoding.
|
||||
func WithJSONMarshal(marshaler func(v any) ([]byte, error)) {
|
||||
zerolog.InterfaceMarshalFunc = func(i any) ([]byte, error) {
|
||||
switch v := i.(type) {
|
||||
case json.Marshaler:
|
||||
return marshaler(i)
|
||||
case encoding.TextMarshaler:
|
||||
return marshaler(i)
|
||||
case fmt.Stringer:
|
||||
return marshaler(v.String())
|
||||
default:
|
||||
return marshaler(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type zeroLogWrapper struct {
|
||||
*zerolog.Logger
|
||||
}
|
||||
@ -69,6 +110,15 @@ func NewLogger(dst io.Writer, options ...Option) Logger {
|
||||
}
|
||||
|
||||
logger := zerolog.New(output)
|
||||
|
||||
if logCfg.StackTrace {
|
||||
zerolog.ErrorStackMarshaler = func(err error) interface{} {
|
||||
return pkgerrors.MarshalStack(errors.WithStack(err))
|
||||
}
|
||||
|
||||
logger = logger.With().Stack().Logger()
|
||||
}
|
||||
|
||||
if logCfg.TimeFormat != "" {
|
||||
logger = logger.With().Timestamp().Logger()
|
||||
}
|
||||
@ -77,6 +127,8 @@ func NewLogger(dst io.Writer, options ...Option) Logger {
|
||||
logger = logger.Level(logCfg.Level)
|
||||
}
|
||||
|
||||
logger = logger.Hook(logCfg.Hooks...)
|
||||
|
||||
return zeroLogWrapper{&logger}
|
||||
}
|
||||
|
||||
@ -91,13 +143,19 @@ func (l zeroLogWrapper) Info(msg string, keyVals ...interface{}) {
|
||||
l.Logger.Info().Fields(keyVals).Msg(msg)
|
||||
}
|
||||
|
||||
// Error takes a message and a set of key/value pairs and logs with level DEBUG.
|
||||
// Warn takes a message and a set of key/value pairs and logs with level WARN.
|
||||
// The key of the tuple must be a string.
|
||||
func (l zeroLogWrapper) Warn(msg string, keyVals ...interface{}) {
|
||||
l.Logger.Warn().Fields(keyVals).Msg(msg)
|
||||
}
|
||||
|
||||
// Error takes a message and a set of key/value pairs and logs with level ERROR.
|
||||
// The key of the tuple must be a string.
|
||||
func (l zeroLogWrapper) Error(msg string, keyVals ...interface{}) {
|
||||
l.Logger.Error().Fields(keyVals).Msg(msg)
|
||||
}
|
||||
|
||||
// Debug takes a message and a set of key/value pairs and logs with level ERR.
|
||||
// Debug takes a message and a set of key/value pairs and logs with level DEBUG.
|
||||
// The key of the tuple must be a string.
|
||||
func (l zeroLogWrapper) Debug(msg string, keyVals ...interface{}) {
|
||||
l.Logger.Debug().Fields(keyVals).Msg(msg)
|
||||
@ -109,6 +167,12 @@ func (l zeroLogWrapper) With(keyVals ...interface{}) Logger {
|
||||
return zeroLogWrapper{&logger}
|
||||
}
|
||||
|
||||
// WithContext returns a new wrapped logger with additional context provided by a set.
|
||||
func (l zeroLogWrapper) WithContext(keyVals ...interface{}) any {
|
||||
logger := l.Logger.With().Fields(keyVals).Logger()
|
||||
return zeroLogWrapper{&logger}
|
||||
}
|
||||
|
||||
// Impl returns the underlying zerolog logger.
|
||||
// It can be used to used zerolog structured API directly instead of the wrapper.
|
||||
func (l zeroLogWrapper) Impl() interface{} {
|
||||
@ -126,8 +190,10 @@ func NewNopLogger() Logger {
|
||||
// The custom implementation is about 3x faster.
|
||||
type nopLogger struct{}
|
||||
|
||||
func (nopLogger) Info(string, ...any) {}
|
||||
func (nopLogger) Error(string, ...any) {}
|
||||
func (nopLogger) Debug(string, ...any) {}
|
||||
func (nopLogger) With(...any) Logger { return nopLogger{} }
|
||||
func (nopLogger) Impl() any { return nopLogger{} }
|
||||
func (nopLogger) Info(string, ...any) {}
|
||||
func (nopLogger) Warn(string, ...any) {}
|
||||
func (nopLogger) Error(string, ...any) {}
|
||||
func (nopLogger) Debug(string, ...any) {}
|
||||
func (nopLogger) With(...any) Logger { return nopLogger{} }
|
||||
func (nopLogger) WithContext(...any) any { return nopLogger{} }
|
||||
func (nopLogger) Impl() any { return nopLogger{} }
|
||||
|
||||
61
log/logger_test.go
Normal file
61
log/logger_test.go
Normal file
@ -0,0 +1,61 @@
|
||||
package log_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
)
|
||||
|
||||
func inner() error {
|
||||
return errors.New("seems we have an error here")
|
||||
}
|
||||
|
||||
type _MockHook string
|
||||
|
||||
func (h _MockHook) Run(e *zerolog.Event, l zerolog.Level, msg string) {
|
||||
e.Bool(string(h), true)
|
||||
}
|
||||
|
||||
func TestLoggerOptionHooks(t *testing.T) {
|
||||
buf := new(bytes.Buffer)
|
||||
var (
|
||||
mockHook1 _MockHook = "mock_message1"
|
||||
mockHook2 _MockHook = "mock_message2"
|
||||
)
|
||||
logger := log.NewLogger(buf, log.HooksOption(mockHook1, mockHook2), log.ColorOption(false))
|
||||
logger.Info("hello world")
|
||||
if !strings.Contains(buf.String(), "mock_message1=true") {
|
||||
t.Fatalf("expected mock_message1=true, got: %s", buf.String())
|
||||
}
|
||||
if !strings.Contains(buf.String(), "mock_message2=true") {
|
||||
t.Fatalf("expected mock_message2=true, got: %s", buf.String())
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
logger = log.NewLogger(buf, log.HooksOption(), log.ColorOption(false))
|
||||
logger.Info("hello world")
|
||||
if !strings.Contains(buf.String(), "hello world") {
|
||||
t.Fatalf("expected hello world, got: %s", buf.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoggerOptionStackTrace(t *testing.T) {
|
||||
buf := new(bytes.Buffer)
|
||||
logger := log.NewLogger(buf, log.TraceOption(true), log.ColorOption(false))
|
||||
logger.Error("this log should be displayed", "error", inner())
|
||||
if strings.Count(buf.String(), "logger_test.go") != 1 {
|
||||
t.Fatalf("stack trace not found, got: %s", buf.String())
|
||||
}
|
||||
buf.Reset()
|
||||
|
||||
logger = log.NewLogger(buf, log.TraceOption(false), log.ColorOption(false))
|
||||
logger.Error("this log should be displayed", "error", inner())
|
||||
if strings.Count(buf.String(), "logger_test.go") > 0 {
|
||||
t.Fatalf("stack trace found, got: %s", buf.String())
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,9 @@ var defaultConfig = Config{
|
||||
Filter: nil,
|
||||
OutputJSON: false,
|
||||
Color: true,
|
||||
StackTrace: false,
|
||||
TimeFormat: time.Kitchen,
|
||||
Hooks: nil,
|
||||
}
|
||||
|
||||
// Config defines configuration for the logger.
|
||||
@ -21,7 +23,9 @@ type Config struct {
|
||||
Filter FilterFunc
|
||||
OutputJSON bool
|
||||
Color bool
|
||||
StackTrace bool
|
||||
TimeFormat string
|
||||
Hooks []zerolog.Hook
|
||||
}
|
||||
|
||||
type Option func(*Config)
|
||||
@ -78,3 +82,17 @@ func TimeFormatOption(format string) Option {
|
||||
cfg.TimeFormat = format
|
||||
}
|
||||
}
|
||||
|
||||
// TraceOption add option to enable/disable print of stacktrace on error log
|
||||
func TraceOption(val bool) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.StackTrace = val
|
||||
}
|
||||
}
|
||||
|
||||
// HooksOption append hooks to the Logger hooks
|
||||
func HooksOption(hooks ...zerolog.Hook) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.Hooks = append(cfg.Hooks, hooks...)
|
||||
}
|
||||
}
|
||||
|
||||
50
log/slog/logger.go
Normal file
50
log/slog/logger.go
Normal file
@ -0,0 +1,50 @@
|
||||
// Package slog contains a Logger type that satisfies [cosmossdk.io/log.Logger],
|
||||
// backed by a standard library [*log/slog.Logger].
|
||||
package slog
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
)
|
||||
|
||||
var _ log.Logger = Logger{}
|
||||
|
||||
// Logger satisfies [log.Logger] with logging backed by
|
||||
// an instance of [*slog.Logger].
|
||||
type Logger struct {
|
||||
log *slog.Logger
|
||||
}
|
||||
|
||||
// NewCustomLogger returns a Logger backed by an existing slog.Logger instance.
|
||||
// All logging methods are called directly on the *slog.Logger;
|
||||
// therefore it is the caller's responsibility to configure message filtering,
|
||||
// level filtering, output format, and so on.
|
||||
func NewCustomLogger(log *slog.Logger) Logger {
|
||||
return Logger{log: log}
|
||||
}
|
||||
|
||||
func (l Logger) Info(msg string, keyVals ...any) {
|
||||
l.log.Info(msg, keyVals...)
|
||||
}
|
||||
|
||||
func (l Logger) Warn(msg string, keyVals ...any) {
|
||||
l.log.Warn(msg, keyVals...)
|
||||
}
|
||||
|
||||
func (l Logger) Error(msg string, keyVals ...any) {
|
||||
l.log.Error(msg, keyVals...)
|
||||
}
|
||||
|
||||
func (l Logger) Debug(msg string, keyVals ...any) {
|
||||
l.log.Debug(msg, keyVals...)
|
||||
}
|
||||
|
||||
func (l Logger) With(keyVals ...any) log.Logger {
|
||||
return Logger{log: l.log.With(keyVals...)}
|
||||
}
|
||||
|
||||
// Impl returns l's underlying [*slog.Logger].
|
||||
func (l Logger) Impl() any {
|
||||
return l.log
|
||||
}
|
||||
92
log/slog/logger_test.go
Normal file
92
log/slog/logger_test.go
Normal file
@ -0,0 +1,92 @@
|
||||
package slog_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
stdslog "log/slog"
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/log/slog"
|
||||
)
|
||||
|
||||
func TestSlog(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
h := stdslog.NewJSONHandler(&buf, &stdslog.HandlerOptions{
|
||||
Level: stdslog.LevelDebug,
|
||||
})
|
||||
logger := slog.NewCustomLogger(stdslog.New(h))
|
||||
|
||||
type logLine struct {
|
||||
Level string `json:"level"`
|
||||
Msg string `json:"msg"`
|
||||
Num int `json:"num"`
|
||||
}
|
||||
|
||||
var line logLine
|
||||
|
||||
logger.Debug("Message one", "num", 1)
|
||||
if err := json.Unmarshal(buf.Bytes(), &line); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if want := (logLine{
|
||||
Level: stdslog.LevelDebug.String(),
|
||||
Msg: "Message one",
|
||||
Num: 1,
|
||||
}); want != line {
|
||||
t.Fatalf("unexpected log record: want %v, got %v", want, line)
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
logger.Info("Message two", "num", 2)
|
||||
if err := json.Unmarshal(buf.Bytes(), &line); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if want := (logLine{
|
||||
Level: stdslog.LevelInfo.String(),
|
||||
Msg: "Message two",
|
||||
Num: 2,
|
||||
}); want != line {
|
||||
t.Fatalf("unexpected log record: want %v, got %v", want, line)
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
logger.Warn("Message three", "num", 3)
|
||||
if err := json.Unmarshal(buf.Bytes(), &line); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if want := (logLine{
|
||||
Level: stdslog.LevelWarn.String(),
|
||||
Msg: "Message three",
|
||||
Num: 3,
|
||||
}); want != line {
|
||||
t.Fatalf("unexpected log record: want %v, got %v", want, line)
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
logger.Error("Message four", "num", 4)
|
||||
if err := json.Unmarshal(buf.Bytes(), &line); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if want := (logLine{
|
||||
Level: stdslog.LevelError.String(),
|
||||
Msg: "Message four",
|
||||
Num: 4,
|
||||
}); want != line {
|
||||
t.Fatalf("unexpected log record: want %v, got %v", want, line)
|
||||
}
|
||||
|
||||
wLogger := logger.With("num", 5)
|
||||
buf.Reset()
|
||||
wLogger.Info("Using .With")
|
||||
|
||||
if err := json.Unmarshal(buf.Bytes(), &line); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if want := (logLine{
|
||||
Level: stdslog.LevelInfo.String(),
|
||||
Msg: "Using .With",
|
||||
Num: 5,
|
||||
}); want != line {
|
||||
t.Fatalf("unexpected log record: want %v, got %v", want, line)
|
||||
}
|
||||
}
|
||||
16
log/sonar-project.properties
Normal file
16
log/sonar-project.properties
Normal file
@ -0,0 +1,16 @@
|
||||
sonar.projectKey=cosmos-sdk-log
|
||||
sonar.organization=cosmos
|
||||
|
||||
sonar.projectName=Cosmos SDK - Log
|
||||
sonar.project.monorepo.enabled=true
|
||||
|
||||
sonar.sources=.
|
||||
sonar.exclusions=**/*_test.go,**/*.pb.go,**/*.pulsar.go,**/*.pb.gw.go
|
||||
sonar.coverage.exclusions=**/*_test.go,**/testutil/**,**/*.pb.go,**/*.pb.gw.go,**/*.pulsar.go,test_helpers.go,docs/**
|
||||
sonar.tests=.
|
||||
sonar.test.inclusions=**/*_test.go
|
||||
sonar.go.coverage.reportPaths=coverage.out
|
||||
|
||||
sonar.sourceEncoding=UTF-8
|
||||
sonar.scm.provider=git
|
||||
sonar.scm.forceReloadAll=true
|
||||
@ -1,6 +1,10 @@
|
||||
package log
|
||||
|
||||
import "github.com/rs/zerolog"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// TestingT is the interface required for logging in tests.
|
||||
// It is a subset of testing.T to avoid a direct dependency on the testing package.
|
||||
@ -39,15 +43,18 @@ func NewTestLoggerError(t TestingT) Logger {
|
||||
}
|
||||
|
||||
func newTestLogger(t TestingT, lvl zerolog.Level) Logger {
|
||||
cw := zerolog.NewConsoleWriter()
|
||||
cw.Out = zerolog.TestWriter{
|
||||
T: t,
|
||||
// Normally one would use zerolog.ConsoleTestWriter
|
||||
// to set the option on NewConsoleWriter,
|
||||
// but the zerolog source for that is hardcoded to Frame=6.
|
||||
// With Frame=6, all source locations are printed as "logger.go",
|
||||
// but Frame=7 prints correct source locations.
|
||||
Frame: 7,
|
||||
cw := zerolog.ConsoleWriter{
|
||||
NoColor: true,
|
||||
TimeFormat: time.Kitchen,
|
||||
Out: zerolog.TestWriter{
|
||||
T: t,
|
||||
// Normally one would use zerolog.ConsoleTestWriter
|
||||
// to set the option on NewConsoleWriter,
|
||||
// but the zerolog source for that is hardcoded to Frame=6.
|
||||
// With Frame=6, all source locations are printed as "logger.go",
|
||||
// but Frame=7 prints correct source locations.
|
||||
Frame: 7,
|
||||
},
|
||||
}
|
||||
return NewCustomLogger(zerolog.New(cw).Level(lvl))
|
||||
}
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/bytedance/sonic"
|
||||
)
|
||||
|
||||
// NewFilterWriter returns a writer that filters out all key/value pairs that do not match the filter.
|
||||
@ -28,7 +29,7 @@ func (fw *filterWriter) Write(p []byte) (n int, err error) {
|
||||
Module string `json:"module"`
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(p, &event); err != nil {
|
||||
if err := sonic.Unmarshal(p, &event); err != nil {
|
||||
return 0, fmt.Errorf("failed to unmarshal event: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@ -5,8 +5,6 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
)
|
||||
|
||||
@ -15,13 +13,19 @@ func TestFilteredWriter(t *testing.T) {
|
||||
|
||||
level := "consensus:debug,mempool:debug,*:error"
|
||||
filter, err := log.ParseLogLevel(level)
|
||||
assert.NilError(t, err)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse log level: %v", err)
|
||||
}
|
||||
|
||||
logger := log.NewLogger(buf, log.FilterOption(filter))
|
||||
logger.Debug("this log line should be displayed", log.ModuleKey, "consensus")
|
||||
assert.Check(t, strings.Contains(buf.String(), "this log line should be displayed"))
|
||||
if !strings.Contains(buf.String(), "this log line should be displayed") {
|
||||
t.Errorf("expected log line to be displayed, but it was not")
|
||||
}
|
||||
buf.Reset()
|
||||
|
||||
logger.Debug("this log line should be filtered", log.ModuleKey, "server")
|
||||
assert.Check(t, buf.Len() == 0)
|
||||
if buf.Len() != 0 {
|
||||
t.Errorf("expected log line to be filtered, but it was not")
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user