diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:41:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:41:39 +0000 |
commit | fcfb5e62f95d625836328131cc5ca851182bcae4 (patch) | |
tree | 5309ef2284a82d61ece838d1dd1c97c09df152b8 /dependencies/pkg/mod/go.uber.org | |
parent | Adding upstream version 1.1.1. (diff) | |
download | icingadb-upstream.tar.xz icingadb-upstream.zip |
Adding upstream version 1.2.0.upstream/1.2.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dependencies/pkg/mod/go.uber.org')
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.25.0/Makefile | 82 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array_go118.go | 156 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array_go118_test.go | 240 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.25.0/example_go118_test.go | 66 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.codecov.yml (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.codecov.yml) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/ISSUE_TEMPLATE/bug_report.md (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/ISSUE_TEMPLATE/bug_report.md) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/ISSUE_TEMPLATE/config.yml (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/ISSUE_TEMPLATE/config.yml) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/ISSUE_TEMPLATE/feature_request.md (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/ISSUE_TEMPLATE/feature_request.md) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/dependabot.yml (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/dependabot.yml) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/workflows/fossa.yaml (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/workflows/fossa.yaml) | 2 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/workflows/go.yml (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/workflows/go.yml) | 39 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.gitignore (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.gitignore) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.golangci.yml | 77 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.readme.tmpl (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.readme.tmpl) | 10 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/CHANGELOG.md (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/CHANGELOG.md) | 273 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/CODE_OF_CONDUCT.md (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/CODE_OF_CONDUCT.md) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/CONTRIBUTING.md (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/CONTRIBUTING.md) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/FAQ.md (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/FAQ.md) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/LICENSE (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/LICENSE.txt) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/Makefile | 76 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/README.md (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/README.md) | 66 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/array.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array.go) | 127 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/array_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array_test.go) | 209 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/buffer/buffer.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/buffer/buffer.go) | 5 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/buffer/buffer_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/buffer/buffer_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/buffer/pool.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/buffer/pool.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/buffer/pool_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/buffer/pool_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/checklicense.sh (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/checklicense.sh) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/clock_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/clock_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/common_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/common_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/config.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/config.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/config_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/config_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/doc.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/doc.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/encoder.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/encoder.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/encoder_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/encoder_test.go) | 4 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/error.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/error.go) | 5 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/error_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/error_test.go) | 36 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/example_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/example_test.go) | 53 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/field.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/field.go) | 27 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/field_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/field_test.go) | 32 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/flag.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/flag.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/flag_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/flag_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/glide.yaml (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/glide.yaml) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/global.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/global.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/global_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/global_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/go.mod (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/go.mod) | 3 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/go.sum (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/go.sum) | 8 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/http_handler.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/http_handler.go) | 19 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/http_handler_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/http_handler_test.go) | 29 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/increase_level_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/increase_level_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/bufferpool/bufferpool.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/bufferpool/bufferpool.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/color/color.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/color/color.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/color/color_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/color/color_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/exit/exit.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/exit/exit.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/exit/exit_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/exit/exit_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/level_enabler.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/level_enabler.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/pool/pool.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/pool/pool.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/pool/pool_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/pool/pool_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/readme/readme.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/readme/readme.go) | 25 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/stacktrace/stack.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/stacktrace.go) | 71 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/stacktrace/stack_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/stacktrace_test.go) | 28 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/clock.go | 153 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/clock_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/clock_test.go) | 25 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/doc.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/doc.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/timeout.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/timeout.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/writer.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/writer.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/leak_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/leak_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/level.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/level.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/level_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/level_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/logger.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/logger.go) | 81 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/logger_bench_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/logger_bench_test.go) | 43 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/logger_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/logger_test.go) | 382 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/options.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/options.go) | 15 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sink.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sink.go) | 5 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sink_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sink_test.go) | 5 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sink_windows_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sink_windows_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/stacktrace_ext_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/stacktrace_ext_test.go) | 4 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sugar.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sugar.go) | 39 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sugar_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sugar_test.go) | 119 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/time.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/time.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/time_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/time_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/writer.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/writer.go) | 12 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/writer_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/writer_test.go) | 4 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/buffered_write_syncer.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/buffered_write_syncer.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/buffered_write_syncer_bench_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/buffered_write_syncer_bench_test.go) | 8 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/buffered_write_syncer_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/buffered_write_syncer_test.go) | 3 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/clock.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/clock.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/clock_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/clock_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/console_encoder.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/console_encoder.go) | 2 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/console_encoder_bench_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/console_encoder_bench_test.go) | 1 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/console_encoder_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/console_encoder_test.go) | 62 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/core.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/core.go) | 6 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/core_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/core_test.go) | 3 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/doc.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/doc.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/encoder.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/encoder.go) | 15 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/encoder_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/encoder_test.go) | 10 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/entry.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/entry.go) | 4 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/entry_ext_test.go | 55 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/entry_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/entry_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/error.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/error.go) | 5 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/error_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/error_test.go) | 47 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/field.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/field.go) | 2 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/field_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/field_test.go) | 15 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/hook.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/hook.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/hook_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/hook_test.go) | 1 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/increase_level.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/increase_level.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/increase_level_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/increase_level_test.go) | 2 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/json_encoder.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/json_encoder.go) | 145 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/json_encoder_bench_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/json_encoder_bench_test.go) | 43 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/json_encoder_impl_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/json_encoder_impl_test.go) | 91 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/json_encoder_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/json_encoder_test.go) | 14 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/lazy_with.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/clock.go) | 46 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/lazy_with_test.go | 154 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/leak_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/leak_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/level.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/level.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/level_strings.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/level_strings.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/level_strings_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/level_strings_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/level_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/level_test.go) | 2 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/marshaler.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/marshaler.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/memory_encoder.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/memory_encoder.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/memory_encoder_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/memory_encoder_test.go) | 28 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/reflected_encoder.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/reflected_encoder.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/sampler.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/sampler.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/sampler_bench_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/sampler_bench_test.go) | 2 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/sampler_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/sampler_test.go) | 1 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/tee.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/tee.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/tee_logger_bench_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/tee_logger_bench_test.go) | 1 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/tee_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/tee_test.go) | 3 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/write_syncer.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/write_syncer.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/write_syncer_bench_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/write_syncer_bench_test.go) | 21 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/write_syncer_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/write_syncer_test.go) | 2 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapgrpc/zapgrpc.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapgrpc/zapgrpc.go) | 18 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapgrpc/zapgrpc_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapgrpc/zapgrpc_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapio/example_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapio/example_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapio/writer.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapio/writer.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapio/writer_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapio/writer_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/doc.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/doc.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/logger.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/logger.go) | 37 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/logger_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/logger_test.go) | 2 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/observer/logged_entry.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/observer/logged_entry.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/observer/logged_entry_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/observer/logged_entry_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/observer/observer.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/observer/observer.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/observer/observer_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/observer/observer_test.go) | 4 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/testingt.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/testingt.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/testingt_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/testingt_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/timeout.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/timeout.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/timeout_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/timeout_test.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/writer.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/writer.go) | 0 | ||||
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/writer_test.go (renamed from dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/writer_test.go) | 0 |
149 files changed, 2500 insertions, 1010 deletions
diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/Makefile b/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/Makefile deleted file mode 100644 index 518c3fa..0000000 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -export GOBIN ?= $(shell pwd)/bin - -REVIVE = $(GOBIN)/revive -STATICCHECK = $(GOBIN)/staticcheck -GOVULNCHECK = $(GOBIN)/govulncheck -BENCH_FLAGS ?= -cpuprofile=cpu.pprof -memprofile=mem.pprof -benchmem - -# Directories containing independent Go modules. -# -# We track coverage only for the main module. -MODULE_DIRS = . ./exp ./benchmarks ./zapgrpc/internal/test - -# Many Go tools take file globs or directories as arguments instead of packages. -GO_FILES := $(shell \ - find . '(' -path '*/.*' -o -path './vendor' ')' -prune \ - -o -name '*.go' -print | cut -b3-) - -.PHONY: all -all: lint test - -.PHONY: lint -lint: $(REVIVE) $(STATICCHECK) - @rm -rf lint.log - @echo "Checking formatting..." - @gofmt -d -s $(GO_FILES) 2>&1 | tee lint.log - @echo "Checking vet..." - @$(foreach dir,$(MODULE_DIRS),(cd $(dir) && go vet ./... 2>&1) &&) true | tee -a lint.log - @echo "Checking lint..." - @$(foreach dir,$(MODULE_DIRS),(cd $(dir) && \ - $(REVIVE) -set_exit_status ./... 2>&1) &&) true | tee -a lint.log - @echo "Checking staticcheck..." - @$(foreach dir,$(MODULE_DIRS),(cd $(dir) && $(STATICCHECK) ./... 2>&1) &&) true | tee -a lint.log - @echo "Checking for unresolved FIXMEs..." - @git grep -i fixme | grep -v -e Makefile | tee -a lint.log - @echo "Checking for license headers..." - @./checklicense.sh | tee -a lint.log - @[ ! -s lint.log ] - @echo "Checking 'go mod tidy'..." - @make tidy - @if ! git diff --quiet; then \ - echo "'go mod tidy' resulted in changes or working tree is dirty:"; \ - git --no-pager diff; \ - fi - -$(REVIVE): - cd tools && go install github.com/mgechev/revive - -$(GOVULNCHECK): - cd tools && go install golang.org/x/vuln/cmd/govulncheck - -$(STATICCHECK): - cd tools && go install honnef.co/go/tools/cmd/staticcheck - -.PHONY: test -test: - @$(foreach dir,$(MODULE_DIRS),(cd $(dir) && go test -race ./...) &&) true - -.PHONY: cover -cover: - go test -race -coverprofile=cover.out -coverpkg=./... ./... - go tool cover -html=cover.out -o cover.html - -.PHONY: bench -BENCH ?= . -bench: - @$(foreach dir,$(MODULE_DIRS), ( \ - cd $(dir) && \ - go list ./... | xargs -n1 go test -bench=$(BENCH) -run="^$$" $(BENCH_FLAGS) \ - ) &&) true - -.PHONY: updatereadme -updatereadme: - rm -f README.md - cat .readme.tmpl | go run internal/readme/readme.go > README.md - -.PHONY: tidy -tidy: - @$(foreach dir,$(MODULE_DIRS),(cd $(dir) && go mod tidy) &&) true - -.PHONY: vulncheck -vulncheck: $(GOVULNCHECK) - $(GOVULNCHECK) ./...
\ No newline at end of file diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array_go118.go b/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array_go118.go deleted file mode 100644 index d0d2c49..0000000 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array_go118.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) 2022 Uber Technologies, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -//go:build go1.18 -// +build go1.18 - -package zap - -import ( - "fmt" - - "go.uber.org/zap/zapcore" -) - -// Objects constructs a field with the given key, holding a list of the -// provided objects that can be marshaled by Zap. -// -// Note that these objects must implement zapcore.ObjectMarshaler directly. -// That is, if you're trying to marshal a []Request, the MarshalLogObject -// method must be declared on the Request type, not its pointer (*Request). -// If it's on the pointer, use ObjectValues. -// -// Given an object that implements MarshalLogObject on the value receiver, you -// can log a slice of those objects with Objects like so: -// -// type Author struct{ ... } -// func (a Author) MarshalLogObject(enc zapcore.ObjectEncoder) error -// -// var authors []Author = ... -// logger.Info("loading article", zap.Objects("authors", authors)) -// -// Similarly, given a type that implements MarshalLogObject on its pointer -// receiver, you can log a slice of pointers to that object with Objects like -// so: -// -// type Request struct{ ... } -// func (r *Request) MarshalLogObject(enc zapcore.ObjectEncoder) error -// -// var requests []*Request = ... -// logger.Info("sending requests", zap.Objects("requests", requests)) -// -// If instead, you have a slice of values of such an object, use the -// ObjectValues constructor. -// -// var requests []Request = ... -// logger.Info("sending requests", zap.ObjectValues("requests", requests)) -func Objects[T zapcore.ObjectMarshaler](key string, values []T) Field { - return Array(key, objects[T](values)) -} - -type objects[T zapcore.ObjectMarshaler] []T - -func (os objects[T]) MarshalLogArray(arr zapcore.ArrayEncoder) error { - for _, o := range os { - if err := arr.AppendObject(o); err != nil { - return err - } - } - return nil -} - -// ObjectMarshalerPtr is a constraint that specifies that the given type -// implements zapcore.ObjectMarshaler on a pointer receiver. -type ObjectMarshalerPtr[T any] interface { - *T - zapcore.ObjectMarshaler -} - -// ObjectValues constructs a field with the given key, holding a list of the -// provided objects, where pointers to these objects can be marshaled by Zap. -// -// Note that pointers to these objects must implement zapcore.ObjectMarshaler. -// That is, if you're trying to marshal a []Request, the MarshalLogObject -// method must be declared on the *Request type, not the value (Request). -// If it's on the value, use Objects. -// -// Given an object that implements MarshalLogObject on the pointer receiver, -// you can log a slice of those objects with ObjectValues like so: -// -// type Request struct{ ... } -// func (r *Request) MarshalLogObject(enc zapcore.ObjectEncoder) error -// -// var requests []Request = ... -// logger.Info("sending requests", zap.ObjectValues("requests", requests)) -// -// If instead, you have a slice of pointers of such an object, use the Objects -// field constructor. -// -// var requests []*Request = ... -// logger.Info("sending requests", zap.Objects("requests", requests)) -func ObjectValues[T any, P ObjectMarshalerPtr[T]](key string, values []T) Field { - return Array(key, objectValues[T, P](values)) -} - -type objectValues[T any, P ObjectMarshalerPtr[T]] []T - -func (os objectValues[T, P]) MarshalLogArray(arr zapcore.ArrayEncoder) error { - for i := range os { - // It is necessary for us to explicitly reference the "P" type. - // We cannot simply pass "&os[i]" to AppendObject because its type - // is "*T", which the type system does not consider as - // implementing ObjectMarshaler. - // Only the type "P" satisfies ObjectMarshaler, which we have - // to convert "*T" to explicitly. - var p P = &os[i] - if err := arr.AppendObject(p); err != nil { - return err - } - } - return nil -} - -// Stringers constructs a field with the given key, holding a list of the -// output provided by the value's String method -// -// Given an object that implements String on the value receiver, you -// can log a slice of those objects with Objects like so: -// -// type Request struct{ ... } -// func (a Request) String() string -// -// var requests []Request = ... -// logger.Info("sending requests", zap.Stringers("requests", requests)) -// -// Note that these objects must implement fmt.Stringer directly. -// That is, if you're trying to marshal a []Request, the String method -// must be declared on the Request type, not its pointer (*Request). -func Stringers[T fmt.Stringer](key string, values []T) Field { - return Array(key, stringers[T](values)) -} - -type stringers[T fmt.Stringer] []T - -func (os stringers[T]) MarshalLogArray(arr zapcore.ArrayEncoder) error { - for _, o := range os { - arr.AppendString(o.String()) - } - return nil -} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array_go118_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array_go118_test.go deleted file mode 100644 index e4c6274..0000000 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array_go118_test.go +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright (c) 2022 Uber Technologies, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -//go:build go1.18 -// +build go1.18 - -package zap - -import ( - "errors" - "fmt" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" -) - -func TestObjectsAndObjectValues(t *testing.T) { - t.Parallel() - - tests := []struct { - desc string - give Field - want []any - }{ - { - desc: "Objects/nil slice", - give: Objects[*emptyObject]("", nil), - want: []any{}, - }, - { - desc: "ObjectValues/nil slice", - give: ObjectValues[emptyObject]("", nil), - want: []any{}, - }, - { - desc: "ObjectValues/empty slice", - give: ObjectValues("", []emptyObject{}), - want: []any{}, - }, - { - desc: "ObjectValues/single item", - give: ObjectValues("", []emptyObject{ - {}, - }), - want: []any{ - map[string]any{}, - }, - }, - { - desc: "Objects/multiple different objects", - give: Objects("", []*fakeObject{ - {value: "foo"}, - {value: "bar"}, - {value: "baz"}, - }), - want: []any{ - map[string]any{"value": "foo"}, - map[string]any{"value": "bar"}, - map[string]any{"value": "baz"}, - }, - }, - { - desc: "ObjectValues/multiple different objects", - give: ObjectValues("", []fakeObject{ - {value: "foo"}, - {value: "bar"}, - {value: "baz"}, - }), - want: []any{ - map[string]any{"value": "foo"}, - map[string]any{"value": "bar"}, - map[string]any{"value": "baz"}, - }, - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.desc, func(t *testing.T) { - t.Parallel() - - tt.give.Key = "k" - - enc := zapcore.NewMapObjectEncoder() - tt.give.AddTo(enc) - assert.Equal(t, tt.want, enc.Fields["k"]) - }) - } -} - -type emptyObject struct{} - -func (*emptyObject) MarshalLogObject(zapcore.ObjectEncoder) error { - return nil -} - -type fakeObject struct { - value string - err error // marshaling error, if any -} - -func (o *fakeObject) MarshalLogObject(enc zapcore.ObjectEncoder) error { - enc.AddString("value", o.value) - return o.err -} - -func TestObjectsAndObjectValues_marshalError(t *testing.T) { - t.Parallel() - - tests := []struct { - desc string - give Field - want []any - wantErr string - }{ - { - desc: "Objects", - give: Objects("", []*fakeObject{ - {value: "foo"}, - {value: "bar", err: errors.New("great sadness")}, - {value: "baz"}, // does not get marshaled - }), - want: []any{ - map[string]any{"value": "foo"}, - map[string]any{"value": "bar"}, - }, - wantErr: "great sadness", - }, - { - desc: "ObjectValues", - give: ObjectValues("", []fakeObject{ - {value: "foo"}, - {value: "bar", err: errors.New("stuff failed")}, - {value: "baz"}, // does not get marshaled - }), - want: []any{ - map[string]any{"value": "foo"}, - map[string]any{"value": "bar"}, - }, - wantErr: "stuff failed", - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.desc, func(t *testing.T) { - t.Parallel() - - tt.give.Key = "k" - - enc := zapcore.NewMapObjectEncoder() - tt.give.AddTo(enc) - - require.Contains(t, enc.Fields, "k") - assert.Equal(t, tt.want, enc.Fields["k"]) - - // AddTo puts the error in a "%vError" field based on the name of the - // original field. - require.Contains(t, enc.Fields, "kError") - assert.Equal(t, tt.wantErr, enc.Fields["kError"]) - }) - } -} - -type stringerObject struct { - value string -} - -func (s stringerObject) String() string { - return s.value -} - -func TestStringers(t *testing.T) { - t.Parallel() - - tests := []struct { - desc string - give Field - want []any - }{ - { - desc: "Stringers", - give: Stringers("", []stringerObject{ - {value: "foo"}, - {value: "bar"}, - {value: "baz"}, - }), - want: []any{ - "foo", - "bar", - "baz", - }, - }, - { - desc: "Stringers with []fmt.Stringer", - give: Stringers("", []fmt.Stringer{ - stringerObject{value: "foo"}, - stringerObject{value: "bar"}, - stringerObject{value: "baz"}, - }), - want: []any{ - "foo", - "bar", - "baz", - }, - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.desc, func(t *testing.T) { - t.Parallel() - - tt.give.Key = "k" - - enc := zapcore.NewMapObjectEncoder() - tt.give.AddTo(enc) - assert.Equal(t, tt.want, enc.Fields["k"]) - }) - } -} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/example_go118_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/example_go118_test.go deleted file mode 100644 index dc25370..0000000 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/example_go118_test.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2022 Uber Technologies, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -//go:build go1.18 -// +build go1.18 - -package zap_test - -import "go.uber.org/zap" - -func ExampleObjects() { - logger := zap.NewExample() - defer logger.Sync() - - // Use the Objects field constructor when you have a list of objects, - // all of which implement zapcore.ObjectMarshaler. - logger.Debug("opening connections", - zap.Objects("addrs", []addr{ - {IP: "123.45.67.89", Port: 4040}, - {IP: "127.0.0.1", Port: 4041}, - {IP: "192.168.0.1", Port: 4042}, - })) - // Output: - // {"level":"debug","msg":"opening connections","addrs":[{"ip":"123.45.67.89","port":4040},{"ip":"127.0.0.1","port":4041},{"ip":"192.168.0.1","port":4042}]} -} - -func ExampleObjectValues() { - logger := zap.NewExample() - defer logger.Sync() - - // Use the ObjectValues field constructor when you have a list of - // objects that do not implement zapcore.ObjectMarshaler directly, - // but on their pointer receivers. - logger.Debug("starting tunnels", - zap.ObjectValues("addrs", []request{ - { - URL: "/foo", - Listen: addr{"127.0.0.1", 8080}, - Remote: addr{"123.45.67.89", 4040}, - }, - { - URL: "/bar", - Listen: addr{"127.0.0.1", 8080}, - Remote: addr{"127.0.0.1", 31200}, - }, - })) - // Output: - // {"level":"debug","msg":"starting tunnels","addrs":[{"url":"/foo","ip":"127.0.0.1","port":8080,"remote":{"ip":"123.45.67.89","port":4040}},{"url":"/bar","ip":"127.0.0.1","port":8080,"remote":{"ip":"127.0.0.1","port":31200}}]} -} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.codecov.yml b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.codecov.yml index 8e5ca7d..8e5ca7d 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.codecov.yml +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.codecov.yml diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/ISSUE_TEMPLATE/bug_report.md b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/ISSUE_TEMPLATE/bug_report.md index 96fe902..96fe902 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/ISSUE_TEMPLATE/bug_report.md +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/ISSUE_TEMPLATE/bug_report.md diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/ISSUE_TEMPLATE/config.yml b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/ISSUE_TEMPLATE/config.yml index 917a641..917a641 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/ISSUE_TEMPLATE/config.yml +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/ISSUE_TEMPLATE/config.yml diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/ISSUE_TEMPLATE/feature_request.md b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/ISSUE_TEMPLATE/feature_request.md index 8a1ef5c..8a1ef5c 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/ISSUE_TEMPLATE/feature_request.md +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/ISSUE_TEMPLATE/feature_request.md diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/dependabot.yml b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/dependabot.yml index 33ac821..33ac821 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/dependabot.yml +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/dependabot.yml diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/workflows/fossa.yaml b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/workflows/fossa.yaml index 6c91435..3da3e0d 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/workflows/fossa.yaml +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/workflows/fossa.yaml @@ -11,7 +11,7 @@ jobs: if: github.repository_owner == 'uber-go' steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: FOSSA analysis uses: fossas/fossa-action@v1 diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/workflows/go.yml b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/workflows/go.yml index c4fb393..2fa9a69 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.github/workflows/go.yml +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.github/workflows/go.yml @@ -2,7 +2,7 @@ name: Go on: push: - branches: ['*'] + branches: [master] tags: ['v*'] pull_request: branches: ['*'] @@ -16,20 +16,18 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go: ["1.19.x", "1.20.x"] + go: ["1.21.x", "1.22.x"] include: - - go: 1.20.x - latest: true + - go: 1.22.x steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: ${{ matrix.go }} - cache: true cache-dependency-path: '**/go.sum' - name: Download Dependencies @@ -39,16 +37,33 @@ jobs: (cd benchmarks && go mod download) (cd zapgrpc/internal/test && go mod download) - - name: Lint - if: matrix.latest - run: make lint - - name: Test run: make cover - name: Upload coverage to codecov.io uses: codecov/codecov-action@v3 + lint: + name: Lint + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + name: Check out repository + - uses: actions/setup-go@v4 + name: Set up Go + with: + go-version: 1.22.x + cache: false # managed by golangci-lint + + - uses: golangci/golangci-lint-action@v4 + name: Install golangci-lint + with: + version: latest + args: --version # make lint will run the linter + + - run: make lint + name: Lint + - name: vulncheck - if: matrix.latest run: make vulncheck diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.gitignore b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.gitignore index da9d9d0..da9d9d0 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.gitignore +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.gitignore diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.golangci.yml b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.golangci.yml new file mode 100644 index 0000000..2346df1 --- /dev/null +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.golangci.yml @@ -0,0 +1,77 @@ +output: + # Make output more digestible with quickfix in vim/emacs/etc. + sort-results: true + print-issued-lines: false + +linters: + # We'll track the golangci-lint default linters manually + # instead of letting them change without our control. + disable-all: true + enable: + # golangci-lint defaults: + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - unused + + # Our own extras: + - gofumpt + - nolintlint # lints nolint directives + - revive + +linters-settings: + govet: + # These govet checks are disabled by default, but they're useful. + enable: + - niliness + - reflectvaluecompare + - sortslice + - unusedwrite + + errcheck: + exclude-functions: + # These methods can not fail. + # They operate on an in-memory buffer. + - (*go.uber.org/zap/buffer.Buffer).Write + - (*go.uber.org/zap/buffer.Buffer).WriteByte + - (*go.uber.org/zap/buffer.Buffer).WriteString + + - (*go.uber.org/zap/zapio.Writer).Close + - (*go.uber.org/zap/zapio.Writer).Sync + - (*go.uber.org/zap/zapio.Writer).Write + # Write to zapio.Writer cannot fail, + # so io.WriteString on it cannot fail. + - io.WriteString(*go.uber.org/zap/zapio.Writer) + + # Writing a plain string to a fmt.State cannot fail. + - io.WriteString(fmt.State) + +issues: + # Print all issues reported by all linters. + max-issues-per-linter: 0 + max-same-issues: 0 + + # Don't ignore some of the issues that golangci-lint considers okay. + # This includes documenting all exported entities. + exclude-use-default: false + + exclude-rules: + # Don't warn on unused parameters. + # Parameter names are useful; replacing them with '_' is undesirable. + - linters: [revive] + text: 'unused-parameter: parameter \S+ seems to be unused, consider removing or renaming it as _' + + # staticcheck already has smarter checks for empty blocks. + # revive's empty-block linter has false positives. + # For example, as of writing this, the following is not allowed. + # for foo() { } + - linters: [revive] + text: 'empty-block: this block is empty, you can remove it' + + # Ignore logger.Sync() errcheck failures in example_test.go + # since those are intended to be uncomplicated examples. + - linters: [errcheck] + path: example_test.go + text: 'Error return value of `logger.Sync` is not checked' diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.readme.tmpl b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.readme.tmpl index 92aa65d..4fea302 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/.readme.tmpl +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/.readme.tmpl @@ -1,7 +1,15 @@ # :zap: zap [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] +<div align="center"> + Blazing fast, structured, leveled logging in Go. +![Zap logo](assets/logo.png) + +[![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] + +</div> + ## Installation `go get -u go.uber.org/zap` @@ -92,7 +100,7 @@ standard. <hr> -Released under the [MIT License](LICENSE.txt). +Released under the [MIT License](LICENSE). <sup id="footnote-versions">1</sup> In particular, keep in mind that we may be benchmarking against slightly older versions of other packages. Versions are diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/CHANGELOG.md b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/CHANGELOG.md index fe57bc0..6d6cd5f 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/CHANGELOG.md +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/CHANGELOG.md @@ -1,7 +1,34 @@ # Changelog All notable changes to this project will be documented in this file. -This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 1.27.0 (20 Feb 2024) +Enhancements: +* [#1378][]: Add `WithLazy` method for `SugaredLogger`. +* [#1399][]: zaptest: Add `NewTestingWriter` for customizing TestingWriter with more flexibility than `NewLogger`. +* [#1406][]: Add `Log`, `Logw`, `Logln` methods for `SugaredLogger`. +* [#1416][]: Add `WithPanicHook` option for testing panic logs. + +Thanks to @defval, @dimmo, @arxeiss, and @MKrupauskas for their contributions to this release. + +[#1378]: https://github.com/uber-go/zap/pull/1378 +[#1399]: https://github.com/uber-go/zap/pull/1399 +[#1406]: https://github.com/uber-go/zap/pull/1406 +[#1416]: https://github.com/uber-go/zap/pull/1416 + +## 1.26.0 (14 Sep 2023) +Enhancements: +* [#1297][]: Add Dict as a Field. +* [#1319][]: Add `WithLazy` method to `Logger` which lazily evaluates the structured +context. +* [#1350][]: String encoding is much (~50%) faster now. + +Thanks to @hhk7734, @jquirke, and @cdvr1993 for their contributions to this release. + +[#1297]: https://github.com/uber-go/zap/pull/1297 +[#1319]: https://github.com/uber-go/zap/pull/1319 +[#1350]: https://github.com/uber-go/zap/pull/1350 ## 1.25.0 (1 Aug 2023) @@ -14,7 +41,7 @@ Enhancements: * [#1273][]: Add `Name` to `Logger` which returns the Logger's name if one is set. * [#1281][]: Add `zap/exp/expfield` package which contains helper methods `Str` and `Strs` for constructing String-like zap.Fields. -* [#1310][]: Reduce stack size on `Any`. +* [#1310][]: Reduce stack size on `Any`. Thanks to @knight42, @dzakaammar, @bcspragu, and @rexywork for their contributions to this release. @@ -48,7 +75,6 @@ Enhancements: [#1147]: https://github.com/uber-go/zap/pull/1147 [#1155]: https://github.com/uber-go/zap/pull/1155 - ## 1.22.0 (8 Aug 2022) Enhancements: @@ -197,6 +223,16 @@ Enhancements: Thanks to @ash2k, @FMLS, @jimmystewpot, @Oncilla, @tsoslow, @tylitianrui, @withshubh, and @wziww for their contributions to this release. +[#865]: https://github.com/uber-go/zap/pull/865 +[#867]: https://github.com/uber-go/zap/pull/867 +[#881]: https://github.com/uber-go/zap/pull/881 +[#903]: https://github.com/uber-go/zap/pull/903 +[#912]: https://github.com/uber-go/zap/pull/912 +[#913]: https://github.com/uber-go/zap/pull/913 +[#928]: https://github.com/uber-go/zap/pull/928 +[#931]: https://github.com/uber-go/zap/pull/931 +[#936]: https://github.com/uber-go/zap/pull/936 + ## 1.16.0 (1 Sep 2020) Bugfixes: @@ -218,6 +254,17 @@ Enhancements: Thanks to @SteelPhase, @tmshn, @lixingwang, @wyxloading, @moul, @segevfiner, @andy-retailnext and @jcorbin for their contributions to this release. +[#629]: https://github.com/uber-go/zap/pull/629 +[#697]: https://github.com/uber-go/zap/pull/697 +[#828]: https://github.com/uber-go/zap/pull/828 +[#835]: https://github.com/uber-go/zap/pull/835 +[#843]: https://github.com/uber-go/zap/pull/843 +[#844]: https://github.com/uber-go/zap/pull/844 +[#852]: https://github.com/uber-go/zap/pull/852 +[#854]: https://github.com/uber-go/zap/pull/854 +[#861]: https://github.com/uber-go/zap/pull/861 +[#862]: https://github.com/uber-go/zap/pull/862 + ## 1.15.0 (23 Apr 2020) Bugfixes: @@ -234,6 +281,11 @@ Enhancements: Thanks to @danielbprice for their contributions to this release. +[#804]: https://github.com/uber-go/zap/pull/804 +[#812]: https://github.com/uber-go/zap/pull/812 +[#806]: https://github.com/uber-go/zap/pull/806 +[#813]: https://github.com/uber-go/zap/pull/813 + ## 1.14.1 (14 Mar 2020) Bugfixes: @@ -246,6 +298,10 @@ Bugfixes: Thanks to @YashishDua for their contributions to this release. +[#791]: https://github.com/uber-go/zap/pull/791 +[#795]: https://github.com/uber-go/zap/pull/795 +[#799]: https://github.com/uber-go/zap/pull/799 + ## 1.14.0 (20 Feb 2020) Enhancements: @@ -256,6 +312,11 @@ Enhancements: Thanks to @caibirdme for their contributions to this release. +[#771]: https://github.com/uber-go/zap/pull/771 +[#773]: https://github.com/uber-go/zap/pull/773 +[#775]: https://github.com/uber-go/zap/pull/775 +[#786]: https://github.com/uber-go/zap/pull/786 + ## 1.13.0 (13 Nov 2019) Enhancements: @@ -264,11 +325,15 @@ Enhancements: Thanks to @jbizzle for their contributions to this release. +[#758]: https://github.com/uber-go/zap/pull/758 + ## 1.12.0 (29 Oct 2019) Enhancements: * [#751][]: Migrate to Go modules. +[#751]: https://github.com/uber-go/zap/pull/751 + ## 1.11.0 (21 Oct 2019) Enhancements: @@ -277,6 +342,9 @@ Enhancements: Thanks to @juicemia, @uhthomas for their contributions to this release. +[#725]: https://github.com/uber-go/zap/pull/725 +[#736]: https://github.com/uber-go/zap/pull/736 + ## 1.10.0 (29 Apr 2019) Bugfixes: @@ -294,13 +362,21 @@ Enhancements: Thanks to @iaroslav-ciupin, @lelenanam, @joa, @NWilson for their contributions to this release. -## v1.9.1 (06 Aug 2018) +[#657]: https://github.com/uber-go/zap/pull/657 +[#706]: https://github.com/uber-go/zap/pull/706 +[#610]: https://github.com/uber-go/zap/pull/610 +[#675]: https://github.com/uber-go/zap/pull/675 +[#704]: https://github.com/uber-go/zap/pull/704 + +## 1.9.1 (06 Aug 2018) Bugfixes: * [#614][]: MapObjectEncoder should not ignore empty slices. -## v1.9.0 (19 Jul 2018) +[#614]: https://github.com/uber-go/zap/pull/614 + +## 1.9.0 (19 Jul 2018) Enhancements: * [#602][]: Reduce number of allocations when logging with reflection. @@ -309,7 +385,11 @@ Enhancements: Thanks to @nfarah86, @AlekSi, @JeanMertz, @philippgille, @etsangsplk, and @dimroc for their contributions to this release. -## v1.8.0 (13 Apr 2018) +[#602]: https://github.com/uber-go/zap/pull/602 +[#572]: https://github.com/uber-go/zap/pull/572 +[#606]: https://github.com/uber-go/zap/pull/606 + +## 1.8.0 (13 Apr 2018) Enhancements: * [#508][]: Make log level configurable when redirecting the standard @@ -322,19 +402,28 @@ Bugfixes: Thanks to @DiSiqueira and @djui for their contributions to this release. -## v1.7.1 (25 Sep 2017) +[#508]: https://github.com/uber-go/zap/pull/508 +[#518]: https://github.com/uber-go/zap/pull/518 +[#577]: https://github.com/uber-go/zap/pull/577 +[#574]: https://github.com/uber-go/zap/pull/574 + +## 1.7.1 (25 Sep 2017) Bugfixes: * [#504][]: Store strings when using AddByteString with the map encoder. -## v1.7.0 (21 Sep 2017) +[#504]: https://github.com/uber-go/zap/pull/504 + +## 1.7.0 (21 Sep 2017) Enhancements: * [#487][]: Add `NewStdLogAt`, which extends `NewStdLog` by allowing the user to specify the level of the logged messages. -## v1.6.0 (30 Aug 2017) +[#487]: https://github.com/uber-go/zap/pull/487 + +## 1.6.0 (30 Aug 2017) Enhancements: @@ -342,7 +431,10 @@ Enhancements: * [#490][]: Add a `ContextMap` method to observer logs for simpler field validation in tests. -## v1.5.0 (22 Jul 2017) +[#490]: https://github.com/uber-go/zap/pull/490 +[#491]: https://github.com/uber-go/zap/pull/491 + +## 1.5.0 (22 Jul 2017) Enhancements: @@ -355,7 +447,12 @@ Bugfixes: Thanks to @richard-tunein and @pavius for their contributions to this release. -## v1.4.1 (08 Jun 2017) +[#477]: https://github.com/uber-go/zap/pull/477 +[#465]: https://github.com/uber-go/zap/pull/465 +[#460]: https://github.com/uber-go/zap/pull/460 +[#470]: https://github.com/uber-go/zap/pull/470 + +## 1.4.1 (08 Jun 2017) This release fixes two bugs. @@ -364,7 +461,10 @@ Bugfixes: * [#435][]: Support a variety of case conventions when unmarshaling levels. * [#444][]: Fix a panic in the observer. -## v1.4.0 (12 May 2017) +[#435]: https://github.com/uber-go/zap/pull/435 +[#444]: https://github.com/uber-go/zap/pull/444 + +## 1.4.0 (12 May 2017) This release adds a few small features and is fully backward-compatible. @@ -376,7 +476,11 @@ Enhancements: * [#431][]: Make `zap.AtomicLevel` implement `fmt.Stringer`, which makes a variety of operations a bit simpler. -## v1.3.0 (25 Apr 2017) +[#424]: https://github.com/uber-go/zap/pull/424 +[#425]: https://github.com/uber-go/zap/pull/425 +[#431]: https://github.com/uber-go/zap/pull/431 + +## 1.3.0 (25 Apr 2017) This release adds an enhancement to zap's testing helpers as well as the ability to marshal an AtomicLevel. It is fully backward-compatible. @@ -387,7 +491,10 @@ Enhancements: particularly useful when testing the `SugaredLogger`. * [#416][]: Make `AtomicLevel` implement `encoding.TextMarshaler`. -## v1.2.0 (13 Apr 2017) +[#415]: https://github.com/uber-go/zap/pull/415 +[#416]: https://github.com/uber-go/zap/pull/416 + +## 1.2.0 (13 Apr 2017) This release adds a gRPC compatibility wrapper. It is fully backward-compatible. @@ -396,7 +503,9 @@ Enhancements: * [#402][]: Add a `zapgrpc` package that wraps zap's Logger and implements `grpclog.Logger`. -## v1.1.0 (31 Mar 2017) +[#402]: https://github.com/uber-go/zap/pull/402 + +## 1.1.0 (31 Mar 2017) This release fixes two bugs and adds some enhancements to zap's testing helpers. It is fully backward-compatible. @@ -413,7 +522,11 @@ Enhancements: Thanks to @moitias for contributing to this release. -## v1.0.0 (14 Mar 2017) +[#385]: https://github.com/uber-go/zap/pull/385 +[#396]: https://github.com/uber-go/zap/pull/396 +[#386]: https://github.com/uber-go/zap/pull/386 + +## 1.0.0 (14 Mar 2017) This is zap's first stable release. All exported APIs are now final, and no further breaking changes will be made in the 1.x release series. Anyone using a @@ -458,7 +571,21 @@ Enhancements: Thanks to @suyash, @htrendev, @flisky, @Ulexus, and @skipor for their contributions to this release. -## v1.0.0-rc.3 (7 Mar 2017) +[#366]: https://github.com/uber-go/zap/pull/366 +[#364]: https://github.com/uber-go/zap/pull/364 +[#371]: https://github.com/uber-go/zap/pull/371 +[#362]: https://github.com/uber-go/zap/pull/362 +[#369]: https://github.com/uber-go/zap/pull/369 +[#347]: https://github.com/uber-go/zap/pull/347 +[#373]: https://github.com/uber-go/zap/pull/373 +[#348]: https://github.com/uber-go/zap/pull/348 +[#327]: https://github.com/uber-go/zap/pull/327 +[#376]: https://github.com/uber-go/zap/pull/376 +[#346]: https://github.com/uber-go/zap/pull/346 +[#365]: https://github.com/uber-go/zap/pull/365 +[#372]: https://github.com/uber-go/zap/pull/372 + +## 1.0.0-rc.3 (7 Mar 2017) This is the third release candidate for zap's stable release. There are no breaking changes. @@ -479,7 +606,12 @@ Enhancements: Thanks to @ansel1 and @suyash for their contributions to this release. -## v1.0.0-rc.2 (21 Feb 2017) +[#339]: https://github.com/uber-go/zap/pull/339 +[#307]: https://github.com/uber-go/zap/pull/307 +[#353]: https://github.com/uber-go/zap/pull/353 +[#311]: https://github.com/uber-go/zap/pull/311 + +## 1.0.0-rc.2 (21 Feb 2017) This is the second release candidate for zap's stable release. It includes two breaking changes. @@ -516,7 +648,16 @@ Enhancements: Thanks to @skipor and @chapsuk for their contributions to this release. -## v1.0.0-rc.1 (14 Feb 2017) +[#316]: https://github.com/uber-go/zap/pull/316 +[#309]: https://github.com/uber-go/zap/pull/309 +[#317]: https://github.com/uber-go/zap/pull/317 +[#321]: https://github.com/uber-go/zap/pull/321 +[#325]: https://github.com/uber-go/zap/pull/325 +[#333]: https://github.com/uber-go/zap/pull/333 +[#326]: https://github.com/uber-go/zap/pull/326 +[#300]: https://github.com/uber-go/zap/pull/300 + +## 1.0.0-rc.1 (14 Feb 2017) This is the first release candidate for zap's stable release. There are multiple breaking changes and improvements from the pre-release version. Most notably: @@ -536,7 +677,7 @@ breaking changes and improvements from the pre-release version. Most notably: * Sampling is more accurate, and doesn't depend on the standard library's shared timer heap. -## v0.1.0-beta.1 (6 Feb 2017) +## 0.1.0-beta.1 (6 Feb 2017) This is a minor version, tagged to allow users to pin to the pre-1.0 APIs and upgrade at their leisure. Since this is the first tagged release, there are no @@ -544,95 +685,3 @@ backward compatibility concerns and all functionality is new. Early zap adopters should pin to the 0.1.x minor version until they're ready to upgrade to the upcoming stable release. - -[#316]: https://github.com/uber-go/zap/pull/316 -[#309]: https://github.com/uber-go/zap/pull/309 -[#317]: https://github.com/uber-go/zap/pull/317 -[#321]: https://github.com/uber-go/zap/pull/321 -[#325]: https://github.com/uber-go/zap/pull/325 -[#333]: https://github.com/uber-go/zap/pull/333 -[#326]: https://github.com/uber-go/zap/pull/326 -[#300]: https://github.com/uber-go/zap/pull/300 -[#339]: https://github.com/uber-go/zap/pull/339 -[#307]: https://github.com/uber-go/zap/pull/307 -[#353]: https://github.com/uber-go/zap/pull/353 -[#311]: https://github.com/uber-go/zap/pull/311 -[#366]: https://github.com/uber-go/zap/pull/366 -[#364]: https://github.com/uber-go/zap/pull/364 -[#371]: https://github.com/uber-go/zap/pull/371 -[#362]: https://github.com/uber-go/zap/pull/362 -[#369]: https://github.com/uber-go/zap/pull/369 -[#347]: https://github.com/uber-go/zap/pull/347 -[#373]: https://github.com/uber-go/zap/pull/373 -[#348]: https://github.com/uber-go/zap/pull/348 -[#327]: https://github.com/uber-go/zap/pull/327 -[#376]: https://github.com/uber-go/zap/pull/376 -[#346]: https://github.com/uber-go/zap/pull/346 -[#365]: https://github.com/uber-go/zap/pull/365 -[#372]: https://github.com/uber-go/zap/pull/372 -[#385]: https://github.com/uber-go/zap/pull/385 -[#396]: https://github.com/uber-go/zap/pull/396 -[#386]: https://github.com/uber-go/zap/pull/386 -[#402]: https://github.com/uber-go/zap/pull/402 -[#415]: https://github.com/uber-go/zap/pull/415 -[#416]: https://github.com/uber-go/zap/pull/416 -[#424]: https://github.com/uber-go/zap/pull/424 -[#425]: https://github.com/uber-go/zap/pull/425 -[#431]: https://github.com/uber-go/zap/pull/431 -[#435]: https://github.com/uber-go/zap/pull/435 -[#444]: https://github.com/uber-go/zap/pull/444 -[#477]: https://github.com/uber-go/zap/pull/477 -[#465]: https://github.com/uber-go/zap/pull/465 -[#460]: https://github.com/uber-go/zap/pull/460 -[#470]: https://github.com/uber-go/zap/pull/470 -[#487]: https://github.com/uber-go/zap/pull/487 -[#490]: https://github.com/uber-go/zap/pull/490 -[#491]: https://github.com/uber-go/zap/pull/491 -[#504]: https://github.com/uber-go/zap/pull/504 -[#508]: https://github.com/uber-go/zap/pull/508 -[#518]: https://github.com/uber-go/zap/pull/518 -[#577]: https://github.com/uber-go/zap/pull/577 -[#574]: https://github.com/uber-go/zap/pull/574 -[#602]: https://github.com/uber-go/zap/pull/602 -[#572]: https://github.com/uber-go/zap/pull/572 -[#606]: https://github.com/uber-go/zap/pull/606 -[#614]: https://github.com/uber-go/zap/pull/614 -[#657]: https://github.com/uber-go/zap/pull/657 -[#706]: https://github.com/uber-go/zap/pull/706 -[#610]: https://github.com/uber-go/zap/pull/610 -[#675]: https://github.com/uber-go/zap/pull/675 -[#704]: https://github.com/uber-go/zap/pull/704 -[#725]: https://github.com/uber-go/zap/pull/725 -[#736]: https://github.com/uber-go/zap/pull/736 -[#751]: https://github.com/uber-go/zap/pull/751 -[#758]: https://github.com/uber-go/zap/pull/758 -[#771]: https://github.com/uber-go/zap/pull/771 -[#773]: https://github.com/uber-go/zap/pull/773 -[#775]: https://github.com/uber-go/zap/pull/775 -[#786]: https://github.com/uber-go/zap/pull/786 -[#791]: https://github.com/uber-go/zap/pull/791 -[#795]: https://github.com/uber-go/zap/pull/795 -[#799]: https://github.com/uber-go/zap/pull/799 -[#804]: https://github.com/uber-go/zap/pull/804 -[#812]: https://github.com/uber-go/zap/pull/812 -[#806]: https://github.com/uber-go/zap/pull/806 -[#813]: https://github.com/uber-go/zap/pull/813 -[#629]: https://github.com/uber-go/zap/pull/629 -[#697]: https://github.com/uber-go/zap/pull/697 -[#828]: https://github.com/uber-go/zap/pull/828 -[#835]: https://github.com/uber-go/zap/pull/835 -[#843]: https://github.com/uber-go/zap/pull/843 -[#844]: https://github.com/uber-go/zap/pull/844 -[#852]: https://github.com/uber-go/zap/pull/852 -[#854]: https://github.com/uber-go/zap/pull/854 -[#861]: https://github.com/uber-go/zap/pull/861 -[#862]: https://github.com/uber-go/zap/pull/862 -[#865]: https://github.com/uber-go/zap/pull/865 -[#867]: https://github.com/uber-go/zap/pull/867 -[#881]: https://github.com/uber-go/zap/pull/881 -[#903]: https://github.com/uber-go/zap/pull/903 -[#912]: https://github.com/uber-go/zap/pull/912 -[#913]: https://github.com/uber-go/zap/pull/913 -[#928]: https://github.com/uber-go/zap/pull/928 -[#931]: https://github.com/uber-go/zap/pull/931 -[#936]: https://github.com/uber-go/zap/pull/936 diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/CODE_OF_CONDUCT.md b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/CODE_OF_CONDUCT.md index e327d9a..e327d9a 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/CODE_OF_CONDUCT.md +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/CODE_OF_CONDUCT.md diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/CONTRIBUTING.md b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/CONTRIBUTING.md index ea02f3c..ea02f3c 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/CONTRIBUTING.md +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/CONTRIBUTING.md diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/FAQ.md b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/FAQ.md index b183b20..b183b20 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/FAQ.md +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/FAQ.md diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/LICENSE.txt b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/LICENSE index 6652bed..6652bed 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/LICENSE.txt +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/LICENSE diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/Makefile b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/Makefile new file mode 100644 index 0000000..eb1cee5 --- /dev/null +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/Makefile @@ -0,0 +1,76 @@ +# Directory containing the Makefile. +PROJECT_ROOT = $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) + +export GOBIN ?= $(PROJECT_ROOT)/bin +export PATH := $(GOBIN):$(PATH) + +GOVULNCHECK = $(GOBIN)/govulncheck +BENCH_FLAGS ?= -cpuprofile=cpu.pprof -memprofile=mem.pprof -benchmem + +# Directories containing independent Go modules. +MODULE_DIRS = . ./exp ./benchmarks ./zapgrpc/internal/test + +# Directories that we want to track coverage for. +COVER_DIRS = . ./exp + +.PHONY: all +all: lint test + +.PHONY: lint +lint: golangci-lint tidy-lint license-lint + +.PHONY: golangci-lint +golangci-lint: + @$(foreach mod,$(MODULE_DIRS), \ + (cd $(mod) && \ + echo "[lint] golangci-lint: $(mod)" && \ + golangci-lint run --path-prefix $(mod)) &&) true + +.PHONY: tidy +tidy: + @$(foreach dir,$(MODULE_DIRS), \ + (cd $(dir) && go mod tidy) &&) true + +.PHONY: tidy-lint +tidy-lint: + @$(foreach mod,$(MODULE_DIRS), \ + (cd $(mod) && \ + echo "[lint] tidy: $(mod)" && \ + go mod tidy && \ + git diff --exit-code -- go.mod go.sum) &&) true + + +.PHONY: license-lint +license-lint: + ./checklicense.sh + +$(GOVULNCHECK): + cd tools && go install golang.org/x/vuln/cmd/govulncheck + +.PHONY: test +test: + @$(foreach dir,$(MODULE_DIRS),(cd $(dir) && go test -race ./...) &&) true + +.PHONY: cover +cover: + @$(foreach dir,$(COVER_DIRS), ( \ + cd $(dir) && \ + go test -race -coverprofile=cover.out -coverpkg=./... ./... \ + && go tool cover -html=cover.out -o cover.html) &&) true + +.PHONY: bench +BENCH ?= . +bench: + @$(foreach dir,$(MODULE_DIRS), ( \ + cd $(dir) && \ + go list ./... | xargs -n1 go test -bench=$(BENCH) -run="^$$" $(BENCH_FLAGS) \ + ) &&) true + +.PHONY: updatereadme +updatereadme: + rm -f README.md + cat .readme.tmpl | go run internal/readme/readme.go > README.md + +.PHONY: vulncheck +vulncheck: $(GOVULNCHECK) + $(GOVULNCHECK) ./... diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/README.md b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/README.md index 9de0892..a17035c 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/README.md +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/README.md @@ -1,7 +1,16 @@ -# :zap: zap [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] +# :zap: zap + + +<div align="center"> Blazing fast, structured, leveled logging in Go. +![Zap logo](assets/logo.png) + +[![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] + +</div> + ## Installation `go get -u go.uber.org/zap` @@ -66,41 +75,44 @@ Log a message and 10 fields: | Package | Time | Time % to zap | Objects Allocated | | :------ | :--: | :-----------: | :---------------: | -| :zap: zap | 1744 ns/op | +0% | 5 allocs/op -| :zap: zap (sugared) | 2483 ns/op | +42% | 10 allocs/op -| zerolog | 918 ns/op | -47% | 1 allocs/op -| go-kit | 5590 ns/op | +221% | 57 allocs/op -| slog | 5640 ns/op | +223% | 40 allocs/op -| apex/log | 21184 ns/op | +1115% | 63 allocs/op -| logrus | 24338 ns/op | +1296% | 79 allocs/op -| log15 | 26054 ns/op | +1394% | 74 allocs/op +| :zap: zap | 656 ns/op | +0% | 5 allocs/op +| :zap: zap (sugared) | 935 ns/op | +43% | 10 allocs/op +| zerolog | 380 ns/op | -42% | 1 allocs/op +| go-kit | 2249 ns/op | +243% | 57 allocs/op +| slog (LogAttrs) | 2479 ns/op | +278% | 40 allocs/op +| slog | 2481 ns/op | +278% | 42 allocs/op +| apex/log | 9591 ns/op | +1362% | 63 allocs/op +| log15 | 11393 ns/op | +1637% | 75 allocs/op +| logrus | 11654 ns/op | +1677% | 79 allocs/op Log a message with a logger that already has 10 fields of context: | Package | Time | Time % to zap | Objects Allocated | | :------ | :--: | :-----------: | :---------------: | -| :zap: zap | 193 ns/op | +0% | 0 allocs/op -| :zap: zap (sugared) | 227 ns/op | +18% | 1 allocs/op -| zerolog | 81 ns/op | -58% | 0 allocs/op -| slog | 322 ns/op | +67% | 0 allocs/op -| go-kit | 5377 ns/op | +2686% | 56 allocs/op -| apex/log | 19518 ns/op | +10013% | 53 allocs/op -| log15 | 19812 ns/op | +10165% | 70 allocs/op -| logrus | 21997 ns/op | +11297% | 68 allocs/op +| :zap: zap | 67 ns/op | +0% | 0 allocs/op +| :zap: zap (sugared) | 84 ns/op | +25% | 1 allocs/op +| zerolog | 35 ns/op | -48% | 0 allocs/op +| slog | 193 ns/op | +188% | 0 allocs/op +| slog (LogAttrs) | 200 ns/op | +199% | 0 allocs/op +| go-kit | 2460 ns/op | +3572% | 56 allocs/op +| log15 | 9038 ns/op | +13390% | 70 allocs/op +| apex/log | 9068 ns/op | +13434% | 53 allocs/op +| logrus | 10521 ns/op | +15603% | 68 allocs/op Log a static string, without any context or `printf`-style templating: | Package | Time | Time % to zap | Objects Allocated | | :------ | :--: | :-----------: | :---------------: | -| :zap: zap | 165 ns/op | +0% | 0 allocs/op -| :zap: zap (sugared) | 212 ns/op | +28% | 1 allocs/op -| zerolog | 95 ns/op | -42% | 0 allocs/op -| slog | 296 ns/op | +79% | 0 allocs/op -| go-kit | 415 ns/op | +152% | 9 allocs/op -| standard library | 422 ns/op | +156% | 2 allocs/op -| apex/log | 1601 ns/op | +870% | 5 allocs/op -| logrus | 3017 ns/op | +1728% | 23 allocs/op -| log15 | 3469 ns/op | +2002% | 20 allocs/op +| :zap: zap | 63 ns/op | +0% | 0 allocs/op +| :zap: zap (sugared) | 81 ns/op | +29% | 1 allocs/op +| zerolog | 32 ns/op | -49% | 0 allocs/op +| standard library | 124 ns/op | +97% | 1 allocs/op +| slog | 196 ns/op | +211% | 0 allocs/op +| slog (LogAttrs) | 200 ns/op | +217% | 0 allocs/op +| go-kit | 213 ns/op | +238% | 9 allocs/op +| apex/log | 771 ns/op | +1124% | 5 allocs/op +| logrus | 1439 ns/op | +2184% | 23 allocs/op +| log15 | 2069 ns/op | +3184% | 20 allocs/op ## Development Status: Stable @@ -120,7 +132,7 @@ standard. <hr> -Released under the [MIT License](LICENSE.txt). +Released under the [MIT License](LICENSE). <sup id="footnote-versions">1</sup> In particular, keep in mind that we may be benchmarking against slightly older versions of other packages. Versions are diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/array.go index 5be3704..abfccb5 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/array.go @@ -21,6 +21,7 @@ package zap import ( + "fmt" "time" "go.uber.org/zap/zapcore" @@ -94,11 +95,137 @@ func Int8s(key string, nums []int8) Field { return Array(key, int8s(nums)) } +// Objects constructs a field with the given key, holding a list of the +// provided objects that can be marshaled by Zap. +// +// Note that these objects must implement zapcore.ObjectMarshaler directly. +// That is, if you're trying to marshal a []Request, the MarshalLogObject +// method must be declared on the Request type, not its pointer (*Request). +// If it's on the pointer, use ObjectValues. +// +// Given an object that implements MarshalLogObject on the value receiver, you +// can log a slice of those objects with Objects like so: +// +// type Author struct{ ... } +// func (a Author) MarshalLogObject(enc zapcore.ObjectEncoder) error +// +// var authors []Author = ... +// logger.Info("loading article", zap.Objects("authors", authors)) +// +// Similarly, given a type that implements MarshalLogObject on its pointer +// receiver, you can log a slice of pointers to that object with Objects like +// so: +// +// type Request struct{ ... } +// func (r *Request) MarshalLogObject(enc zapcore.ObjectEncoder) error +// +// var requests []*Request = ... +// logger.Info("sending requests", zap.Objects("requests", requests)) +// +// If instead, you have a slice of values of such an object, use the +// ObjectValues constructor. +// +// var requests []Request = ... +// logger.Info("sending requests", zap.ObjectValues("requests", requests)) +func Objects[T zapcore.ObjectMarshaler](key string, values []T) Field { + return Array(key, objects[T](values)) +} + +type objects[T zapcore.ObjectMarshaler] []T + +func (os objects[T]) MarshalLogArray(arr zapcore.ArrayEncoder) error { + for _, o := range os { + if err := arr.AppendObject(o); err != nil { + return err + } + } + return nil +} + +// ObjectMarshalerPtr is a constraint that specifies that the given type +// implements zapcore.ObjectMarshaler on a pointer receiver. +type ObjectMarshalerPtr[T any] interface { + *T + zapcore.ObjectMarshaler +} + +// ObjectValues constructs a field with the given key, holding a list of the +// provided objects, where pointers to these objects can be marshaled by Zap. +// +// Note that pointers to these objects must implement zapcore.ObjectMarshaler. +// That is, if you're trying to marshal a []Request, the MarshalLogObject +// method must be declared on the *Request type, not the value (Request). +// If it's on the value, use Objects. +// +// Given an object that implements MarshalLogObject on the pointer receiver, +// you can log a slice of those objects with ObjectValues like so: +// +// type Request struct{ ... } +// func (r *Request) MarshalLogObject(enc zapcore.ObjectEncoder) error +// +// var requests []Request = ... +// logger.Info("sending requests", zap.ObjectValues("requests", requests)) +// +// If instead, you have a slice of pointers of such an object, use the Objects +// field constructor. +// +// var requests []*Request = ... +// logger.Info("sending requests", zap.Objects("requests", requests)) +func ObjectValues[T any, P ObjectMarshalerPtr[T]](key string, values []T) Field { + return Array(key, objectValues[T, P](values)) +} + +type objectValues[T any, P ObjectMarshalerPtr[T]] []T + +func (os objectValues[T, P]) MarshalLogArray(arr zapcore.ArrayEncoder) error { + for i := range os { + // It is necessary for us to explicitly reference the "P" type. + // We cannot simply pass "&os[i]" to AppendObject because its type + // is "*T", which the type system does not consider as + // implementing ObjectMarshaler. + // Only the type "P" satisfies ObjectMarshaler, which we have + // to convert "*T" to explicitly. + var p P = &os[i] + if err := arr.AppendObject(p); err != nil { + return err + } + } + return nil +} + // Strings constructs a field that carries a slice of strings. func Strings(key string, ss []string) Field { return Array(key, stringArray(ss)) } +// Stringers constructs a field with the given key, holding a list of the +// output provided by the value's String method +// +// Given an object that implements String on the value receiver, you +// can log a slice of those objects with Objects like so: +// +// type Request struct{ ... } +// func (a Request) String() string +// +// var requests []Request = ... +// logger.Info("sending requests", zap.Stringers("requests", requests)) +// +// Note that these objects must implement fmt.Stringer directly. +// That is, if you're trying to marshal a []Request, the String method +// must be declared on the Request type, not its pointer (*Request). +func Stringers[T fmt.Stringer](key string, values []T) Field { + return Array(key, stringers[T](values)) +} + +type stringers[T fmt.Stringer] []T + +func (os stringers[T]) MarshalLogArray(arr zapcore.ArrayEncoder) error { + for _, o := range os { + arr.AppendString(o.String()) + } + return nil +} + // Times constructs a field that carries a slice of time.Times. func Times(key string, ts []time.Time) Field { return Array(key, times(ts)) diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/array_test.go index 961cb1c..97738c9 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/array_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/array_test.go @@ -21,12 +21,15 @@ package zap import ( + "errors" + "fmt" "testing" "time" "go.uber.org/zap/zapcore" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func BenchmarkBoolsArrayMarshaler(b *testing.B) { @@ -105,3 +108,209 @@ func TestArrayWrappers(t *testing.T) { assert.Equal(t, 1, len(enc.Fields), "%s: found extra keys in map: %v", tt.desc, enc.Fields) } } + +func TestObjectsAndObjectValues(t *testing.T) { + t.Parallel() + + tests := []struct { + desc string + give Field + want []any + }{ + { + desc: "Objects/nil slice", + give: Objects[*emptyObject]("", nil), + want: []any{}, + }, + { + desc: "ObjectValues/nil slice", + give: ObjectValues[emptyObject]("", nil), + want: []any{}, + }, + { + desc: "ObjectValues/empty slice", + give: ObjectValues("", []emptyObject{}), + want: []any{}, + }, + { + desc: "ObjectValues/single item", + give: ObjectValues("", []emptyObject{ + {}, + }), + want: []any{ + map[string]any{}, + }, + }, + { + desc: "Objects/multiple different objects", + give: Objects("", []*fakeObject{ + {value: "foo"}, + {value: "bar"}, + {value: "baz"}, + }), + want: []any{ + map[string]any{"value": "foo"}, + map[string]any{"value": "bar"}, + map[string]any{"value": "baz"}, + }, + }, + { + desc: "ObjectValues/multiple different objects", + give: ObjectValues("", []fakeObject{ + {value: "foo"}, + {value: "bar"}, + {value: "baz"}, + }), + want: []any{ + map[string]any{"value": "foo"}, + map[string]any{"value": "bar"}, + map[string]any{"value": "baz"}, + }, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.desc, func(t *testing.T) { + t.Parallel() + + tt.give.Key = "k" + + enc := zapcore.NewMapObjectEncoder() + tt.give.AddTo(enc) + assert.Equal(t, tt.want, enc.Fields["k"]) + }) + } +} + +type emptyObject struct{} + +func (*emptyObject) MarshalLogObject(zapcore.ObjectEncoder) error { + return nil +} + +type fakeObject struct { + value string + err error // marshaling error, if any +} + +func (o *fakeObject) MarshalLogObject(enc zapcore.ObjectEncoder) error { + enc.AddString("value", o.value) + return o.err +} + +func TestObjectsAndObjectValues_marshalError(t *testing.T) { + t.Parallel() + + tests := []struct { + desc string + give Field + want []any + wantErr string + }{ + { + desc: "Objects", + give: Objects("", []*fakeObject{ + {value: "foo"}, + {value: "bar", err: errors.New("great sadness")}, + {value: "baz"}, // does not get marshaled + }), + want: []any{ + map[string]any{"value": "foo"}, + map[string]any{"value": "bar"}, + }, + wantErr: "great sadness", + }, + { + desc: "ObjectValues", + give: ObjectValues("", []fakeObject{ + {value: "foo"}, + {value: "bar", err: errors.New("stuff failed")}, + {value: "baz"}, // does not get marshaled + }), + want: []any{ + map[string]any{"value": "foo"}, + map[string]any{"value": "bar"}, + }, + wantErr: "stuff failed", + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.desc, func(t *testing.T) { + t.Parallel() + + tt.give.Key = "k" + + enc := zapcore.NewMapObjectEncoder() + tt.give.AddTo(enc) + + require.Contains(t, enc.Fields, "k") + assert.Equal(t, tt.want, enc.Fields["k"]) + + // AddTo puts the error in a "%vError" field based on the name of the + // original field. + require.Contains(t, enc.Fields, "kError") + assert.Equal(t, tt.wantErr, enc.Fields["kError"]) + }) + } +} + +type stringerObject struct { + value string +} + +func (s stringerObject) String() string { + return s.value +} + +func TestStringers(t *testing.T) { + t.Parallel() + + tests := []struct { + desc string + give Field + want []any + }{ + { + desc: "Stringers", + give: Stringers("", []stringerObject{ + {value: "foo"}, + {value: "bar"}, + {value: "baz"}, + }), + want: []any{ + "foo", + "bar", + "baz", + }, + }, + { + desc: "Stringers with []fmt.Stringer", + give: Stringers("", []fmt.Stringer{ + stringerObject{value: "foo"}, + stringerObject{value: "bar"}, + stringerObject{value: "baz"}, + }), + want: []any{ + "foo", + "bar", + "baz", + }, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.desc, func(t *testing.T) { + t.Parallel() + + tt.give.Key = "k" + + enc := zapcore.NewMapObjectEncoder() + tt.give.AddTo(enc) + assert.Equal(t, tt.want, enc.Fields["k"]) + }) + } +} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/buffer/buffer.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/buffer/buffer.go index 9e929cd..0b8540c 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/buffer/buffer.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/buffer/buffer.go @@ -42,6 +42,11 @@ func (b *Buffer) AppendByte(v byte) { b.bs = append(b.bs, v) } +// AppendBytes writes the given slice of bytes to the Buffer. +func (b *Buffer) AppendBytes(v []byte) { + b.bs = append(b.bs, v...) +} + // AppendString writes a string to the Buffer. func (b *Buffer) AppendString(s string) { b.bs = append(b.bs, s...) diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/buffer/buffer_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/buffer/buffer_test.go index 71ffac1..71ffac1 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/buffer/buffer_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/buffer/buffer_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/buffer/pool.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/buffer/pool.go index 8463233..8463233 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/buffer/pool.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/buffer/pool.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/buffer/pool_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/buffer/pool_test.go index a219815..a219815 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/buffer/pool_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/buffer/pool_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/checklicense.sh b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/checklicense.sh index 345ac8b..345ac8b 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/checklicense.sh +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/checklicense.sh diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/clock_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/clock_test.go index 29825fc..29825fc 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/clock_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/clock_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/common_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/common_test.go index b0a4a2e..b0a4a2e 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/common_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/common_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/config.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/config.go index e76e4e6..e76e4e6 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/config.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/config.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/config_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/config_test.go index 4badd1b..4badd1b 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/config_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/config_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/doc.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/doc.go index 3c50d7b..3c50d7b 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/doc.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/doc.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/encoder.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/encoder.go index caa04ce..caa04ce 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/encoder.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/encoder.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/encoder_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/encoder_test.go index f6be665..b71eb65 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/encoder_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/encoder_test.go @@ -41,7 +41,7 @@ func TestRegisterEncoder(t *testing.T) { func TestDuplicateRegisterEncoder(t *testing.T) { testEncoders(func() { - RegisterEncoder("foo", newNilEncoder) + assert.NoError(t, RegisterEncoder("foo", newNilEncoder), "expected to be able to register the encoder foo") assert.Error(t, RegisterEncoder("foo", newNilEncoder), "expected an error when registering an encoder with the same name twice") }) } @@ -52,7 +52,7 @@ func TestRegisterEncoderNoName(t *testing.T) { func TestNewEncoder(t *testing.T) { testEncoders(func() { - RegisterEncoder("foo", newNilEncoder) + assert.NoError(t, RegisterEncoder("foo", newNilEncoder), "expected to be able to register the encoder foo") encoder, err := newEncoder("foo", zapcore.EncoderConfig{}) assert.NoError(t, err, "could not create an encoder for the registered name foo") assert.Nil(t, encoder, "the encoder from newNilEncoder is not nil") diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/error.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/error.go index 38cb768..45f7b83 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/error.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/error.go @@ -61,9 +61,12 @@ func (errs errArray) MarshalLogArray(arr zapcore.ArrayEncoder) error { // allocating, pool the wrapper type. elem := _errArrayElemPool.Get() elem.error = errs[i] - arr.AppendObject(elem) + err := arr.AppendObject(elem) elem.error = nil _errArrayElemPool.Put(elem) + if err != nil { + return err + } } return nil } diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/error_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/error_test.go index 64dab19..4bfa370 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/error_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/error_test.go @@ -95,3 +95,39 @@ func TestErrorsArraysHandleRichErrors(t *testing.T) { require.True(t, ok, "Expected serialized error to be a map, got %T.", serialized) assert.Equal(t, "egad", errMap["error"], "Unexpected standard error string.") } + +func TestErrArrayBrokenEncoder(t *testing.T) { + t.Parallel() + + failWith := errors.New("great sadness") + err := (brokenArrayObjectEncoder{ + Err: failWith, + ObjectEncoder: zapcore.NewMapObjectEncoder(), + }).AddArray("errors", errArray{ + errors.New("foo"), + errors.New("bar"), + }) + require.Error(t, err, "Expected error from broken encoder.") + assert.ErrorIs(t, err, failWith, "Unexpected error.") +} + +// brokenArrayObjectEncoder is an ObjectEncoder +// that builds a broken ArrayEncoder. +type brokenArrayObjectEncoder struct { + zapcore.ObjectEncoder + zapcore.ArrayEncoder + + Err error // error to return +} + +func (enc brokenArrayObjectEncoder) AddArray(key string, marshaler zapcore.ArrayMarshaler) error { + return enc.ObjectEncoder.AddArray(key, + zapcore.ArrayMarshalerFunc(func(ae zapcore.ArrayEncoder) error { + enc.ArrayEncoder = ae + return marshaler.MarshalLogArray(enc) + })) +} + +func (enc brokenArrayObjectEncoder) AppendObject(zapcore.ObjectMarshaler) error { + return enc.Err +} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/example_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/example_test.go index 327e3ef..af7df0e 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/example_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/example_test.go @@ -358,3 +358,56 @@ func ExampleWrapCore_wrap() { // {"level":"info","msg":"doubled"} // {"level":"info","msg":"doubled"} } + +func ExampleDict() { + logger := zap.NewExample() + defer logger.Sync() + + logger.Info("login event", + zap.Dict("event", + zap.Int("id", 123), + zap.String("name", "jane"), + zap.String("status", "pending"))) + // Output: + // {"level":"info","msg":"login event","event":{"id":123,"name":"jane","status":"pending"}} +} + +func ExampleObjects() { + logger := zap.NewExample() + defer logger.Sync() + + // Use the Objects field constructor when you have a list of objects, + // all of which implement zapcore.ObjectMarshaler. + logger.Debug("opening connections", + zap.Objects("addrs", []addr{ + {IP: "123.45.67.89", Port: 4040}, + {IP: "127.0.0.1", Port: 4041}, + {IP: "192.168.0.1", Port: 4042}, + })) + // Output: + // {"level":"debug","msg":"opening connections","addrs":[{"ip":"123.45.67.89","port":4040},{"ip":"127.0.0.1","port":4041},{"ip":"192.168.0.1","port":4042}]} +} + +func ExampleObjectValues() { + logger := zap.NewExample() + defer logger.Sync() + + // Use the ObjectValues field constructor when you have a list of + // objects that do not implement zapcore.ObjectMarshaler directly, + // but on their pointer receivers. + logger.Debug("starting tunnels", + zap.ObjectValues("addrs", []request{ + { + URL: "/foo", + Listen: addr{"127.0.0.1", 8080}, + Remote: addr{"123.45.67.89", 4040}, + }, + { + URL: "/bar", + Listen: addr{"127.0.0.1", 8080}, + Remote: addr{"127.0.0.1", 31200}, + }, + })) + // Output: + // {"level":"debug","msg":"starting tunnels","addrs":[{"url":"/foo","ip":"127.0.0.1","port":8080,"remote":{"ip":"123.45.67.89","port":4040}},{"url":"/bar","ip":"127.0.0.1","port":8080,"remote":{"ip":"127.0.0.1","port":31200}}]} +} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/field.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/field.go index 7f22c53..6743930 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/field.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/field.go @@ -25,6 +25,7 @@ import ( "math" "time" + "go.uber.org/zap/internal/stacktrace" "go.uber.org/zap/zapcore" ) @@ -374,7 +375,7 @@ func StackSkip(key string, skip int) Field { // from expanding the zapcore.Field union struct to include a byte slice. Since // taking a stacktrace is already so expensive (~10us), the extra allocation // is okay. - return String(key, takeStacktrace(skip+1)) // skip StackSkip + return String(key, stacktrace.Take(skip+1)) // skip StackSkip } // Duration constructs a field with the given key and value. The encoder @@ -410,6 +411,26 @@ func Inline(val zapcore.ObjectMarshaler) Field { } } +// Dict constructs a field containing the provided key-value pairs. +// It acts similar to [Object], but with the fields specified as arguments. +func Dict(key string, val ...Field) Field { + return dictField(key, val) +} + +// We need a function with the signature (string, T) for zap.Any. +func dictField(key string, val []Field) Field { + return Object(key, dictObject(val)) +} + +type dictObject []Field + +func (d dictObject) MarshalLogObject(enc zapcore.ObjectEncoder) error { + for _, f := range d { + f.AddTo(enc) + } + return nil +} + // We discovered an issue where zap.Any can cause a performance degradation // when used in new goroutines. // @@ -439,6 +460,8 @@ func Inline(val zapcore.ObjectMarshaler) Field { // - https://github.com/uber-go/zap/pull/1304 // - https://github.com/uber-go/zap/pull/1305 // - https://github.com/uber-go/zap/pull/1308 +// +// See https://github.com/golang/go/issues/62077 for upstream issue. type anyFieldC[T any] func(string, T) Field func (f anyFieldC[T]) Any(key string, val any) Field { @@ -462,6 +485,8 @@ func Any(key string, value interface{}) Field { c = anyFieldC[zapcore.ObjectMarshaler](Object) case zapcore.ArrayMarshaler: c = anyFieldC[zapcore.ArrayMarshaler](Array) + case []Field: + c = anyFieldC[[]Field](dictField) case bool: c = anyFieldC[bool](Bool) case *bool: diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/field_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/field_test.go index 8f2f52d..f87f159 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/field_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/field_test.go @@ -29,6 +29,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "go.uber.org/zap/internal/stacktrace" "go.uber.org/zap/zapcore" ) @@ -127,6 +128,7 @@ func TestFieldConstructors(t *testing.T) { {"Inline", Field{Type: zapcore.InlineMarshalerType, Interface: name}, Inline(name)}, {"Any:ObjectMarshaler", Any("k", name), Object("k", name)}, {"Any:ArrayMarshaler", Any("k", bools([]bool{true})), Array("k", bools([]bool{true}))}, + {"Any:Dict", Any("k", []Field{String("k", "v")}), Dict("k", String("k", "v"))}, {"Any:Stringer", Any("k", addr), Stringer("k", addr)}, {"Any:Bool", Any("k", true), Bool("k", true)}, {"Any:Bools", Any("k", []bool{true}), Bools("k", []bool{true})}, @@ -268,7 +270,7 @@ func TestStackField(t *testing.T) { assert.Equal(t, "stacktrace", f.Key, "Unexpected field key.") assert.Equal(t, zapcore.StringType, f.Type, "Unexpected field type.") r := regexp.MustCompile(`field_test.go:(\d+)`) - assert.Equal(t, r.ReplaceAllString(takeStacktrace(0), "field_test.go"), r.ReplaceAllString(f.String, "field_test.go"), "Unexpected stack trace") + assert.Equal(t, r.ReplaceAllString(stacktrace.Take(0), "field_test.go"), r.ReplaceAllString(f.String, "field_test.go"), "Unexpected stack trace") assertCanBeReused(t, f) } @@ -277,7 +279,7 @@ func TestStackSkipField(t *testing.T) { assert.Equal(t, "stacktrace", f.Key, "Unexpected field key.") assert.Equal(t, zapcore.StringType, f.Type, "Unexpected field type.") r := regexp.MustCompile(`field_test.go:(\d+)`) - assert.Equal(t, r.ReplaceAllString(takeStacktrace(0), "field_test.go"), r.ReplaceAllString(f.String, "field_test.go"), f.String, "Unexpected stack trace") + assert.Equal(t, r.ReplaceAllString(stacktrace.Take(0), "field_test.go"), r.ReplaceAllString(f.String, "field_test.go"), f.String, "Unexpected stack trace") assertCanBeReused(t, f) } @@ -285,6 +287,30 @@ func TestStackSkipFieldWithSkip(t *testing.T) { f := StackSkip("stacktrace", 1) assert.Equal(t, "stacktrace", f.Key, "Unexpected field key.") assert.Equal(t, zapcore.StringType, f.Type, "Unexpected field type.") - assert.Equal(t, takeStacktrace(1), f.String, "Unexpected stack trace") + assert.Equal(t, stacktrace.Take(1), f.String, "Unexpected stack trace") assertCanBeReused(t, f) } + +func TestDict(t *testing.T) { + tests := []struct { + desc string + field Field + expected any + }{ + {"empty", Dict(""), map[string]any{}}, + {"single", Dict("", String("k", "v")), map[string]any{"k": "v"}}, + {"multiple", Dict("", String("k", "v"), String("k2", "v2")), map[string]any{"k": "v", "k2": "v2"}}, + } + + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + enc := zapcore.NewMapObjectEncoder() + tt.field.Key = "k" + tt.field.AddTo(enc) + assert.Equal(t, tt.expected, enc.Fields["k"], "unexpected map contents") + assert.Len(t, enc.Fields, 1, "found extra keys in map: %v", enc.Fields) + + assertCanBeReused(t, tt.field) + }) + } +} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/flag.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/flag.go index 1312875..1312875 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/flag.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/flag.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/flag_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/flag_test.go index 9ff5444..9ff5444 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/flag_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/flag_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/glide.yaml b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/glide.yaml index 8e1d05e..8e1d05e 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/glide.yaml +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/glide.yaml diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/global.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/global.go index 3cb46c9..3cb46c9 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/global.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/global.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/global_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/global_test.go index 17fa225..17fa225 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/global_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/global_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/go.mod b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/go.mod index 455dae4..88575f4 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/go.mod +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/go.mod @@ -3,9 +3,8 @@ module go.uber.org/zap go 1.19 require ( - github.com/benbjohnson/clock v1.3.0 github.com/stretchr/testify v1.8.1 - go.uber.org/goleak v1.2.0 + go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.10.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/go.sum b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/go.sum index ffa7955..a725757 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/go.sum +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/go.sum @@ -1,5 +1,3 @@ -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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= @@ -16,12 +14,10 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ 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= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/http_handler.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/http_handler.go index 632b683..2be8f65 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/http_handler.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/http_handler.go @@ -69,6 +69,13 @@ import ( // // curl -X PUT localhost:8080/log/level -H "Content-Type: application/json" -d '{"level":"debug"}' func (lvl AtomicLevel) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if err := lvl.serveHTTP(w, r); err != nil { + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "internal error: %v", err) + } +} + +func (lvl AtomicLevel) serveHTTP(w http.ResponseWriter, r *http.Request) error { type errorResponse struct { Error string `json:"error"` } @@ -80,19 +87,20 @@ func (lvl AtomicLevel) ServeHTTP(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: - enc.Encode(payload{Level: lvl.Level()}) + return enc.Encode(payload{Level: lvl.Level()}) + case http.MethodPut: requestedLvl, err := decodePutRequest(r.Header.Get("Content-Type"), r) if err != nil { w.WriteHeader(http.StatusBadRequest) - enc.Encode(errorResponse{Error: err.Error()}) - return + return enc.Encode(errorResponse{Error: err.Error()}) } lvl.SetLevel(requestedLvl) - enc.Encode(payload{Level: lvl.Level()}) + return enc.Encode(payload{Level: lvl.Level()}) + default: w.WriteHeader(http.StatusMethodNotAllowed) - enc.Encode(errorResponse{ + return enc.Encode(errorResponse{ Error: "Only GET and PUT are supported.", }) } @@ -129,5 +137,4 @@ func decodePutJSON(body io.Reader) (zapcore.Level, error) { return 0, errors.New("must specify logging level") } return *pld.Level, nil - } diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/http_handler_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/http_handler_test.go index 9fa9c64..9da3dc7 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/http_handler_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/http_handler_test.go @@ -22,6 +22,7 @@ package zap_test import ( "encoding/json" + "errors" "net/http" "net/http/httptest" "strings" @@ -167,7 +168,9 @@ func TestAtomicLevelServeHTTP(t *testing.T) { res, err := http.DefaultClient.Do(req) require.NoError(t, err, "Error making %s request.", req.Method) - defer res.Body.Close() + defer func() { + assert.NoError(t, res.Body.Close(), "Error closing response body.") + }() require.Equal(t, tt.expectedCode, res.StatusCode, "Unexpected status code.") if tt.expectedCode != http.StatusOK { @@ -188,3 +191,27 @@ func TestAtomicLevelServeHTTP(t *testing.T) { }) } } + +func TestAtomicLevelServeHTTPBrokenWriter(t *testing.T) { + t.Parallel() + + lvl := zap.NewAtomicLevel() + + request, err := http.NewRequest(http.MethodGet, "http://localhost:1234/log/level", nil) + require.NoError(t, err, "Error constructing request.") + + recorder := httptest.NewRecorder() + lvl.ServeHTTP(&brokenHTTPResponseWriter{ + ResponseWriter: recorder, + }, request) + + assert.Equal(t, http.StatusInternalServerError, recorder.Code, "Unexpected status code.") +} + +type brokenHTTPResponseWriter struct { + http.ResponseWriter +} + +func (w *brokenHTTPResponseWriter) Write([]byte) (int, error) { + return 0, errors.New("great sadness") +} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/increase_level_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/increase_level_test.go index 2d88380..2d88380 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/increase_level_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/increase_level_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/bufferpool/bufferpool.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/bufferpool/bufferpool.go index dad583a..dad583a 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/bufferpool/bufferpool.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/bufferpool/bufferpool.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/color/color.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/color/color.go index c4d5d02..c4d5d02 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/color/color.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/color/color.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/color/color_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/color/color_test.go index 4982903..4982903 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/color/color_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/color/color_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/exit/exit.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/exit/exit.go index f673f99..f673f99 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/exit/exit.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/exit/exit.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/exit/exit_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/exit/exit_test.go index 2299584..2299584 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/exit/exit_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/exit/exit_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/level_enabler.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/level_enabler.go index 40bfed8..40bfed8 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/level_enabler.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/level_enabler.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/pool/pool.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/pool/pool.go index 60e9d2c..60e9d2c 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/pool/pool.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/pool/pool.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/pool/pool_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/pool/pool_test.go index 094edf9..094edf9 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/pool/pool_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/pool/pool_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/readme/readme.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/readme/readme.go index 1487659..a9c8ad7 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/readme/readme.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/readme/readme.go @@ -35,19 +35,18 @@ import ( "time" ) -var ( - libraryNameToMarkdownName = map[string]string{ - "Zap": ":zap: zap", - "Zap.Sugar": ":zap: zap (sugared)", - "stdlib.Println": "standard library", - "sirupsen/logrus": "logrus", - "go-kit/kit/log": "go-kit", - "inconshreveable/log15": "log15", - "apex/log": "apex/log", - "rs/zerolog": "zerolog", - "slog": "slog", - } -) +var libraryNameToMarkdownName = map[string]string{ + "Zap": ":zap: zap", + "Zap.Sugar": ":zap: zap (sugared)", + "stdlib.Println": "standard library", + "sirupsen/logrus": "logrus", + "go-kit/kit/log": "go-kit", + "inconshreveable/log15": "log15", + "apex/log": "apex/log", + "rs/zerolog": "zerolog", + "slog": "slog", + "slog.LogAttrs": "slog (LogAttrs)", +} func main() { flag.Parse() diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/stacktrace.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/stacktrace/stack.go index 1f152eb..82af755 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/stacktrace.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/stacktrace/stack.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -18,7 +18,9 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -package zap +// Package stacktrace provides support for gathering stack traces +// efficiently. +package stacktrace import ( "runtime" @@ -28,13 +30,14 @@ import ( "go.uber.org/zap/internal/pool" ) -var _stacktracePool = pool.New(func() *stacktrace { - return &stacktrace{ +var _stackPool = pool.New(func() *Stack { + return &Stack{ storage: make([]uintptr, 64), } }) -type stacktrace struct { +// Stack is a captured stack trace. +type Stack struct { pcs []uintptr // program counters; always a subslice of storage frames *runtime.Frames @@ -48,30 +51,30 @@ type stacktrace struct { storage []uintptr } -// stacktraceDepth specifies how deep of a stack trace should be captured. -type stacktraceDepth int +// Depth specifies how deep of a stack trace should be captured. +type Depth int const ( - // stacktraceFirst captures only the first frame. - stacktraceFirst stacktraceDepth = iota + // First captures only the first frame. + First Depth = iota - // stacktraceFull captures the entire call stack, allocating more + // Full captures the entire call stack, allocating more // storage for it if needed. - stacktraceFull + Full ) -// captureStacktrace captures a stack trace of the specified depth, skipping +// Capture captures a stack trace of the specified depth, skipping // the provided number of frames. skip=0 identifies the caller of -// captureStacktrace. +// Capture. // // The caller must call Free on the returned stacktrace after using it. -func captureStacktrace(skip int, depth stacktraceDepth) *stacktrace { - stack := _stacktracePool.Get() +func Capture(skip int, depth Depth) *Stack { + stack := _stackPool.Get() switch depth { - case stacktraceFirst: + case First: stack.pcs = stack.storage[:1] - case stacktraceFull: + case Full: stack.pcs = stack.storage } @@ -85,7 +88,7 @@ func captureStacktrace(skip int, depth stacktraceDepth) *stacktrace { // runtime.Callers truncates the recorded stacktrace if there is no // room in the provided slice. For the full stack trace, keep expanding // storage until there are fewer frames than there is room. - if depth == stacktraceFull { + if depth == Full { pcs := stack.pcs for numFrames == len(pcs) { pcs = make([]uintptr, len(pcs)*2) @@ -107,50 +110,54 @@ func captureStacktrace(skip int, depth stacktraceDepth) *stacktrace { // Free releases resources associated with this stacktrace // and returns it back to the pool. -func (st *stacktrace) Free() { +func (st *Stack) Free() { st.frames = nil st.pcs = nil - _stacktracePool.Put(st) + _stackPool.Put(st) } // Count reports the total number of frames in this stacktrace. // Count DOES NOT change as Next is called. -func (st *stacktrace) Count() int { +func (st *Stack) Count() int { return len(st.pcs) } // Next returns the next frame in the stack trace, // and a boolean indicating whether there are more after it. -func (st *stacktrace) Next() (_ runtime.Frame, more bool) { +func (st *Stack) Next() (_ runtime.Frame, more bool) { return st.frames.Next() } -func takeStacktrace(skip int) string { - stack := captureStacktrace(skip+1, stacktraceFull) +// Take returns a string representation of the current stacktrace. +// +// skip is the number of frames to skip before recording the stack trace. +// skip=0 identifies the caller of Take. +func Take(skip int) string { + stack := Capture(skip+1, Full) defer stack.Free() buffer := bufferpool.Get() defer buffer.Free() - stackfmt := newStackFormatter(buffer) + stackfmt := NewFormatter(buffer) stackfmt.FormatStack(stack) return buffer.String() } -// stackFormatter formats a stack trace into a readable string representation. -type stackFormatter struct { +// Formatter formats a stack trace into a readable string representation. +type Formatter struct { b *buffer.Buffer nonEmpty bool // whehther we've written at least one frame already } -// newStackFormatter builds a new stackFormatter. -func newStackFormatter(b *buffer.Buffer) stackFormatter { - return stackFormatter{b: b} +// NewFormatter builds a new Formatter. +func NewFormatter(b *buffer.Buffer) Formatter { + return Formatter{b: b} } // FormatStack formats all remaining frames in the provided stacktrace -- minus // the final runtime.main/runtime.goexit frame. -func (sf *stackFormatter) FormatStack(stack *stacktrace) { +func (sf *Formatter) FormatStack(stack *Stack) { // Note: On the last iteration, frames.Next() returns false, with a valid // frame, but we ignore this frame. The last frame is a runtime frame which // adds noise, since it's only either runtime.main or runtime.goexit. @@ -160,7 +167,7 @@ func (sf *stackFormatter) FormatStack(stack *stacktrace) { } // FormatFrame formats the given frame. -func (sf *stackFormatter) FormatFrame(frame runtime.Frame) { +func (sf *Formatter) FormatFrame(frame runtime.Frame) { if sf.nonEmpty { sf.b.AppendByte('\n') } diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/stacktrace_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/stacktrace/stack_test.go index 82b6af3..195eeae 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/stacktrace_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/stacktrace/stack_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -18,7 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -package zap +package stacktrace import ( "bytes" @@ -29,20 +29,20 @@ import ( "github.com/stretchr/testify/require" ) -func TestTakeStacktrace(t *testing.T) { - trace := takeStacktrace(0) +func TestTake(t *testing.T) { + trace := Take(0) lines := strings.Split(trace, "\n") require.NotEmpty(t, lines, "Expected stacktrace to have at least one frame.") assert.Contains( t, lines[0], - "go.uber.org/zap.TestTakeStacktrace", + "go.uber.org/zap/internal/stacktrace.TestTake", "Expected stacktrace to start with the test.", ) } -func TestTakeStacktraceWithSkip(t *testing.T) { - trace := takeStacktrace(1) +func TestTakeWithSkip(t *testing.T) { + trace := Take(1) lines := strings.Split(trace, "\n") require.NotEmpty(t, lines, "Expected stacktrace to have at least one frame.") assert.Contains( @@ -53,10 +53,10 @@ func TestTakeStacktraceWithSkip(t *testing.T) { ) } -func TestTakeStacktraceWithSkipInnerFunc(t *testing.T) { +func TestTakeWithSkipInnerFunc(t *testing.T) { var trace string func() { - trace = takeStacktrace(2) + trace = Take(2) }() lines := strings.Split(trace, "\n") require.NotEmpty(t, lines, "Expected stacktrace to have at least one frame.") @@ -68,13 +68,13 @@ func TestTakeStacktraceWithSkipInnerFunc(t *testing.T) { ) } -func TestTakeStacktraceDeepStack(t *testing.T) { +func TestTakeDeepStack(t *testing.T) { const ( N = 500 - withStackDepthName = "go.uber.org/zap.withStackDepth" + withStackDepthName = "go.uber.org/zap/internal/stacktrace.withStackDepth" ) withStackDepth(N, func() { - trace := takeStacktrace(0) + trace := Take(0) for found := 0; found < N; found++ { i := strings.Index(trace, withStackDepthName) if i < 0 { @@ -86,9 +86,9 @@ func TestTakeStacktraceDeepStack(t *testing.T) { }) } -func BenchmarkTakeStacktrace(b *testing.B) { +func BenchmarkTake(b *testing.B) { for i := 0; i < b.N; i++ { - takeStacktrace(0) + Take(0) } } diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/clock.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/clock.go new file mode 100644 index 0000000..47b0b7f --- /dev/null +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/clock.go @@ -0,0 +1,153 @@ +// Copyright (c) 2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package ztest + +import ( + "sort" + "sync" + "time" +) + +// MockClock is a fake source of time. +// It implements standard time operations, +// but allows the user to control the passage of time. +// +// Use the [Add] method to progress time. +type MockClock struct { + mu sync.RWMutex + now time.Time + + // The MockClock works by maintaining a list of waiters. + // Each waiter knows the time at which it should be resolved. + // When the clock advances, all waiters that are in range are resolved + // in chronological order. + waiters []waiter +} + +// NewMockClock builds a new mock clock +// using the current actual time as the initial time. +func NewMockClock() *MockClock { + return &MockClock{ + now: time.Now(), + } +} + +// Now reports the current time. +func (c *MockClock) Now() time.Time { + c.mu.RLock() + defer c.mu.RUnlock() + return c.now +} + +// NewTicker returns a time.Ticker that ticks at the specified frequency. +// +// As with [time.NewTicker], +// the ticker will drop ticks if the receiver is slow, +// and the channel is never closed. +// +// Calling Stop on the returned ticker is a no-op. +// The ticker only runs when the clock is advanced. +func (c *MockClock) NewTicker(d time.Duration) *time.Ticker { + ch := make(chan time.Time, 1) + + var tick func(time.Time) + tick = func(now time.Time) { + next := now.Add(d) + c.runAt(next, func() { + defer tick(next) + + select { + case ch <- next: + // ok + default: + // The receiver is slow. + // Drop the tick and continue. + } + }) + } + tick(c.Now()) + + return &time.Ticker{C: ch} +} + +// runAt schedules the given function to be run at the given time. +// The function runs without a lock held, so it may schedule more work. +func (c *MockClock) runAt(t time.Time, fn func()) { + c.mu.Lock() + defer c.mu.Unlock() + c.waiters = append(c.waiters, waiter{until: t, fn: fn}) +} + +type waiter struct { + until time.Time + fn func() +} + +// Add progresses time by the given duration. +// Other operations waiting for the time to advance +// will be resolved if they are within range. +// +// Side effects of operations waiting for the time to advance +// will take effect on a best-effort basis. +// Avoid racing with operations that have side effects. +// +// Panics if the duration is negative. +func (c *MockClock) Add(d time.Duration) { + if d < 0 { + panic("cannot add negative duration") + } + + c.mu.Lock() + defer c.mu.Unlock() + + sort.Slice(c.waiters, func(i, j int) bool { + return c.waiters[i].until.Before(c.waiters[j].until) + }) + + newTime := c.now.Add(d) + // newTime won't be recorded until the end of this method. + // This ensures that any waiters that are resolved + // are resolved at the time they were expecting. + + for len(c.waiters) > 0 { + w := c.waiters[0] + if w.until.After(newTime) { + break + } + c.waiters[0] = waiter{} // avoid memory leak + c.waiters = c.waiters[1:] + + // The waiter is within range. + // Travel to the time of the waiter and resolve it. + c.now = w.until + + // The waiter may schedule more work + // so we must release the lock. + c.mu.Unlock() + w.fn() + // Sleeping here is necessary to let the side effects of waiters + // take effect before we continue. + time.Sleep(1 * time.Millisecond) + c.mu.Lock() + } + + c.now = newTime +} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/clock_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/clock_test.go index 3808ed7..6db724b 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/clock_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/clock_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -55,3 +55,26 @@ func TestMockClock_NewTicker(t *testing.T) { assert.Equal(t, int32(2), n.Load()) close(quit) } + +func TestMockClock_NewTicker_slowConsumer(t *testing.T) { + clock := NewMockClock() + + ticker := clock.NewTicker(time.Microsecond) + defer ticker.Stop() + + // Two ticks, only one consumed. + clock.Add(2 * time.Microsecond) + <-ticker.C + + select { + case <-ticker.C: + t.Fatal("unexpected tick") + default: + // ok + } +} + +func TestMockClock_Add_negative(t *testing.T) { + clock := NewMockClock() + assert.Panics(t, func() { clock.Add(-1) }) +} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/doc.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/doc.go index cd4b98c..cd4b98c 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/doc.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/doc.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/timeout.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/timeout.go index e4222f9..e4222f9 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/timeout.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/timeout.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/writer.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/writer.go index f54d856..f54d856 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/writer.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/internal/ztest/writer.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/leak_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/leak_test.go index 474ed2f..474ed2f 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/leak_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/leak_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/level.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/level.go index 155b208..155b208 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/level.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/level.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/level_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/level_test.go index db7391d..db7391d 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/level_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/level_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/logger.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/logger.go index 0e95480..c4d3003 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/logger.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/logger.go @@ -27,6 +27,7 @@ import ( "strings" "go.uber.org/zap/internal/bufferpool" + "go.uber.org/zap/internal/stacktrace" "go.uber.org/zap/zapcore" ) @@ -42,6 +43,7 @@ type Logger struct { development bool addCaller bool + onPanic zapcore.CheckWriteHook // default is WriteThenPanic onFatal zapcore.CheckWriteHook // default is WriteThenFatal name string @@ -173,7 +175,8 @@ func (log *Logger) WithOptions(opts ...Option) *Logger { } // With creates a child logger and adds structured context to it. Fields added -// to the child don't affect the parent, and vice versa. +// to the child don't affect the parent, and vice versa. Any fields that +// require evaluation (such as Objects) are evaluated upon invocation of With. func (log *Logger) With(fields ...Field) *Logger { if len(fields) == 0 { return log @@ -183,6 +186,28 @@ func (log *Logger) With(fields ...Field) *Logger { return l } +// WithLazy creates a child logger and adds structured context to it lazily. +// +// The fields are evaluated only if the logger is further chained with [With] +// or is written to with any of the log level methods. +// Until that occurs, the logger may retain references to objects inside the fields, +// and logging will reflect the state of an object at the time of logging, +// not the time of WithLazy(). +// +// WithLazy provides a worthwhile performance optimization for contextual loggers +// when the likelihood of using the child logger is low, +// such as error paths and rarely taken branches. +// +// Similar to [With], fields added to the child don't affect the parent, and vice versa. +func (log *Logger) WithLazy(fields ...Field) *Logger { + if len(fields) == 0 { + return log + } + return log.WithOptions(WrapCore(func(core zapcore.Core) zapcore.Core { + return zapcore.NewLazyWith(core, fields) + })) +} + // Level reports the minimum enabled level for this logger. // // For NopLoggers, this is [zapcore.InvalidLevel]. @@ -199,6 +224,8 @@ func (log *Logger) Check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { // Log logs a message at the specified level. The message includes any fields // passed at the log site, as well as any fields accumulated on the logger. +// Any Fields that require evaluation (such as Objects) are evaluated upon +// invocation of Log. func (log *Logger) Log(lvl zapcore.Level, msg string, fields ...Field) { if ce := log.check(lvl, msg); ce != nil { ce.Write(fields...) @@ -288,8 +315,8 @@ func (log *Logger) Name() string { } func (log *Logger) clone() *Logger { - copy := *log - return © + clone := *log + return &clone } func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { @@ -319,27 +346,12 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { // Set up any required terminal behavior. switch ent.Level { case zapcore.PanicLevel: - ce = ce.After(ent, zapcore.WriteThenPanic) + ce = ce.After(ent, terminalHookOverride(zapcore.WriteThenPanic, log.onPanic)) case zapcore.FatalLevel: - onFatal := log.onFatal - // nil or WriteThenNoop will lead to continued execution after - // a Fatal log entry, which is unexpected. For example, - // - // f, err := os.Open(..) - // if err != nil { - // log.Fatal("cannot open", zap.Error(err)) - // } - // fmt.Println(f.Name()) - // - // The f.Name() will panic if we continue execution after the - // log.Fatal. - if onFatal == nil || onFatal == zapcore.WriteThenNoop { - onFatal = zapcore.WriteThenFatal - } - ce = ce.After(ent, onFatal) + ce = ce.After(ent, terminalHookOverride(zapcore.WriteThenFatal, log.onFatal)) case zapcore.DPanicLevel: if log.development { - ce = ce.After(ent, zapcore.WriteThenPanic) + ce = ce.After(ent, terminalHookOverride(zapcore.WriteThenPanic, log.onPanic)) } } @@ -360,17 +372,17 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { // Adding the caller or stack trace requires capturing the callers of // this function. We'll share information between these two. - stackDepth := stacktraceFirst + stackDepth := stacktrace.First if addStack { - stackDepth = stacktraceFull + stackDepth = stacktrace.Full } - stack := captureStacktrace(log.callerSkip+callerSkipOffset, stackDepth) + stack := stacktrace.Capture(log.callerSkip+callerSkipOffset, stackDepth) defer stack.Free() if stack.Count() == 0 { if log.addCaller { fmt.Fprintf(log.errorOutput, "%v Logger.check error: failed to get caller\n", ent.Time.UTC()) - log.errorOutput.Sync() + _ = log.errorOutput.Sync() } return ce } @@ -391,7 +403,7 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { buffer := bufferpool.Get() defer buffer.Free() - stackfmt := newStackFormatter(buffer) + stackfmt := stacktrace.NewFormatter(buffer) // We've already extracted the first frame, so format that // separately and defer to stackfmt for the rest. @@ -404,3 +416,20 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { return ce } + +func terminalHookOverride(defaultHook, override zapcore.CheckWriteHook) zapcore.CheckWriteHook { + // A nil or WriteThenNoop hook will lead to continued execution after + // a Panic or Fatal log entry, which is unexpected. For example, + // + // f, err := os.Open(..) + // if err != nil { + // log.Fatal("cannot open", zap.Error(err)) + // } + // fmt.Println(f.Name()) + // + // The f.Name() will panic if we continue execution after the log.Fatal. + if override == nil || override == zapcore.WriteThenNoop { + return defaultHook + } + return override +} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/logger_bench_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/logger_bench_test.go index bcf501a..9d41298 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/logger_bench_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/logger_bench_test.go @@ -23,6 +23,7 @@ package zap import ( "errors" "runtime" + "strconv" "sync" "testing" "time" @@ -199,6 +200,48 @@ func BenchmarkAddCallerAndStacktrace(b *testing.B) { }) } +func Benchmark5WithsUsed(b *testing.B) { + benchmarkWithUsed(b, (*Logger).With, 5, true) +} + +// This benchmark will be used in future as a +// baseline for improving +func Benchmark5WithsNotUsed(b *testing.B) { + benchmarkWithUsed(b, (*Logger).With, 5, false) +} + +func Benchmark5WithLazysUsed(b *testing.B) { + benchmarkWithUsed(b, (*Logger).WithLazy, 5, true) +} + +// This benchmark will be used in future as a +// baseline for improving +func Benchmark5WithLazysNotUsed(b *testing.B) { + benchmarkWithUsed(b, (*Logger).WithLazy, 5, false) +} + +func benchmarkWithUsed(b *testing.B, withMethod func(*Logger, ...zapcore.Field) *Logger, N int, use bool) { + keys := make([]string, N) + values := make([]string, N) + for i := 0; i < N; i++ { + keys[i] = "k" + strconv.Itoa(i) + values[i] = "v" + strconv.Itoa(i) + } + + b.ResetTimer() + + withBenchedLogger(b, func(log *Logger) { + for i := 0; i < N; i++ { + log = withMethod(log, String(keys[i], values[i])) + } + if use { + log.Info("used") + return + } + runtime.KeepAlive(log) + }) +} + func Benchmark10Fields(b *testing.B) { withBenchedLogger(b, func(log *Logger) { log.Info("Ten fields, passed at the log site.", diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/logger_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/logger_test.go index d4af575..4a953b6 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/logger_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/logger_test.go @@ -22,6 +22,8 @@ package zap import ( "errors" + "fmt" + "strconv" "sync" "sync/atomic" "testing" @@ -124,20 +126,250 @@ func TestLoggerInitialFields(t *testing.T) { } func TestLoggerWith(t *testing.T) { - fieldOpts := opts(Fields(Int("foo", 42))) - withLogger(t, DebugLevel, fieldOpts, func(logger *Logger, logs *observer.ObservedLogs) { - // Child loggers should have copy-on-write semantics, so two children - // shouldn't stomp on each other's fields or affect the parent's fields. - logger.With(String("one", "two")).Info("") - logger.With(String("three", "four")).Info("") - logger.Info("") + tests := []struct { + name string + initialFields []Field + withMethod func(*Logger, ...Field) *Logger + }{ + { + "regular non lazy logger", + []Field{Int("foo", 42)}, + (*Logger).With, + }, + { + "regular non lazy logger no initial fields", + []Field{}, + (*Logger).With, + }, + { + "lazy with logger", + []Field{Int("foo", 42)}, + (*Logger).WithLazy, + }, + { + "lazy with logger no initial fields", + []Field{}, + (*Logger).WithLazy, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + withLogger(t, DebugLevel, opts(Fields(tt.initialFields...)), func(logger *Logger, logs *observer.ObservedLogs) { + // Child loggers should have copy-on-write semantics, so two children + // shouldn't stomp on each other's fields or affect the parent's fields. + tt.withMethod(logger).Info("") + tt.withMethod(logger, String("one", "two")).Info("") + tt.withMethod(logger, String("three", "four")).Info("") + tt.withMethod(logger, String("five", "six")).With(String("seven", "eight")).Info("") + logger.Info("") - assert.Equal(t, []observer.LoggedEntry{ - {Context: []Field{Int("foo", 42), String("one", "two")}}, - {Context: []Field{Int("foo", 42), String("three", "four")}}, - {Context: []Field{Int("foo", 42)}}, - }, logs.AllUntimed(), "Unexpected cross-talk between child loggers.") - }) + assert.Equal(t, []observer.LoggedEntry{ + {Context: tt.initialFields}, + {Context: append(tt.initialFields, String("one", "two"))}, + {Context: append(tt.initialFields, String("three", "four"))}, + {Context: append(tt.initialFields, String("five", "six"), String("seven", "eight"))}, + {Context: tt.initialFields}, + }, logs.AllUntimed(), "Unexpected cross-talk between child loggers.") + }) + }) + } +} + +func TestLoggerWithCaptures(t *testing.T) { + type withF func(*Logger, ...Field) *Logger + tests := []struct { + name string + withMethods []withF + wantJSON []string + }{ + { + name: "regular with captures arguments at time of With", + withMethods: []withF{(*Logger).With}, + wantJSON: []string{ + `{ + "m": "hello 0", + "a0": [0], + "b0": [1] + }`, + `{ + "m": "world 0", + "a0": [0], + "c0": [2] + }`, + }, + }, + { + name: "lazy with captures arguments at time of With or Logging", + withMethods: []withF{(*Logger).WithLazy}, + wantJSON: []string{ + `{ + "m": "hello 0", + "a0": [1], + "b0": [1] + }`, + `{ + "m": "world 0", + "a0": [1], + "c0": [2] + }`, + }, + }, + { + name: "2x With captures arguments at time of each With", + withMethods: []withF{(*Logger).With, (*Logger).With}, + wantJSON: []string{ + `{ + "m": "hello 0", + "a0": [0], + "b0": [1] + }`, + `{ + "m": "world 0", + "a0": [0], + "c0": [2] + }`, + `{ + "m": "hello 1", + "a0": [0], + "c0": [2], + "a1": [10], + "b1": [11] + }`, + `{ + "m": "world 1", + "a0": [0], + "c0": [2], + "a1": [10], + "c1": [12] + }`, + }, + }, + { + name: "2x WithLazy. Captures arguments only at logging time.", + withMethods: []withF{(*Logger).WithLazy, (*Logger).WithLazy}, + wantJSON: []string{ + `{ + "m": "hello 0", + "a0": [1], + "b0": [1] + }`, + `{ + "m": "world 0", + "a0": [1], + "c0": [2] + }`, + `{ + "m": "hello 1", + "a0": [1], + "c0": [2], + "a1": [11], + "b1": [11] + }`, + `{ + "m": "world 1", + "a0": [1], + "c0": [2], + "a1": [11], + "c1": [12] + }`, + }, + }, + { + name: "WithLazy then With", + withMethods: []withF{(*Logger).WithLazy, (*Logger).With}, + wantJSON: []string{ + `{ + "m": "hello 0", + "a0": [1], + "b0": [1] + }`, + `{ + "m": "world 0", + "a0": [1], + "c0": [2] + }`, + `{ + "m": "hello 1", + "a0": [1], + "c0": [2], + "a1": [10], + "b1": [11] + }`, + `{ + "m": "world 1", + "a0": [1], + "c0": [2], + "a1": [10], + "c1": [12] + }`, + }, + }, + { + name: "With then WithLazy", + withMethods: []withF{(*Logger).With, (*Logger).WithLazy}, + wantJSON: []string{ + `{ + "m": "hello 0", + "a0": [0], + "b0": [1] + }`, + `{ + "m": "world 0", + "a0": [0], + "c0": [2] + }`, + `{ + "m": "hello 1", + "a0": [0], + "c0": [2], + "a1": [11], + "b1": [11] + }`, + `{ + "m": "world 1", + "a0": [0], + "c0": [2], + "a1": [11], + "c1": [12] + }`, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + enc := zapcore.NewJSONEncoder(zapcore.EncoderConfig{ + MessageKey: "m", + }) + + var bs ztest.Buffer + logger := New(zapcore.NewCore(enc, &bs, DebugLevel)) + + for i, withMethod := range tt.withMethods { + + iStr := strconv.Itoa(i) + x := 10 * i + arr := zapcore.ArrayMarshalerFunc(func(enc zapcore.ArrayEncoder) error { + enc.AppendInt(x) + return nil + }) + + // Demonstrate the arguments are captured when With() and Info() are invoked. + logger = withMethod(logger, Array("a"+iStr, arr)) + x++ + logger.Info(fmt.Sprintf("hello %d", i), Array("b"+iStr, arr)) + x++ + logger = withMethod(logger, Array("c"+iStr, arr)) + logger.Info(fmt.Sprintf("world %d", i)) + } + + if lines := bs.Lines(); assert.Len(t, lines, len(tt.wantJSON)) { + for i, want := range tt.wantJSON { + assert.JSONEq(t, want, lines[i], "Unexpected output from the %d'th log.", i) + } + } + }) + } } func TestLoggerLogPanic(t *testing.T) { @@ -604,6 +836,130 @@ func TestLoggerFatalOnNoop(t *testing.T) { assert.Equal(t, 1, exitStub.Code, "must exit with status 1 for WriteThenNoop") } +func TestLoggerCustomOnPanic(t *testing.T) { + tests := []struct { + msg string + level zapcore.Level + opts []Option + finished bool + want []observer.LoggedEntry + recoverValue any + }{ + { + msg: "panic with nil hook", + level: PanicLevel, + opts: opts(WithPanicHook(nil)), + finished: false, + want: []observer.LoggedEntry{ + { + Entry: zapcore.Entry{Level: PanicLevel, Message: "foobar"}, + Context: []Field{}, + }, + }, + recoverValue: "foobar", + }, + { + msg: "panic with noop hook", + level: PanicLevel, + opts: opts(WithPanicHook(zapcore.WriteThenNoop)), + finished: false, + want: []observer.LoggedEntry{ + { + Entry: zapcore.Entry{Level: PanicLevel, Message: "foobar"}, + Context: []Field{}, + }, + }, + recoverValue: "foobar", + }, + { + msg: "no panic with goexit hook", + level: PanicLevel, + opts: opts(WithPanicHook(zapcore.WriteThenGoexit)), + finished: false, + want: []observer.LoggedEntry{ + { + Entry: zapcore.Entry{Level: PanicLevel, Message: "foobar"}, + Context: []Field{}, + }, + }, + recoverValue: nil, + }, + { + msg: "dpanic no panic in development mode with goexit hook", + level: DPanicLevel, + opts: opts(WithPanicHook(zapcore.WriteThenGoexit), Development()), + finished: false, + want: []observer.LoggedEntry{ + { + Entry: zapcore.Entry{Level: DPanicLevel, Message: "foobar"}, + Context: []Field{}, + }, + }, + recoverValue: nil, + }, + { + msg: "dpanic panic in development mode with noop hook", + level: DPanicLevel, + opts: opts(WithPanicHook(zapcore.WriteThenNoop), Development()), + finished: false, + want: []observer.LoggedEntry{ + { + Entry: zapcore.Entry{Level: DPanicLevel, Message: "foobar"}, + Context: []Field{}, + }, + }, + recoverValue: "foobar", + }, + { + msg: "dpanic no exit in production mode with goexit hook", + level: DPanicLevel, + opts: opts(WithPanicHook(zapcore.WriteThenPanic)), + finished: true, + want: []observer.LoggedEntry{ + { + Entry: zapcore.Entry{Level: DPanicLevel, Message: "foobar"}, + Context: []Field{}, + }, + }, + recoverValue: nil, + }, + { + msg: "dpanic no panic in production mode with panic hook", + level: DPanicLevel, + opts: opts(WithPanicHook(zapcore.WriteThenPanic)), + finished: true, + want: []observer.LoggedEntry{ + { + Entry: zapcore.Entry{Level: DPanicLevel, Message: "foobar"}, + Context: []Field{}, + }, + }, + recoverValue: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.msg, func(t *testing.T) { + withLogger(t, InfoLevel, tt.opts, func(logger *Logger, logs *observer.ObservedLogs) { + var finished bool + recovered := make(chan any) + go func() { + defer func() { + recovered <- recover() + }() + + logger.Log(tt.level, "foobar") + finished = true + }() + + assert.Equal(t, tt.recoverValue, <-recovered, "unexpected value from recover()") + assert.Equal(t, tt.finished, finished, "expect goroutine finished state doesn't match") + assert.Equal(t, tt.want, logs.AllUntimed(), "unexpected logs") + }) + }) + } +} + func TestLoggerCustomOnFatal(t *testing.T) { tests := []struct { msg string diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/options.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/options.go index c4f3bca..43d357a 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/options.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/options.go @@ -132,6 +132,21 @@ func IncreaseLevel(lvl zapcore.LevelEnabler) Option { }) } +// WithPanicHook sets a CheckWriteHook to run on Panic/DPanic logs. +// Zap will call this hook after writing a log statement with a Panic/DPanic level. +// +// For example, the following builds a logger that will exit the current +// goroutine after writing a Panic/DPanic log message, but it will not start a panic. +// +// zap.New(core, zap.WithPanicHook(zapcore.WriteThenGoexit)) +// +// This is useful for testing Panic/DPanic log output. +func WithPanicHook(hook zapcore.CheckWriteHook) Option { + return optionFunc(func(log *Logger) { + log.onPanic = hook + }) +} + // OnFatal sets the action to take on fatal logs. // // Deprecated: Use [WithFatalHook] instead. diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sink.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sink.go index 478c9a1..499772a 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sink.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sink.go @@ -66,7 +66,8 @@ func newSinkRegistry() *sinkRegistry { factories: make(map[string]func(*url.URL) (Sink, error)), openFile: os.OpenFile, } - sr.RegisterSink(schemeFile, sr.newFileSinkFromURL) + // Infallible operation: the registry is empty, so we can't have a conflict. + _ = sr.RegisterSink(schemeFile, sr.newFileSinkFromURL) return sr } @@ -154,7 +155,7 @@ func (sr *sinkRegistry) newFileSinkFromPath(path string) (Sink, error) { case "stderr": return nopCloserSink{os.Stderr}, nil } - return sr.openFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666) + return sr.openFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0o666) } func normalizeScheme(s string) (string, error) { diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sink_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sink_test.go index 0dfa616..5fc37be 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sink_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sink_test.go @@ -68,13 +68,12 @@ func TestRegisterSink(t *testing.T) { require.NoError(t, RegisterSink(strings.ToUpper(memScheme), memFactory), "Failed to register scheme %q.", memScheme) require.NoError(t, RegisterSink(nopScheme, nopFactory), "Failed to register scheme %q.", nopScheme) - sink, close, err := Open( + sink, closeSink, err := Open( memScheme+"://somewhere", nopScheme+"://somewhere-else", ) require.NoError(t, err, "Unexpected error opening URLs with registered schemes.") - - defer close() + defer closeSink() assert.Equal(t, 1, memCalls, "Unexpected number of calls to memory factory.") assert.Equal(t, 1, nopCalls, "Unexpected number of calls to no-op factory.") diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sink_windows_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sink_windows_test.go index fd6a475..fd6a475 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sink_windows_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sink_windows_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/stacktrace_ext_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/stacktrace_ext_test.go index 71f0983..9f018aa 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/stacktrace_ext_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/stacktrace_ext_test.go @@ -97,7 +97,7 @@ func TestStacktraceFiltersVendorZap(t *testing.T) { testDir := filepath.Join(goPath, "src/go.uber.org/zap_test/") vendorDir := filepath.Join(testDir, "vendor") - require.NoError(t, os.MkdirAll(testDir, 0777), "Failed to create source director") + require.NoError(t, os.MkdirAll(testDir, 0o777), "Failed to create source director") curFile := getSelfFilename(t) setupSymlink(t, curFile, filepath.Join(testDir, curFile)) @@ -175,7 +175,7 @@ func getSelfFilename(t *testing.T) string { func setupSymlink(t *testing.T, src, dst string) { // Make sure the destination directory exists. - os.MkdirAll(filepath.Dir(dst), 0777) + require.NoError(t, os.MkdirAll(filepath.Dir(dst), 0o777)) // Get absolute path of the source for the symlink, otherwise we can create a symlink // that uses relative paths. diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sugar.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sugar.go index 00ac5fe..8904cd0 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sugar.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sugar.go @@ -115,6 +115,21 @@ func (s *SugaredLogger) With(args ...interface{}) *SugaredLogger { return &SugaredLogger{base: s.base.With(s.sweetenFields(args)...)} } +// WithLazy adds a variadic number of fields to the logging context lazily. +// The fields are evaluated only if the logger is further chained with [With] +// or is written to with any of the log level methods. +// Until that occurs, the logger may retain references to objects inside the fields, +// and logging will reflect the state of an object at the time of logging, +// not the time of WithLazy(). +// +// Similar to [With], fields added to the child don't affect the parent, +// and vice versa. Also, the keys in key-value pairs should be strings. In development, +// passing a non-string key panics, while in production it logs an error and skips the pair. +// Passing an orphaned key has the same behavior. +func (s *SugaredLogger) WithLazy(args ...interface{}) *SugaredLogger { + return &SugaredLogger{base: s.base.WithLazy(s.sweetenFields(args)...)} +} + // Level reports the minimum enabled level for this logger. // // For NopLoggers, this is [zapcore.InvalidLevel]. @@ -122,6 +137,12 @@ func (s *SugaredLogger) Level() zapcore.Level { return zapcore.LevelOf(s.base.core) } +// Log logs the provided arguments at provided level. +// Spaces are added between arguments when neither is a string. +func (s *SugaredLogger) Log(lvl zapcore.Level, args ...interface{}) { + s.log(lvl, "", args, nil) +} + // Debug logs the provided arguments at [DebugLevel]. // Spaces are added between arguments when neither is a string. func (s *SugaredLogger) Debug(args ...interface{}) { @@ -165,6 +186,12 @@ func (s *SugaredLogger) Fatal(args ...interface{}) { s.log(FatalLevel, "", args, nil) } +// Logf formats the message according to the format specifier +// and logs it at provided level. +func (s *SugaredLogger) Logf(lvl zapcore.Level, template string, args ...interface{}) { + s.log(lvl, template, args, nil) +} + // Debugf formats the message according to the format specifier // and logs it at [DebugLevel]. func (s *SugaredLogger) Debugf(template string, args ...interface{}) { @@ -208,6 +235,12 @@ func (s *SugaredLogger) Fatalf(template string, args ...interface{}) { s.log(FatalLevel, template, args, nil) } +// Logw logs a message with some additional context. The variadic key-value +// pairs are treated as they are in With. +func (s *SugaredLogger) Logw(lvl zapcore.Level, msg string, keysAndValues ...interface{}) { + s.log(lvl, msg, nil, keysAndValues) +} + // Debugw logs a message with some additional context. The variadic key-value // pairs are treated as they are in With. // @@ -255,6 +288,12 @@ func (s *SugaredLogger) Fatalw(msg string, keysAndValues ...interface{}) { s.log(FatalLevel, msg, nil, keysAndValues) } +// Logln logs a message at provided level. +// Spaces are always added between arguments. +func (s *SugaredLogger) Logln(lvl zapcore.Level, args ...interface{}) { + s.logln(lvl, args, nil) +} + // Debugln logs a message at [DebugLevel]. // Spaces are always added between arguments. func (s *SugaredLogger) Debugln(args ...interface{}) { diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sugar_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sugar_test.go index 9e914ec..8ca2bdd 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/sugar_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/sugar_test.go @@ -22,6 +22,8 @@ package zap import ( "errors" + "fmt" + "strconv" "testing" "go.uber.org/zap/internal/exit" @@ -54,6 +56,9 @@ func TestSugarWith(t *testing.T) { } } + type withAny func(*SugaredLogger, ...interface{}) *SugaredLogger + withMethods := []withAny{(*SugaredLogger).With, (*SugaredLogger).WithLazy} + tests := []struct { desc string args []interface{} @@ -141,16 +146,94 @@ func TestSugarWith(t *testing.T) { } for _, tt := range tests { - withSugar(t, DebugLevel, nil, func(logger *SugaredLogger, logs *observer.ObservedLogs) { - logger.With(tt.args...).Info("") - output := logs.AllUntimed() - if len(tt.errLogs) > 0 { - for i := range tt.errLogs { - assert.Equal(t, tt.errLogs[i], output[i], "Unexpected error log at position %d for scenario %s.", i, tt.desc) + for _, withMethod := range withMethods { + withSugar(t, DebugLevel, nil, func(logger *SugaredLogger, logs *observer.ObservedLogs) { + withMethod(logger, tt.args...).Info("") + output := logs.AllUntimed() + if len(tt.errLogs) > 0 { + for i := range tt.errLogs { + assert.Equal(t, tt.errLogs[i], output[i], "Unexpected error log at position %d for scenario %s.", i, tt.desc) + } + } + assert.Equal(t, len(tt.errLogs)+1, len(output), "Expected only one non-error message to be logged in scenario %s.", tt.desc) + assert.Equal(t, tt.expected, output[len(tt.errLogs)].Context, "Unexpected message context in scenario %s.", tt.desc) + }) + } + } +} + +func TestSugarWithCaptures(t *testing.T) { + type withAny func(*SugaredLogger, ...interface{}) *SugaredLogger + + tests := []struct { + name string + withMethods []withAny + wantJSON []string + }{ + { + name: "with captures arguments at time of With", + withMethods: []withAny{(*SugaredLogger).With}, + wantJSON: []string{ + `{ + "m": "hello 0", + "a0": [0], + "b0": [1] + }`, + `{ + "m": "world 0", + "a0": [0], + "c0": [2] + }`, + }, + }, + { + name: "lazy with captures arguments at time of Logging", + withMethods: []withAny{(*SugaredLogger).WithLazy}, + wantJSON: []string{ + `{ + "m": "hello 0", + "a0": [1], + "b0": [1] + }`, + `{ + "m": "world 0", + "a0": [1], + "c0": [2] + }`, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + enc := zapcore.NewJSONEncoder(zapcore.EncoderConfig{ + MessageKey: "m", + }) + + var bs ztest.Buffer + logger := New(zapcore.NewCore(enc, &bs, DebugLevel)).Sugar() + + for i, withMethod := range tt.withMethods { + iStr := strconv.Itoa(i) + x := 10 * i + arr := zapcore.ArrayMarshalerFunc(func(enc zapcore.ArrayEncoder) error { + enc.AppendInt(x) + return nil + }) + + logger = withMethod(logger, Array("a"+iStr, arr)) + x++ + logger.Infow(fmt.Sprintf("hello %d", i), Array("b"+iStr, arr)) + x++ + logger = withMethod(logger, Array("c"+iStr, arr)) + logger.Infow(fmt.Sprintf("world %d", i)) + } + + if lines := bs.Lines(); assert.Len(t, lines, len(tt.wantJSON)) { + for i, want := range tt.wantJSON { + assert.JSONEq(t, want, lines[i], "Unexpected output from the %d'th log.", i) } } - assert.Equal(t, len(tt.errLogs)+1, len(output), "Expected only one non-error message to be logged in scenario %s.", tt.desc) - assert.Equal(t, tt.expected, output[len(tt.errLogs)].Context, "Unexpected message context in scenario %s.", tt.desc) }) } } @@ -228,9 +311,10 @@ func TestSugarStructuredLogging(t *testing.T) { logger.With(context...).Warnw(tt.msg, extra...) logger.With(context...).Errorw(tt.msg, extra...) logger.With(context...).DPanicw(tt.msg, extra...) + logger.With(context...).Logw(WarnLevel, tt.msg, extra...) - expected := make([]observer.LoggedEntry, 5) - for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel} { + expected := make([]observer.LoggedEntry, 6) + for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel, WarnLevel} { expected[i] = observer.LoggedEntry{ Entry: zapcore.Entry{Message: tt.expectMsg, Level: lvl}, Context: expectedFields, @@ -260,9 +344,10 @@ func TestSugarConcatenatingLogging(t *testing.T) { logger.With(context...).Warn(tt.args...) logger.With(context...).Error(tt.args...) logger.With(context...).DPanic(tt.args...) + logger.With(context...).Log(InfoLevel, tt.args...) - expected := make([]observer.LoggedEntry, 5) - for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel} { + expected := make([]observer.LoggedEntry, 6) + for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel, InfoLevel} { expected[i] = observer.LoggedEntry{ Entry: zapcore.Entry{Message: tt.expect, Level: lvl}, Context: expectedFields, @@ -296,9 +381,10 @@ func TestSugarTemplatedLogging(t *testing.T) { logger.With(context...).Warnf(tt.format, tt.args...) logger.With(context...).Errorf(tt.format, tt.args...) logger.With(context...).DPanicf(tt.format, tt.args...) + logger.With(context...).Logf(ErrorLevel, tt.format, tt.args...) - expected := make([]observer.LoggedEntry, 5) - for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel} { + expected := make([]observer.LoggedEntry, 6) + for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel, ErrorLevel} { expected[i] = observer.LoggedEntry{ Entry: zapcore.Entry{Message: tt.expect, Level: lvl}, Context: expectedFields, @@ -332,9 +418,10 @@ func TestSugarLnLogging(t *testing.T) { logger.With(context...).Warnln(tt.args...) logger.With(context...).Errorln(tt.args...) logger.With(context...).DPanicln(tt.args...) + logger.With(context...).Logln(InfoLevel, tt.args...) - expected := make([]observer.LoggedEntry, 5) - for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel} { + expected := make([]observer.LoggedEntry, 6) + for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel, InfoLevel} { expected[i] = observer.LoggedEntry{ Entry: zapcore.Entry{Message: tt.expect, Level: lvl}, Context: expectedFields, diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/time.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/time.go index c5a1f16..c5a1f16 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/time.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/time.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/time_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/time_test.go index cb993ab..cb993ab 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/time_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/time_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/writer.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/writer.go index f08728e..06768c6 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/writer.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/writer.go @@ -48,21 +48,21 @@ import ( // os.Stdout and os.Stderr. When specified without a scheme, relative file // paths also work. func Open(paths ...string) (zapcore.WriteSyncer, func(), error) { - writers, close, err := open(paths) + writers, closeAll, err := open(paths) if err != nil { return nil, nil, err } writer := CombineWriteSyncers(writers...) - return writer, close, nil + return writer, closeAll, nil } func open(paths []string) ([]zapcore.WriteSyncer, func(), error) { writers := make([]zapcore.WriteSyncer, 0, len(paths)) closers := make([]io.Closer, 0, len(paths)) - close := func() { + closeAll := func() { for _, c := range closers { - c.Close() + _ = c.Close() } } @@ -77,11 +77,11 @@ func open(paths []string) ([]zapcore.WriteSyncer, func(), error) { closers = append(closers, sink) } if openErr != nil { - close() + closeAll() return nil, nil, openErr } - return writers, close, nil + return writers, closeAll, nil } // CombineWriteSyncers is a utility that combines multiple WriteSyncers into a diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/writer_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/writer_test.go index b743455..20e00b7 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/writer_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/writer_test.go @@ -91,7 +91,6 @@ func TestOpen(t *testing.T) { } assert.True(t, fileExists(tempName)) - os.Remove(tempName) } func TestOpenPathsNotFound(t *testing.T) { @@ -255,7 +254,8 @@ func TestOpenWithErroringSinkFactory(t *testing.T) { func TestCombineWriteSyncers(t *testing.T) { tw := &testWriter{"test", t} w := CombineWriteSyncers(tw) - w.Write([]byte("test")) + _, err := w.Write([]byte("test")) + assert.NoError(t, err, "Unexpected write error.") } func fileExists(name string) bool { diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/buffered_write_syncer.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/buffered_write_syncer.go index a40e93b..a40e93b 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/buffered_write_syncer.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/buffered_write_syncer.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/buffered_write_syncer_bench_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/buffered_write_syncer_bench_test.go index 1e3db59..56ad5f2 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/buffered_write_syncer_bench_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/buffered_write_syncer_bench_test.go @@ -40,11 +40,15 @@ func BenchmarkBufferedWriteSyncer(b *testing.B) { w := &BufferedWriteSyncer{ WS: AddSync(file), } - defer w.Stop() + defer func() { + assert.NoError(b, w.Stop(), "failed to stop buffered write syncer") + }() b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { - w.Write([]byte("foobarbazbabble")) + if _, err := w.Write([]byte("foobarbazbabble")); err != nil { + b.Fatal(err) + } } }) }) diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/buffered_write_syncer_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/buffered_write_syncer_test.go index 8a36ad6..d0f6037 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/buffered_write_syncer_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/buffered_write_syncer_test.go @@ -101,7 +101,8 @@ func TestBufferWriter(t *testing.T) { n, err := ws.Write([]byte("foo")) require.NoError(t, err, "Unexpected error writing to WriteSyncer.") require.Equal(t, 3, n, "Wrote an unexpected number of bytes.") - ws.Write([]byte("foo")) + _, err = ws.Write([]byte("foo")) + assert.Error(t, err, "Expected error writing to WriteSyncer.") assert.Error(t, ws.Stop(), "Expected stop to fail.") }) diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/clock.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/clock.go index 422fd82..422fd82 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/clock.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/clock.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/clock_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/clock_test.go index 0dff349..0dff349 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/clock_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/clock_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/console_encoder.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/console_encoder.go index 8ca0bfa..cc2b4e0 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/console_encoder.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/console_encoder.go @@ -77,7 +77,7 @@ func (c consoleEncoder) EncodeEntry(ent Entry, fields []Field) (*buffer.Buffer, // If this ever becomes a performance bottleneck, we can implement // ArrayEncoder for our plain-text format. arr := getSliceEncoder() - if c.TimeKey != "" && c.EncodeTime != nil { + if c.TimeKey != "" && c.EncodeTime != nil && !ent.Time.IsZero() { c.EncodeTime(ent.Time, arr) } if c.LevelKey != "" && c.EncodeLevel != nil { diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/console_encoder_bench_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/console_encoder_bench_test.go index 62feaea..a2a360f 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/console_encoder_bench_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/console_encoder_bench_test.go @@ -23,6 +23,7 @@ package zapcore_test import ( "testing" + //revive:disable:dot-imports . "go.uber.org/zap/zapcore" ) diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/console_encoder_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/console_encoder_test.go index b03f1a7..be8adc7 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/console_encoder_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/console_encoder_test.go @@ -21,21 +21,65 @@ package zapcore_test import ( "testing" + "time" "github.com/stretchr/testify/assert" + //revive:disable:dot-imports . "go.uber.org/zap/zapcore" ) -var ( - testEntry = Entry{ - LoggerName: "main", - Level: InfoLevel, - Message: `hello`, - Time: _epoch, - Stack: "fake-stack", - Caller: EntryCaller{Defined: true, File: "foo.go", Line: 42, Function: "foo.Foo"}, +var testEntry = Entry{ + LoggerName: "main", + Level: InfoLevel, + Message: `hello`, + Time: _epoch, + Stack: "fake-stack", + Caller: EntryCaller{Defined: true, File: "foo.go", Line: 42, Function: "foo.Foo"}, +} + +func TestConsoleEncodeEntry(t *testing.T) { + tests := []struct { + desc string + expected string + ent Entry + fields []Field + }{ + { + desc: "info no fields", + expected: "2018-06-19T16:33:42Z\tinfo\tbob\tlob law\n", + ent: Entry{ + Level: InfoLevel, + Time: time.Date(2018, 6, 19, 16, 33, 42, 99, time.UTC), + LoggerName: "bob", + Message: "lob law", + }, + }, + { + desc: "zero_time_omitted", + expected: "info\tname\tmessage\n", + ent: Entry{ + Level: InfoLevel, + Time: time.Time{}, + LoggerName: "name", + Message: "message", + }, + }, } -) + + cfg := testEncoderConfig() + cfg.EncodeTime = RFC3339TimeEncoder + enc := NewConsoleEncoder(cfg) + + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + buf, err := enc.EncodeEntry(tt.ent, tt.fields) + if assert.NoError(t, err, "Unexpected console encoding error.") { + assert.Equal(t, tt.expected, buf.String(), "Incorrect encoded entry.") + } + buf.Free() + }) + } +} func TestConsoleSeparator(t *testing.T) { tests := []struct { diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/core.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/core.go index 9dfd640..776e93f 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/core.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/core.go @@ -102,9 +102,9 @@ func (c *ioCore) Write(ent Entry, fields []Field) error { return err } if ent.Level > ErrorLevel { - // Since we may be crashing the program, sync the output. Ignore Sync - // errors, pending a clean solution to issue #370. - c.Sync() + // Since we may be crashing the program, sync the output. + // Ignore Sync errors, pending a clean solution to issue #370. + _ = c.Sync() } return nil } diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/core_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/core_test.go index 1311097..3b23d2d 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/core_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/core_test.go @@ -27,6 +27,7 @@ import ( "time" "go.uber.org/zap/internal/ztest" + //revive:disable:dot-imports . "go.uber.org/zap/zapcore" "github.com/stretchr/testify/assert" @@ -148,7 +149,7 @@ func TestIOCoreSyncsOutput(t *testing.T) { DebugLevel, ) - core.Write(tt.entry, nil) + assert.NoError(t, core.Write(tt.entry, nil), "Unexpected error writing entry.") assert.Equal(t, tt.shouldSync, sink.Called(), "Incorrect Sync behavior.") } } diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/doc.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/doc.go index 31000e9..31000e9 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/doc.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/doc.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/encoder.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/encoder.go index 5769ff3..0446254 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/encoder.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/encoder.go @@ -37,6 +37,9 @@ const DefaultLineEnding = "\n" const OmitKey = "" // A LevelEncoder serializes a Level to a primitive type. +// +// This function must make exactly one call +// to a PrimitiveArrayEncoder's Append* method. type LevelEncoder func(Level, PrimitiveArrayEncoder) // LowercaseLevelEncoder serializes a Level to a lowercase string. For example, @@ -90,6 +93,9 @@ func (e *LevelEncoder) UnmarshalText(text []byte) error { } // A TimeEncoder serializes a time.Time to a primitive type. +// +// This function must make exactly one call +// to a PrimitiveArrayEncoder's Append* method. type TimeEncoder func(time.Time, PrimitiveArrayEncoder) // EpochTimeEncoder serializes a time.Time to a floating-point number of seconds @@ -219,6 +225,9 @@ func (e *TimeEncoder) UnmarshalJSON(data []byte) error { } // A DurationEncoder serializes a time.Duration to a primitive type. +// +// This function must make exactly one call +// to a PrimitiveArrayEncoder's Append* method. type DurationEncoder func(time.Duration, PrimitiveArrayEncoder) // SecondsDurationEncoder serializes a time.Duration to a floating-point number of seconds elapsed. @@ -262,6 +271,9 @@ func (e *DurationEncoder) UnmarshalText(text []byte) error { } // A CallerEncoder serializes an EntryCaller to a primitive type. +// +// This function must make exactly one call +// to a PrimitiveArrayEncoder's Append* method. type CallerEncoder func(EntryCaller, PrimitiveArrayEncoder) // FullCallerEncoder serializes a caller in /full/path/to/package/file:line @@ -292,6 +304,9 @@ func (e *CallerEncoder) UnmarshalText(text []byte) error { // A NameEncoder serializes a period-separated logger name to a primitive // type. +// +// This function must make exactly one call +// to a PrimitiveArrayEncoder's Append* method. type NameEncoder func(string, PrimitiveArrayEncoder) // FullNameEncoder serializes the logger name as-is. diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/encoder_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/encoder_test.go index c0dbc5b..f89f489 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/encoder_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/encoder_test.go @@ -30,6 +30,7 @@ import ( "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" + //revive:disable:dot-imports . "go.uber.org/zap/zapcore" ) @@ -285,10 +286,11 @@ func TestEncoderConfiguration(t *testing.T) { }, extra: func(enc Encoder) { enc.AddTime("extra", _epoch) - enc.AddArray("extras", ArrayMarshalerFunc(func(enc ArrayEncoder) error { + err := enc.AddArray("extras", ArrayMarshalerFunc(func(enc ArrayEncoder) error { enc.AppendTime(_epoch) return nil })) + assert.NoError(t, err) }, expectedJSON: `{"L":"info","T":"1970-01-01 00:00:00 +0000 UTC","N":"main","C":"foo.go:42","F":"foo.Foo","M":"hello","extra":"1970-01-01 00:00:00 +0000 UTC","extras":["1970-01-01 00:00:00 +0000 UTC"],"S":"fake-stack"}` + "\n", expectedConsole: "1970-01-01 00:00:00 +0000 UTC\tinfo\tmain\tfoo.go:42\tfoo.Foo\thello\t" + // plain-text preamble @@ -313,10 +315,11 @@ func TestEncoderConfiguration(t *testing.T) { }, extra: func(enc Encoder) { enc.AddDuration("extra", time.Second) - enc.AddArray("extras", ArrayMarshalerFunc(func(enc ArrayEncoder) error { + err := enc.AddArray("extras", ArrayMarshalerFunc(func(enc ArrayEncoder) error { enc.AppendDuration(time.Minute) return nil })) + assert.NoError(t, err) }, expectedJSON: `{"L":"info","T":0,"N":"main","C":"foo.go:42","F":"foo.Foo","M":"hello","extra":"1s","extras":["1m0s"],"S":"fake-stack"}` + "\n", expectedConsole: "0\tinfo\tmain\tfoo.go:42\tfoo.Foo\thello\t" + // preamble @@ -720,10 +723,11 @@ func TestNameEncoders(t *testing.T) { func assertAppended(t testing.TB, expected interface{}, f func(ArrayEncoder), msgAndArgs ...interface{}) { mem := NewMapObjectEncoder() - mem.AddArray("k", ArrayMarshalerFunc(func(arr ArrayEncoder) error { + err := mem.AddArray("k", ArrayMarshalerFunc(func(arr ArrayEncoder) error { f(arr) return nil })) + assert.NoError(t, err, msgAndArgs...) arr := mem.Fields["k"].([]interface{}) require.Equal(t, 1, len(arr), "Expected to append exactly one element to array.") assert.Equal(t, expected, arr[0], msgAndArgs...) diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/entry.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/entry.go index 059844f..459a5d7 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/entry.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/entry.go @@ -242,7 +242,7 @@ func (ce *CheckedEntry) Write(fields ...Field) { // CheckedEntry is being used after it was returned to the pool, // the message may be an amalgamation from multiple call sites. fmt.Fprintf(ce.ErrorOutput, "%v Unsafe CheckedEntry re-use near Entry %+v.\n", ce.Time, ce.Entry) - ce.ErrorOutput.Sync() + _ = ce.ErrorOutput.Sync() // ignore error } return } @@ -254,7 +254,7 @@ func (ce *CheckedEntry) Write(fields ...Field) { } if err != nil && ce.ErrorOutput != nil { fmt.Fprintf(ce.ErrorOutput, "%v write error: %v\n", ce.Time, err) - ce.ErrorOutput.Sync() + _ = ce.ErrorOutput.Sync() // ignore error } hook := ce.after diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/entry_ext_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/entry_ext_test.go new file mode 100644 index 0000000..fd1a05c --- /dev/null +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/entry_ext_test.go @@ -0,0 +1,55 @@ +// Copyright (c) 2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package zapcore_test + +import ( + "bytes" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest" +) + +func TestCheckedEntryIllegalReuse(t *testing.T) { + t.Parallel() + + var errOut bytes.Buffer + + testCore := zaptest.NewLogger(t).Core() + ce := testCore.Check(zapcore.Entry{ + Level: zapcore.InfoLevel, + Time: time.Now(), + Message: "hello", + }, nil) + ce.ErrorOutput = zapcore.AddSync(&errOut) + + // The first write should succeed. + ce.Write(zap.String("k", "v"), zap.Int("n", 42)) + assert.Empty(t, errOut.String(), "Expected no errors on first write.") + + // The second write should fail. + ce.Write(zap.String("foo", "bar"), zap.Int("x", 1)) + assert.Contains(t, errOut.String(), "Unsafe CheckedEntry re-use near Entry", + "Expected error logged on second write.") +} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/entry_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/entry_test.go index 6555ab6..6555ab6 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/entry_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/entry_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/error.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/error.go index c67dd71..c40df13 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/error.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/error.go @@ -98,8 +98,11 @@ func (errs errArray) MarshalLogArray(arr ArrayEncoder) error { } el := newErrArrayElem(errs[i]) - arr.AppendObject(el) + err := arr.AppendObject(el) el.Free() + if err != nil { + return err + } } return nil } diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/error_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/error_test.go index d8263ab..41f243a 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/error_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/error_test.go @@ -29,6 +29,7 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/multierr" + //revive:disable:dot-imports . "go.uber.org/zap/zapcore" ) @@ -161,3 +162,49 @@ func TestRichErrorSupport(t *testing.T) { f.AddTo(enc) assert.Equal(t, "failed: egad", enc.Fields["k"], "Unexpected basic error message.") } + +func TestErrArrayBrokenEncoder(t *testing.T) { + t.Parallel() + + f := Field{ + Key: "foo", + Type: ErrorType, + Interface: multierr.Combine( + errors.New("foo"), + errors.New("bar"), + ), + } + + failWith := errors.New("great sadness") + enc := NewMapObjectEncoder() + f.AddTo(brokenArrayObjectEncoder{ + Err: failWith, + ObjectEncoder: enc, + }) + + // Failure to add the field to the encoder + // causes the error to be added as a string field. + assert.Equal(t, "great sadness", enc.Fields["fooError"], + "Unexpected error message.") +} + +// brokenArrayObjectEncoder is an ObjectEncoder +// that builds a broken ArrayEncoder. +type brokenArrayObjectEncoder struct { + ObjectEncoder + ArrayEncoder + + Err error // error to return +} + +func (enc brokenArrayObjectEncoder) AddArray(key string, marshaler ArrayMarshaler) error { + return enc.ObjectEncoder.AddArray(key, + ArrayMarshalerFunc(func(ae ArrayEncoder) error { + enc.ArrayEncoder = ae + return marshaler.MarshalLogArray(enc) + })) +} + +func (enc brokenArrayObjectEncoder) AppendObject(ObjectMarshaler) error { + return enc.Err +} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/field.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/field.go index 95bdb0a..308c978 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/field.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/field.go @@ -47,7 +47,7 @@ const ( ByteStringType // Complex128Type indicates that the field carries a complex128. Complex128Type - // Complex64Type indicates that the field carries a complex128. + // Complex64Type indicates that the field carries a complex64. Complex64Type // DurationType indicates that the field carries a time.Duration. DurationType diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/field_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/field_test.go index c436329..06bcef2 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/field_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/field_test.go @@ -31,6 +31,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" + + //revive:disable:dot-imports . "go.uber.org/zap/zapcore" ) @@ -88,9 +90,8 @@ type errObj struct { func (eobj *errObj) Error() string { if eobj.kind == 1 { panic("panic in Error() method") - } else { - return eobj.errMsg } + return eobj.errMsg } func TestUnknownFieldType(t *testing.T) { @@ -309,6 +310,16 @@ func TestEquals(t *testing.T) { b: zap.Any("k", map[string]string{"a": "d"}), want: false, }, + { + a: zap.Dict("k", zap.String("a", "b")), + b: zap.Dict("k", zap.String("a", "b")), + want: true, + }, + { + a: zap.Dict("k", zap.String("a", "b")), + b: zap.Dict("k", zap.String("a", "d")), + want: false, + }, } for _, tt := range tests { diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/hook.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/hook.go index 198def9..198def9 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/hook.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/hook.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/hook_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/hook_test.go index 46e3c35..360b222 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/hook_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/hook_test.go @@ -23,6 +23,7 @@ package zapcore_test import ( "testing" + //revive:disable:dot-imports . "go.uber.org/zap/zapcore" "go.uber.org/zap/zaptest/observer" diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/increase_level.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/increase_level.go index 7a11237..7a11237 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/increase_level.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/increase_level.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/increase_level_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/increase_level_test.go index f80d790..14cd857 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/increase_level_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/increase_level_test.go @@ -27,6 +27,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" + + //revive:disable:dot-imports . "go.uber.org/zap/zapcore" "go.uber.org/zap/zaptest/observer" ) diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/json_encoder.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/json_encoder.go index ce6838d..9685169 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/json_encoder.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/json_encoder.go @@ -372,7 +372,7 @@ func (enc *jsonEncoder) EncodeEntry(ent Entry, fields []Field) (*buffer.Buffer, final.AppendString(ent.Level.String()) } } - if final.TimeKey != "" { + if final.TimeKey != "" && !ent.Time.IsZero() { final.AddTime(final.TimeKey, ent.Time) } if ent.LoggerName != "" && final.NameKey != "" { @@ -486,73 +486,98 @@ func (enc *jsonEncoder) appendFloat(val float64, bitSize int) { // Unlike the standard library's encoder, it doesn't attempt to protect the // user from browser vulnerabilities or JSONP-related problems. func (enc *jsonEncoder) safeAddString(s string) { - for i := 0; i < len(s); { - if enc.tryAddRuneSelf(s[i]) { - i++ - continue - } - r, size := utf8.DecodeRuneInString(s[i:]) - if enc.tryAddRuneError(r, size) { - i++ - continue - } - enc.buf.AppendString(s[i : i+size]) - i += size - } + safeAppendStringLike( + (*buffer.Buffer).AppendString, + utf8.DecodeRuneInString, + enc.buf, + s, + ) } // safeAddByteString is no-alloc equivalent of safeAddString(string(s)) for s []byte. func (enc *jsonEncoder) safeAddByteString(s []byte) { + safeAppendStringLike( + (*buffer.Buffer).AppendBytes, + utf8.DecodeRune, + enc.buf, + s, + ) +} + +// safeAppendStringLike is a generic implementation of safeAddString and safeAddByteString. +// It appends a string or byte slice to the buffer, escaping all special characters. +func safeAppendStringLike[S []byte | string]( + // appendTo appends this string-like object to the buffer. + appendTo func(*buffer.Buffer, S), + // decodeRune decodes the next rune from the string-like object + // and returns its value and width in bytes. + decodeRune func(S) (rune, int), + buf *buffer.Buffer, + s S, +) { + // The encoding logic below works by skipping over characters + // that can be safely copied as-is, + // until a character is found that needs special handling. + // At that point, we copy everything we've seen so far, + // and then handle that special character. + // + // last is the index of the last byte that was copied to the buffer. + last := 0 for i := 0; i < len(s); { - if enc.tryAddRuneSelf(s[i]) { + if s[i] >= utf8.RuneSelf { + // Character >= RuneSelf may be part of a multi-byte rune. + // They need to be decoded before we can decide how to handle them. + r, size := decodeRune(s[i:]) + if r != utf8.RuneError || size != 1 { + // No special handling required. + // Skip over this rune and continue. + i += size + continue + } + + // Invalid UTF-8 sequence. + // Replace it with the Unicode replacement character. + appendTo(buf, s[last:i]) + buf.AppendString(`\ufffd`) + i++ - continue - } - r, size := utf8.DecodeRune(s[i:]) - if enc.tryAddRuneError(r, size) { + last = i + } else { + // Character < RuneSelf is a single-byte UTF-8 rune. + if s[i] >= 0x20 && s[i] != '\\' && s[i] != '"' { + // No escaping necessary. + // Skip over this character and continue. + i++ + continue + } + + // This character needs to be escaped. + appendTo(buf, s[last:i]) + switch s[i] { + case '\\', '"': + buf.AppendByte('\\') + buf.AppendByte(s[i]) + case '\n': + buf.AppendByte('\\') + buf.AppendByte('n') + case '\r': + buf.AppendByte('\\') + buf.AppendByte('r') + case '\t': + buf.AppendByte('\\') + buf.AppendByte('t') + default: + // Encode bytes < 0x20, except for the escape sequences above. + buf.AppendString(`\u00`) + buf.AppendByte(_hex[s[i]>>4]) + buf.AppendByte(_hex[s[i]&0xF]) + } + i++ - continue + last = i } - enc.buf.Write(s[i : i+size]) - i += size } -} -// tryAddRuneSelf appends b if it is valid UTF-8 character represented in a single byte. -func (enc *jsonEncoder) tryAddRuneSelf(b byte) bool { - if b >= utf8.RuneSelf { - return false - } - if b >= 0x20 && b != '\\' && b != '"' { - enc.buf.AppendByte(b) - return true - } - switch b { - case '\\', '"': - enc.buf.AppendByte('\\') - enc.buf.AppendByte(b) - case '\n': - enc.buf.AppendByte('\\') - enc.buf.AppendByte('n') - case '\r': - enc.buf.AppendByte('\\') - enc.buf.AppendByte('r') - case '\t': - enc.buf.AppendByte('\\') - enc.buf.AppendByte('t') - default: - // Encode bytes < 0x20, except for the escape sequences above. - enc.buf.AppendString(`\u00`) - enc.buf.AppendByte(_hex[b>>4]) - enc.buf.AppendByte(_hex[b&0xF]) - } - return true -} - -func (enc *jsonEncoder) tryAddRuneError(r rune, size int) bool { - if r == utf8.RuneError && size == 1 { - enc.buf.AppendString(`\ufffd`) - return true - } - return false + // add remaining + appendTo(buf, s[last:]) } diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/json_encoder_bench_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/json_encoder_bench_test.go index bcb5a01..d870e07 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/json_encoder_bench_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/json_encoder_bench_test.go @@ -22,19 +22,24 @@ package zapcore_test import ( "encoding/json" + "fmt" "testing" "time" + //revive:disable:dot-imports . "go.uber.org/zap/zapcore" ) func BenchmarkJSONLogMarshalerFunc(b *testing.B) { for i := 0; i < b.N; i++ { enc := NewJSONEncoder(testEncoderConfig()) - enc.AddObject("nested", ObjectMarshalerFunc(func(enc ObjectEncoder) error { + err := enc.AddObject("nested", ObjectMarshalerFunc(func(enc ObjectEncoder) error { enc.AddInt64("i", int64(i)) return nil })) + if err != nil { + b.Fatal(err) + } } } @@ -48,7 +53,28 @@ func BenchmarkZapJSONFloat32AndComplex64(b *testing.B) { }) } +const _sliceSize = 5000 + +type StringSlice []string + +func (s StringSlice) MarshalLogArray(encoder ArrayEncoder) error { + for _, str := range s { + encoder.AppendString(str) + } + return nil +} + +func generateStringSlice(n int) StringSlice { + output := make(StringSlice, 0, n) + for i := 0; i < n; i++ { + output = append(output, fmt.Sprint("00000000-0000-0000-0000-0000000000", i)) + } + return output +} + func BenchmarkZapJSON(b *testing.B) { + additional := generateStringSlice(_sliceSize) + b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { enc := NewJSONEncoder(testEncoderConfig()) @@ -61,6 +87,7 @@ func BenchmarkZapJSON(b *testing.B) { enc.AddString("string3", "🤔") enc.AddString("string4", "🙊") enc.AddBool("bool", true) + _ = enc.AddArray("test", additional) buf, _ := enc.EncodeEntry(Entry{ Message: "fake", Level: DebugLevel, @@ -72,10 +99,11 @@ func BenchmarkZapJSON(b *testing.B) { func BenchmarkStandardJSON(b *testing.B) { record := struct { - Level string `json:"level"` - Message string `json:"msg"` - Time time.Time `json:"ts"` - Fields map[string]interface{} `json:"fields"` + Level string `json:"level"` + Message string `json:"msg"` + Time time.Time `json:"ts"` + Fields map[string]interface{} `json:"fields"` + Additional StringSlice }{ Level: "debug", Message: "fake", @@ -91,11 +119,14 @@ func BenchmarkStandardJSON(b *testing.B) { "string4": "🙊", "bool": true, }, + Additional: generateStringSlice(_sliceSize), } b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { - json.Marshal(record) + if _, err := json.Marshal(record); err != nil { + b.Fatal(err) + } } }) } diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/json_encoder_impl_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/json_encoder_impl_test.go index fde241f..5f81262 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/json_encoder_impl_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/json_encoder_impl_test.go @@ -29,10 +29,13 @@ import ( "testing" "testing/quick" "time" + "unicode/utf8" + "go.uber.org/zap/buffer" "go.uber.org/zap/internal/bufferpool" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.uber.org/multierr" ) @@ -249,7 +252,7 @@ func TestJSONEncoderObjectFields(t *testing.T) { desc: "object (no nested namespace)", expected: `"obj":{"obj-out":"obj-outside-namespace"},"not-obj":"should-be-outside-obj"`, f: func(e Encoder) { - e.AddObject("obj", maybeNamespace{false}) + assert.NoError(t, e.AddObject("obj", maybeNamespace{false})) e.AddString("not-obj", "should-be-outside-obj") }, }, @@ -257,7 +260,7 @@ func TestJSONEncoderObjectFields(t *testing.T) { desc: "object (with nested namespace)", expected: `"obj":{"obj-out":"obj-outside-namespace","obj-namespace":{"obj-in":"obj-inside-namespace"}},"not-obj":"should-be-outside-obj"`, f: func(e Encoder) { - e.AddObject("obj", maybeNamespace{true}) + assert.NoError(t, e.AddObject("obj", maybeNamespace{true})) e.AddString("not-obj", "should-be-outside-obj") }, }, @@ -265,7 +268,7 @@ func TestJSONEncoderObjectFields(t *testing.T) { desc: "multiple open namespaces", expected: `"k":{"foo":1,"middle":{"foo":2,"inner":{"foo":3}}}`, f: func(e Encoder) { - e.AddObject("k", ObjectMarshalerFunc(func(enc ObjectEncoder) error { + err := e.AddObject("k", ObjectMarshalerFunc(func(enc ObjectEncoder) error { e.AddInt("foo", 1) e.OpenNamespace("middle") e.AddInt("foo", 2) @@ -273,6 +276,7 @@ func TestJSONEncoderObjectFields(t *testing.T) { e.AddInt("foo", 3) return nil })) + assert.NoError(t, err) }, }, } @@ -289,10 +293,11 @@ func TestJSONEncoderTimeFormats(t *testing.T) { f := func(e Encoder) { e.AddTime("k", date) - e.AddArray("a", ArrayMarshalerFunc(func(enc ArrayEncoder) error { + err := e.AddArray("a", ArrayMarshalerFunc(func(enc ArrayEncoder) error { enc.AppendTime(date) return nil })) + assert.NoError(t, err) } tests := []struct { desc string @@ -420,7 +425,7 @@ func TestJSONEncoderArrays(t *testing.T) { desc: "object (no nested namespace) then string", expected: `[{"obj-out":"obj-outside-namespace"},"should-be-outside-obj",{"obj-out":"obj-outside-namespace"},"should-be-outside-obj"]`, f: func(arr ArrayEncoder) { - arr.AppendObject(maybeNamespace{false}) + assert.NoError(t, arr.AppendObject(maybeNamespace{false})) arr.AppendString("should-be-outside-obj") }, }, @@ -428,7 +433,7 @@ func TestJSONEncoderArrays(t *testing.T) { desc: "object (with nested namespace) then string", expected: `[{"obj-out":"obj-outside-namespace","obj-namespace":{"obj-in":"obj-inside-namespace"}},"should-be-outside-obj",{"obj-out":"obj-outside-namespace","obj-namespace":{"obj-in":"obj-inside-namespace"}},"should-be-outside-obj"]`, f: func(arr ArrayEncoder) { - arr.AppendObject(maybeNamespace{true}) + assert.NoError(t, arr.AppendObject(maybeNamespace{true})) arr.AppendString("should-be-outside-obj") }, }, @@ -530,10 +535,13 @@ type turducken struct{} func (t turducken) MarshalLogObject(enc ObjectEncoder) error { return enc.AddArray("ducks", ArrayMarshalerFunc(func(arr ArrayEncoder) error { for i := 0; i < 2; i++ { - arr.AppendObject(ObjectMarshalerFunc(func(inner ObjectEncoder) error { + err := arr.AppendObject(ObjectMarshalerFunc(func(inner ObjectEncoder) error { inner.AddString("in", "chicken") return nil })) + if err != nil { + return err + } } return nil })) @@ -657,3 +665,72 @@ func TestJSONQuick(t *testing.T) { check(asciiRoundTripsCorrectlyString) check(asciiRoundTripsCorrectlyByteString) } + +var _stringLikeCorpus = []string{ + "", + "foo", + "bar", + "a\nb", + "a\tb", + "a\\b", + `a"b`, +} + +func FuzzSafeAppendStringLike_bytes(f *testing.F) { + for _, s := range _stringLikeCorpus { + f.Add([]byte(s)) + } + f.Fuzz(func(t *testing.T, b []byte) { + if !utf8.Valid(b) { + t.Skip() + } + + fuzzSafeAppendStringLike(t, string(b), func(buf *buffer.Buffer) { + safeAppendStringLike( + (*buffer.Buffer).AppendBytes, + utf8.DecodeRune, + buf, + b, + ) + }) + }) +} + +func FuzzSafeAppendStringLike_string(f *testing.F) { + for _, s := range _stringLikeCorpus { + f.Add(s) + } + f.Fuzz(func(t *testing.T, s string) { + if !utf8.ValidString(s) { + t.Skip() + } + + fuzzSafeAppendStringLike(t, s, func(buf *buffer.Buffer) { + safeAppendStringLike( + (*buffer.Buffer).AppendString, + utf8.DecodeRuneInString, + buf, + s, + ) + }) + }) +} + +func fuzzSafeAppendStringLike( + t *testing.T, + want string, + writeString func(*buffer.Buffer), +) { + t.Helper() + + buf := bufferpool.Get() + defer buf.Free() + + buf.AppendByte('"') + writeString(buf) + buf.AppendByte('"') + + var got string + require.NoError(t, json.Unmarshal(buf.Bytes(), &got)) + assert.Equal(t, want, got) +} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/json_encoder_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/json_encoder_test.go index 4c651cf..b215025 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/json_encoder_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/json_encoder_test.go @@ -109,6 +109,20 @@ func TestJSONEncodeEntry(t *testing.T) { }), }, }, + { + desc: "zero_time_omitted", + expected: `{ + "L": "info", + "N": "name", + "M": "message" + }`, + ent: zapcore.Entry{ + Level: zapcore.InfoLevel, + Time: time.Time{}, + LoggerName: "name", + Message: "message", + }, + }, } enc := zapcore.NewJSONEncoder(zapcore.EncoderConfig{ diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/clock.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/lazy_with.go index fe8026d..05288d6 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/internal/ztest/clock.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/lazy_with.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -18,33 +18,37 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -package ztest +package zapcore -import ( - "time" +import "sync" - "github.com/benbjohnson/clock" -) - -// MockClock provides control over the time. -type MockClock struct{ m *clock.Mock } +type lazyWithCore struct { + Core + sync.Once + fields []Field +} -// NewMockClock builds a new mock clock that provides control of time. -func NewMockClock() *MockClock { - return &MockClock{clock.NewMock()} +// NewLazyWith wraps a Core with a "lazy" Core that will only encode fields if +// the logger is written to (or is further chained in a lon-lazy manner). +func NewLazyWith(core Core, fields []Field) Core { + return &lazyWithCore{ + Core: core, + fields: fields, + } } -// Now reports the current time. -func (c *MockClock) Now() time.Time { - return c.m.Now() +func (d *lazyWithCore) initOnce() { + d.Once.Do(func() { + d.Core = d.Core.With(d.fields) + }) } -// NewTicker returns a time.Ticker that ticks at the specified frequency. -func (c *MockClock) NewTicker(d time.Duration) *time.Ticker { - return &time.Ticker{C: c.m.Ticker(d).C} +func (d *lazyWithCore) With(fields []Field) Core { + d.initOnce() + return d.Core.With(fields) } -// Add progresses time by the given duration. -func (c *MockClock) Add(d time.Duration) { - c.m.Add(d) +func (d *lazyWithCore) Check(e Entry, ce *CheckedEntry) *CheckedEntry { + d.initOnce() + return d.Core.Check(e, ce) } diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/lazy_with_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/lazy_with_test.go new file mode 100644 index 0000000..c86b59e --- /dev/null +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/lazy_with_test.go @@ -0,0 +1,154 @@ +// Copyright (c) 2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package zapcore_test + +import ( + "sync/atomic" + "testing" + + "github.com/stretchr/testify/assert" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" +) + +type proxyCore struct { + zapcore.Core + + withCount atomic.Int64 + checkCount atomic.Int64 +} + +func newProxyCore(inner zapcore.Core) *proxyCore { + return &proxyCore{Core: inner} +} + +func (p *proxyCore) With(fields []zapcore.Field) zapcore.Core { + p.withCount.Add(1) + return p.Core.With(fields) +} + +func (p *proxyCore) Check(e zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry { + p.checkCount.Add(1) + return p.Core.Check(e, ce) +} + +func withLazyCore(f func(zapcore.Core, *proxyCore, *observer.ObservedLogs), initialFields ...zapcore.Field) { + infoLogger, infoLogs := observer.New(zapcore.InfoLevel) + proxyCore := newProxyCore(infoLogger) + lazyCore := zapcore.NewLazyWith(proxyCore, initialFields) + f(lazyCore, proxyCore, infoLogs) +} + +func TestLazyCore(t *testing.T) { + tests := []struct { + name string + entries []zapcore.Entry + initialFields []zapcore.Field + withChains [][]zapcore.Field + wantLogs []observer.LoggedEntry + }{ + { + name: "no logging, no with, inner core with never called, inner core check never called", + wantLogs: []observer.LoggedEntry{}, + }, + { + name: "2 logs, 1 dropped, no with, inner core with called once, inner core check never called", + entries: []zapcore.Entry{ + {Level: zapcore.DebugLevel, Message: "log-at-debug"}, + {Level: zapcore.WarnLevel, Message: "log-at-warn"}, + }, + wantLogs: []observer.LoggedEntry{ + { + Entry: zapcore.Entry{ + Level: zapcore.WarnLevel, + Message: "log-at-warn", + }, + Context: []zapcore.Field{}, + }, + }, + }, + { + name: "no logs, 2-chained with, inner core with called once, inner core check never called", + withChains: [][]zapcore.Field{ + {makeInt64Field("a", 11), makeInt64Field("b", 22)}, + {makeInt64Field("c", 33), makeInt64Field("d", 44)}, + }, + wantLogs: []observer.LoggedEntry{}, + }, + { + name: "2 logs, 1 dropped, 2-chained with, inner core with called once, inner core check never called", + entries: []zapcore.Entry{ + {Level: zapcore.DebugLevel, Message: "log-at-debug"}, + {Level: zapcore.WarnLevel, Message: "log-at-warn"}, + }, + withChains: [][]zapcore.Field{ + {makeInt64Field("a", 11), makeInt64Field("b", 22)}, + {makeInt64Field("c", 33), makeInt64Field("d", 44)}, + }, + wantLogs: []observer.LoggedEntry{ + { + Entry: zapcore.Entry{ + Level: zapcore.WarnLevel, + Message: "log-at-warn", + }, + Context: []zapcore.Field{ + makeInt64Field("a", 11), + makeInt64Field("b", 22), + makeInt64Field("c", 33), + makeInt64Field("d", 44), + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + withLazyCore(func(lazy zapcore.Core, proxy *proxyCore, logs *observer.ObservedLogs) { + checkCounts := func(withCount int64, msg string) { + assert.Equal(t, withCount, proxy.withCount.Load(), msg) + } + checkCounts(0, "expected no with calls because the logger is not used yet") + + for _, chain := range tt.withChains { + lazy = lazy.With(chain) + } + if len(tt.withChains) > 0 { + checkCounts(1, "expected with calls because the logger was with-chained") + } else { + checkCounts(0, "expected no with calls because the logger is not used yet") + } + + for _, ent := range tt.entries { + if ce := lazy.Check(ent, nil); ce != nil { + ce.Write() + } + } + if len(tt.entries) > 0 || len(tt.withChains) > 0 { + checkCounts(1, "expected with calls because the logger had entries or with chains") + } else { + checkCounts(0, "expected no with calls because the logger is not used yet") + } + assert.Zero(t, proxy.checkCount.Load(), "expected no check calls because the inner core is copied") + assert.Equal(t, tt.wantLogs, logs.AllUntimed()) + }, tt.initialFields...) + }) + } +} diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/leak_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/leak_test.go index 4ef412e..4ef412e 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/leak_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/leak_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/level.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/level.go index e01a241..e01a241 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/level.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/level.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/level_strings.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/level_strings.go index 7af8dad..7af8dad 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/level_strings.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/level_strings.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/level_strings_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/level_strings_test.go index 14b0bac..14b0bac 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/level_strings_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/level_strings_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/level_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/level_test.go index ab97c98..d8eb962 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/level_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/level_test.go @@ -159,7 +159,7 @@ func TestLevelNils(t *testing.T) { }, "Level(nil).String() should panic") assert.Panics(t, func() { - l.MarshalText() + _, _ = l.MarshalText() // should panic }, "Expected to panic when marshalling a nil level.") err := l.UnmarshalText([]byte("debug")) diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/marshaler.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/marshaler.go index c3c55ba..c3c55ba 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/marshaler.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/marshaler.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/memory_encoder.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/memory_encoder.go index dfead08..dfead08 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/memory_encoder.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/memory_encoder.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/memory_encoder_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/memory_encoder_test.go index 052bdb0..d5f215f 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/memory_encoder_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/memory_encoder_test.go @@ -218,7 +218,7 @@ func TestMapObjectEncoderAdd(t *testing.T) { desc: "object (no nested namespace) then string", f: func(e ObjectEncoder) { e.OpenNamespace("k") - e.AddObject("obj", maybeNamespace{false}) + assert.NoError(t, e.AddObject("obj", maybeNamespace{false})) e.AddString("not-obj", "should-be-outside-obj") }, expected: map[string]interface{}{ @@ -232,7 +232,7 @@ func TestMapObjectEncoderAdd(t *testing.T) { desc: "object (with nested namespace) then string", f: func(e ObjectEncoder) { e.OpenNamespace("k") - e.AddObject("obj", maybeNamespace{true}) + assert.NoError(t, e.AddObject("obj", maybeNamespace{true})) e.AddString("not-obj", "should-be-outside-obj") }, expected: map[string]interface{}{ @@ -255,6 +255,7 @@ func TestMapObjectEncoderAdd(t *testing.T) { }) } } + func TestSliceArrayEncoderAppend(t *testing.T) { tests := []struct { desc string @@ -284,29 +285,33 @@ func TestSliceArrayEncoderAppend(t *testing.T) { {"AppendUint8", func(e ArrayEncoder) { e.AppendUint8(42) }, uint8(42)}, {"AppendUintptr", func(e ArrayEncoder) { e.AppendUintptr(42) }, uintptr(42)}, { - desc: "AppendReflected", - f: func(e ArrayEncoder) { e.AppendReflected(map[string]interface{}{"foo": 5}) }, + desc: "AppendReflected", + f: func(e ArrayEncoder) { + assert.NoError(t, e.AppendReflected(map[string]interface{}{"foo": 5})) + }, expected: map[string]interface{}{"foo": 5}, }, { desc: "AppendArray (arrays of arrays)", f: func(e ArrayEncoder) { - e.AppendArray(ArrayMarshalerFunc(func(inner ArrayEncoder) error { + err := e.AppendArray(ArrayMarshalerFunc(func(inner ArrayEncoder) error { inner.AppendBool(true) inner.AppendBool(false) return nil })) + assert.NoError(t, err) }, expected: []interface{}{true, false}, }, { desc: "object (no nested namespace) then string", f: func(e ArrayEncoder) { - e.AppendArray(ArrayMarshalerFunc(func(inner ArrayEncoder) error { - inner.AppendObject(maybeNamespace{false}) + err := e.AppendArray(ArrayMarshalerFunc(func(inner ArrayEncoder) error { + err := inner.AppendObject(maybeNamespace{false}) inner.AppendString("should-be-outside-obj") - return nil + return err })) + assert.NoError(t, err) }, expected: []interface{}{ map[string]interface{}{ @@ -318,11 +323,12 @@ func TestSliceArrayEncoderAppend(t *testing.T) { { desc: "object (with nested namespace) then string", f: func(e ArrayEncoder) { - e.AppendArray(ArrayMarshalerFunc(func(inner ArrayEncoder) error { - inner.AppendObject(maybeNamespace{true}) + err := e.AppendArray(ArrayMarshalerFunc(func(inner ArrayEncoder) error { + err := inner.AppendObject(maybeNamespace{true}) inner.AppendString("should-be-outside-obj") - return nil + return err })) + assert.NoError(t, err) }, expected: []interface{}{ map[string]interface{}{ diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/reflected_encoder.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/reflected_encoder.go index 8746360..8746360 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/reflected_encoder.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/reflected_encoder.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/sampler.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/sampler.go index b7c093a..b7c093a 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/sampler.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/sampler.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/sampler_bench_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/sampler_bench_test.go index 100e226..1b250cd 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/sampler_bench_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/sampler_bench_test.go @@ -28,6 +28,8 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/zap/internal/ztest" + + //revive:disable:dot-imports . "go.uber.org/zap/zapcore" ) diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/sampler_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/sampler_test.go index df726a2..55b4afa 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/sampler_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/sampler_test.go @@ -29,6 +29,7 @@ import ( "time" "go.uber.org/zap/internal/ztest" + //revive:disable:dot-imports . "go.uber.org/zap/zapcore" "go.uber.org/zap/zaptest/observer" diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/tee.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/tee.go index 9bb32f0..9bb32f0 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/tee.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/tee.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/tee_logger_bench_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/tee_logger_bench_test.go index b30a173..d2fc42b 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/tee_logger_bench_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/tee_logger_bench_test.go @@ -24,6 +24,7 @@ import ( "testing" "go.uber.org/zap/internal/ztest" + //revive:disable:dot-imports . "go.uber.org/zap/zapcore" ) diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/tee_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/tee_test.go index b2b9c9d..f6b14eb 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/tee_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/tee_test.go @@ -25,6 +25,7 @@ import ( "testing" "go.uber.org/zap/internal/ztest" + //revive:disable:dot-imports . "go.uber.org/zap/zapcore" "go.uber.org/zap/zaptest/observer" @@ -120,7 +121,7 @@ func TestTeeWrite(t *testing.T) { debugEntry := Entry{Level: DebugLevel, Message: "log-at-debug"} warnEntry := Entry{Level: WarnLevel, Message: "log-at-warn"} for _, ent := range []Entry{debugEntry, warnEntry} { - tee.Write(ent, nil) + assert.NoError(t, tee.Write(ent, nil)) } for _, logs := range []*observer.ObservedLogs{debugLogs, warnLogs} { diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/write_syncer.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/write_syncer.go index d4a1af3..d4a1af3 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/write_syncer.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/write_syncer.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/write_syncer_bench_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/write_syncer_bench_test.go index db6ec45..90ae475 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/write_syncer_bench_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/write_syncer_bench_test.go @@ -24,6 +24,7 @@ import ( "os" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap/internal/ztest" ) @@ -37,7 +38,9 @@ func BenchmarkMultiWriteSyncer(b *testing.B) { b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { - w.Write([]byte("foobarbazbabble")) + if _, err := w.Write([]byte("foobarbazbabble")); err != nil { + b.Fatal(err) + } } }) }) @@ -51,7 +54,9 @@ func BenchmarkMultiWriteSyncer(b *testing.B) { b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { - w.Write([]byte("foobarbazbabble")) + if _, err := w.Write([]byte("foobarbazbabble")); err != nil { + b.Fatal(err) + } } }) }) @@ -64,11 +69,15 @@ func BenchmarkMultiWriteSyncer(b *testing.B) { &ztest.Discarder{}, ), } - defer w.Stop() + defer func() { + assert.NoError(b, w.Stop(), "Unexpected error stopping buffered write syncer.") + }() b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { - w.Write([]byte("foobarbazbabble")) + if _, err := w.Write([]byte("foobarbazbabble")); err != nil { + b.Fatal(err) + } } }) }) @@ -83,7 +92,9 @@ func BenchmarkWriteSyncer(b *testing.B) { b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { - w.Write([]byte("foobarbazbabble")) + if _, err := w.Write([]byte("foobarbazbabble")); err != nil { + b.Fatal(err) + } } }) }) diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/write_syncer_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/write_syncer_test.go index 4748be7..c0c2698 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapcore/write_syncer_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapcore/write_syncer_test.go @@ -70,7 +70,7 @@ func TestNewMultiWriteSyncerWorksForSingleWriter(t *testing.T) { ws := NewMultiWriteSyncer(w) assert.Equal(t, w, ws, "Expected NewMultiWriteSyncer to return the same WriteSyncer object for a single argument.") - ws.Sync() + assert.NoError(t, ws.Sync(), "Expected Sync to succeed.") assert.True(t, w.Called(), "Expected Sync to be called on the created WriteSyncer") } diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapgrpc/zapgrpc.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapgrpc/zapgrpc.go index 6823773..682de25 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapgrpc/zapgrpc.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapgrpc/zapgrpc.go @@ -36,16 +36,14 @@ const ( grpcLvlFatal ) -var ( - // _grpcToZapLevel maps gRPC log levels to zap log levels. - // See https://pkg.go.dev/go.uber.org/zap@v1.16.0/zapcore#Level - _grpcToZapLevel = map[int]zapcore.Level{ - grpcLvlInfo: zapcore.InfoLevel, - grpcLvlWarn: zapcore.WarnLevel, - grpcLvlError: zapcore.ErrorLevel, - grpcLvlFatal: zapcore.FatalLevel, - } -) +// _grpcToZapLevel maps gRPC log levels to zap log levels. +// See https://pkg.go.dev/go.uber.org/zap@v1.16.0/zapcore#Level +var _grpcToZapLevel = map[int]zapcore.Level{ + grpcLvlInfo: zapcore.InfoLevel, + grpcLvlWarn: zapcore.WarnLevel, + grpcLvlError: zapcore.ErrorLevel, + grpcLvlFatal: zapcore.FatalLevel, +} // An Option overrides a Logger's default configuration. type Option interface { diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapgrpc/zapgrpc_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapgrpc/zapgrpc_test.go index a231d65..a231d65 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapgrpc/zapgrpc_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapgrpc/zapgrpc_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapio/example_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapio/example_test.go index e9565db..e9565db 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapio/example_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapio/example_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapio/writer.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapio/writer.go index a87d910..a87d910 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapio/writer.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapio/writer.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapio/writer_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapio/writer_test.go index 9bdf348..9bdf348 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zapio/writer_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zapio/writer_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/doc.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/doc.go index b377859..b377859 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/doc.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/doc.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/logger.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/logger.go index 6a4a354..4734c33 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/logger.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/logger.go @@ -82,7 +82,7 @@ func NewLogger(t TestingT, opts ...LoggerOption) *zap.Logger { o.applyLoggerOption(&cfg) } - writer := newTestingWriter(t) + writer := NewTestingWriter(t) zapOptions := []zap.Option{ // Send zap errors to the same writer and mark the test as failed if // that happens. @@ -100,27 +100,43 @@ func NewLogger(t TestingT, opts ...LoggerOption) *zap.Logger { ) } -// testingWriter is a WriteSyncer that writes to the given testing.TB. -type testingWriter struct { +// TestingWriter is a WriteSyncer that writes to the given testing.TB. +type TestingWriter struct { t TestingT - // If true, the test will be marked as failed if this testingWriter is + // If true, the test will be marked as failed if this TestingWriter is // ever used. markFailed bool } -func newTestingWriter(t TestingT) testingWriter { - return testingWriter{t: t} +// NewTestingWriter builds a new TestingWriter that writes to the given +// testing.TB. +// +// Use this if you need more flexibility when creating *zap.Logger +// than zaptest.NewLogger() provides. +// +// E.g., if you want to use custom core with zaptest.TestingWriter: +// +// encoder := newCustomEncoder() +// writer := zaptest.NewTestingWriter(t) +// level := zap.NewAtomicLevelAt(zapcore.DebugLevel) +// +// core := newCustomCore(encoder, writer, level) +// +// logger := zap.New(core, zap.AddCaller()) +func NewTestingWriter(t TestingT) TestingWriter { + return TestingWriter{t: t} } -// WithMarkFailed returns a copy of this testingWriter with markFailed set to +// WithMarkFailed returns a copy of this TestingWriter with markFailed set to // the provided value. -func (w testingWriter) WithMarkFailed(v bool) testingWriter { +func (w TestingWriter) WithMarkFailed(v bool) TestingWriter { w.markFailed = v return w } -func (w testingWriter) Write(p []byte) (n int, err error) { +// Write writes bytes from p to the underlying testing.TB. +func (w TestingWriter) Write(p []byte) (n int, err error) { n = len(p) // Strip trailing newline because t.Log always adds one. @@ -135,6 +151,7 @@ func (w testingWriter) Write(p []byte) (n int, err error) { return n, nil } -func (w testingWriter) Sync() error { +// Sync commits the current contents (a no-op for TestingWriter). +func (w TestingWriter) Sync() error { return nil } diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/logger_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/logger_test.go index 576f682..40e368b 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/logger_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/logger_test.go @@ -106,7 +106,7 @@ func TestTestLoggerSupportsWrappedZapOptions(t *testing.T) { func TestTestingWriter(t *testing.T) { ts := newTestLogSpy(t) - w := newTestingWriter(ts) + w := NewTestingWriter(ts) n, err := io.WriteString(w, "hello\n\n") assert.NoError(t, err, "WriteString must not fail") diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/observer/logged_entry.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/observer/logged_entry.go index a4ea7ec..a4ea7ec 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/observer/logged_entry.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/observer/logged_entry.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/observer/logged_entry_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/observer/logged_entry_test.go index 50f6123..50f6123 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/observer/logged_entry_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/observer/logged_entry_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/observer/observer.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/observer/observer.go index f77f130..f77f130 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/observer/observer.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/observer/observer.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/observer/observer_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/observer/observer_test.go index 2a901b1..0cf631c 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/observer/observer_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/observer/observer_test.go @@ -29,6 +29,8 @@ import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" + + //revive:disable:dot-imports . "go.uber.org/zap/zaptest/observer" ) @@ -173,7 +175,7 @@ func TestFilters(t *testing.T) { logger, sink := New(zap.InfoLevel) for _, log := range logs { - logger.Write(log.Entry, log.Context) + assert.NoError(t, logger.Write(log.Entry, log.Context), "Unexpected error writing log entry.") } tests := []struct { diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/testingt.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/testingt.go index 792463b..792463b 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/testingt.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/testingt.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/testingt_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/testingt_test.go index d847796..d847796 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/testingt_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/testingt_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/timeout.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/timeout.go index f0be444..f0be444 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/timeout.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/timeout.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/timeout_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/timeout_test.go index 3962ecd..3962ecd 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/timeout_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/timeout_test.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/writer.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/writer.go index 4b772f8..4b772f8 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/writer.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/writer.go diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/writer_test.go b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/writer_test.go index c18f18a..c18f18a 100644 --- a/dependencies/pkg/mod/go.uber.org/zap@v1.25.0/zaptest/writer_test.go +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.27.0/zaptest/writer_test.go |