Is your feature request related to a problem? Please describe.
Zap’s current encoders (JSON, console) don’t provide an easy-to-read text output for nested objects:
- JSONEncoder is structured but verbose and less operator-friendly for quick inspection in terminals.
- ConsoleEncoder is compact but does not handle nested objects in a way that makes them easy to grep or read.
- Alternatives like Kubernetes’ klog textlogger and Go’s slog.TextHandler provide text output, but are either slower or less flexible.
Describe the solution you'd like
Introduce a new zapcore.Encoder implementation (e.g., TextEncoder) with the following features:
-
Dot-flattened keys for nested objects
Example:
logger.Info("user created", zap.Any("user", User{
Name: "Alice",
Addr: Addr{City: "Bangalore", Zip: "560001"},
}))
Current JSONEncoder output:
{"user": {"Name": "Alice", "Addr": {"City": "Bangalore", "Zip": "560001"}}}
Proposed TextEncoder output:
"user.Name"="Alice" "user.Addr.City"="Bangalore" "user.Addr.Zip"="560001"
This makes logs more human-readable and grep-friendly.
-
Performance improvements
Benchmarks show this encoder is faster than both k8s textlogger and slog.TextHandler, while competitive with zap’s json encoder.
-
Seamless zap integration
- Provided as a
zapcore.Encoder implementation.
- Configurable via
zapcore.NewTextEncoder(cfg) or zap configuration.
Describe alternatives you've considered
- Using JSONEncoder → too verbose and not grep-friendly.
- Using ConsoleEncoder → compact but nested structures are still hard to scan.
- Using Kubernetes’ klog textlogger / slog.TextHandler → slower and not integrated with zap.
Is this a breaking change?
No. This would be an additive change introducing a new encoder.
Existing users of JSONEncoder and ConsoleEncoder remain unaffected.
Additional context
Log a message and 10 fields
(https://github.com/sagarsuperuser/zap/tree/text-encoder#log-a-message-and-10-fields)
| Package |
Time (ns/op) |
Time % vs Zap |
Objects Allocated |
| ⚡ zap (json) |
656 |
+0% |
5 allocs/op |
| ⚡ zap (text) |
852 |
+30% |
5 allocs/op |
| ⚡ zap (sugared json) |
854 |
+30% |
10 allocs/op |
| ⚡ zap (sugared text) |
1071 |
+63% |
10 allocs/op |
| zerolog |
318 |
-52% |
1 alloc/op |
| go-kit |
1989 |
+203% |
56 allocs/op |
| slog |
2122 |
+224% |
41 allocs/op |
| slog (LogAttrs) |
2161 |
+229% |
40 allocs/op |
| apex/log |
10762 |
+1539% |
64 allocs/op |
| log15 |
12049 |
+1736% |
73 allocs/op |
| logrus |
12721 |
+1840% |
84 allocs/op |
| klog/v2 textlogger |
2776 |
+323% |
45 allocs/op |
Example log with nested fields:
(https://github.com/sagarsuperuser/zap/tree/text-encoder?tab=readme-ov-file#example-logging-structured-http-requestresponse-using-text-format)
"level"="info" "ts"=1758088355.259905 "caller"="zap_test/main.go:57" "msg"="served" "http.request.method"="GET" "http.request.url"="/api/v1/users" "http.response.status"=200 "http.response.bytes"=1234
Next Steps
Would the maintainers be open to including this encoder in zap core as an additional zapcore.Encoder implementation?
I can submit a draft PR with tests, benchmarks, and documentation once there’s guidance.
Is your feature request related to a problem? Please describe.
Zap’s current encoders (JSON, console) don’t provide an easy-to-read text output for nested objects:
Describe the solution you'd like
Introduce a new
zapcore.Encoderimplementation (e.g.,TextEncoder) with the following features:Dot-flattened keys for nested objects
Example:
Current JSONEncoder output:
{"user": {"Name": "Alice", "Addr": {"City": "Bangalore", "Zip": "560001"}}}Proposed TextEncoder output:
This makes logs more human-readable and grep-friendly.
Performance improvements
Benchmarks show this encoder is faster than both k8s textlogger and slog.TextHandler, while competitive with zap’s json encoder.
Seamless zap integration
zapcore.Encoderimplementation.zapcore.NewTextEncoder(cfg)or zap configuration.Describe alternatives you've considered
Is this a breaking change?
No. This would be an additive change introducing a new encoder.
Existing users of JSONEncoder and ConsoleEncoder remain unaffected.
Additional context
Log a message and 10 fields
(https://github.com/sagarsuperuser/zap/tree/text-encoder#log-a-message-and-10-fields)
Example log with nested fields:
(https://github.com/sagarsuperuser/zap/tree/text-encoder?tab=readme-ov-file#example-logging-structured-http-requestresponse-using-text-format)
Next Steps
Would the maintainers be open to including this encoder in zap core as an additional zapcore.Encoder implementation?
I can submit a draft PR with tests, benchmarks, and documentation once there’s guidance.