Repository navigation
Conversation
ramanathan1504
left a comment
There was a problem hiding this comment.
Thanks @katstack, the write-up on why -1 has to stay the zstd default is clear, and the FileExtension mapping has a test.
FileExtension.ZSTD now loads ZstdConstants and the constructor checks the range while the rollover is being built, so compressionLevel="0" or a missing zstd-jni jar stops the rollover and every later log event is dropped. Can the level check stay inside execute(), so those cases only fail the compression like on 2.x, and can you add a src/changelog/.2.x.x entry?
|
|
Addressed in 892c912. |
|
@ppkarwasz |
|
Hi @katstack, Thank you for the PR. As @ramanathan1504 mentioned, we are considering removing That said, the attribute exists today, so we might as well honor it wherever we can. ZStandard is not the only algorithm with a compression level: Deflate, GZip and BZip2 support one too. We prefer to change a whole class of implementations at once rather than a single one, so users get consistent behavior and the change can be properly described in the release notes. Would you be willing to extend the PR to the other three algorithms? Two remarks on the implementation:
TL;DR: moving |
|
Hi @ppkarwasz, thank you for the detailed feedback. Our use case is an air-gapped bare-metal environment where local disk capacity is constrained, while CPU headroom is available during rollover. The customer requirement is to retain application logs locally for as long as possible, so trading additional rollover CPU time for a better compression ratio is valuable. For a representative, highly repetitive application-log workload, we observed that Zstd level 9 reduced the archive to roughly 1% of the original size. This is workload-specific rather than a general Zstd result, but it illustrates why operators need to tune the CPU/compression-ratio trade-off instead of always using a fixed default. I will move |
ramanathan1504
left a comment
There was a problem hiding this comment.
Thanks, this is a much better shape: one copy loop in CompressActionSupport, the action out of the exported package, and the new RollingFileManagerTest case pins that a bad level only fails the async compression.
That case is parameterized over bz2 and deflate only. Adding gz and zip to it fails, because GzCompressAction and ZipCompressAction still check the level in their constructors, which run inside the rollover, so those two still lose the log event. Could they move onto AbstractCompressAction too, and could you merge current 2.x so log4j-api-test goes green again?
|
@ramanathan1504 Before I make another code change, could we agree on the semantics for unsupported
I would prefer to avoid format-specific coercions. Zstd would be the only explicit mapping: its native With this approach, BZip2 level Does that match the intended contract for the shared |
|
That contract looks right, and it matches |
|
Hi @ppkarwasz, could you share your thoughts on the proposed fallback behavior for unsupported compression levels? Is there anything else you’d like me to clarify before I proceed with the implementation? Thanks! |
|
@katstack let's go with your table. That contract is fine and it matches what |
…odex/compression-level-default-fallback
Regarding the fallback behavior, it looks like a good idea, although we could probably validate the value sooner, when Regarding the mapping of |
Using Integer.MIN_VALUE to distinguish an unspecified level makes sense to me. I've applied that along with the other changes you suggested. |
|
I would still move all the implementations of Otherwise this looks good to merge. |
|
@ppkarwasz, done. The implementations are in |
|
Looks good to me, thanks! |
ramanathan1504
left a comment
There was a problem hiding this comment.
The eager resolution caches per format so the warning lands once, the fallback keeps the rollover alive for every unsupported level, and the deprecated shims leave the exported surface unchanged against 2.26.1.
Two changelog entries run to two sentences; one line each reads better, and main already has rolling/action/internal, so this lines the two branches up. Approving with that nit.
Co-authored-by: Ramanathan Muthu <ramanathanbscmca@gmail.com>
Head branch was pushed to by a user without write access
|
Applied the changelog suggestions from @ramanathan1504. @ppkarwasz, could you approve the workflows and merge once CI is green? Thanks! |
This PR adds
ZstdCompressAction, replacing the genericCommonsCompressAction("zstd", ...)path (added in #1514) with a dedicated action that supports a configurablecompressionLevel, following the same incremental pattern already used byGzCompressAction(LOG4J2-2598) andZipCompressAction.Supported range is the standard positive Zstd levels
[1, ZstdConstants.ZSTD_CLEVEL_MAX](currently[1, 22]).compressionLevel=-1(unset) continues to resolve to the Zstd default level (3), consistent with the existing behavior documented inFileExtension/rolling-file.adoc.What this PR deliberately does not do
Negative ("fast compression") Zstd levels are not supported. The rolling-appender framework uses
Deflater.DEFAULT_COMPRESSION(-1) as a format-agnostic sentinel for "unspecified compression level," so an explicitcompressionLevel=-1would be indistinguishable from "not set." Onmain,compressionLevelhas already been replaced by a more genericcompressionOptionsmap (#2921); on2.xit remains the mechanism, so this PR stays scoped to extending it rather than adding another special case on top of the sentinel.Testing
ZstdCompressActionTestcovers the new validation/mapping logic, including a test pinning the currently-assumedZstdConstantsbounds so a future zstd-jni/commons-compress upgrade that shifts them fails loudly instead of silently drifting from the documented range. Also ran the existingGzCompressActionTest/ZipCompressActionTest/Bzip2CompressActionTest/rolling-appender suites locally with no regressions, and./mvnw verifypasses on both JDK 8 and JDK 17.References