Birchlabs
Birchlabs

Reputation: 8066

Enabling LZMA(2) (i.e. `.xz`) compression in log4j2

Current state of world

Currently our RollingFileAppender in log4j2.xml uses Gzip compression:

<RollingFile name="RollingFile"
             fileName="logs/engine.log"
             filePattern="logs/engine.log.%i.gz">

Goal

I would like to switch to LZMA(2) (i.e. .xz) compression, to enjoy an improved compression ratio.

Attempt

I have tried changing engine.log.%i.gz to engine.log.%i.xz — as per the documentation:

If the file pattern ends with .gz, .zip, .bz2, .deflate, .pack200, or .xz the resulting archive will be compressed using the compression scheme that matches the suffix. The formats bzip2, Deflate, Pack200 and XZ require Apache Commons Compress. In addition, XZ requires XZ for Java.

Additionally I have ensured that I have a runtime dependency on XZ for Java — via pom.xml:

<dependency>
    <!-- Support Log4j2 Log compression schemes: ".gz", ".zip", ".bz2", ".deflate", ".pack200", [".xz" (part 1 of 2)] -->
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>1.11</version>
</dependency>
<dependency>
    <!-- Support Log4j2 Log compression scheme [".xz" (part 2 of 2)] -->
    <groupId>org.tukaani</groupId>
    <artifactId>xz</artifactId>
    <version>1.5</version>
</dependency>

Result

When the RollingFileAppender is triggered: the archive created is indeed named engines.log.1.xz — as required.

However, its contents are incorrect:

Expectation

engines.log.1.xz should contain LZMA(2) compressed text

Actual

engines.log.1.xz instead contains plain, uncompressed text.

Sanity checks

I confirm that the org.tukaani:xz and org.apache.commons:commons-compress successfully made it into the classpath of my jar:

🍔 jar tf mycooljar.jar | grep tukaani
org/tukaani/
org/tukaani/xz/
…

🍔 jar tf mycooljar.jar | grep org/apache/commons/compress
org/apache/commons/compress/
org/apache/commons/compress/changes/
…

This Java program is not deployed to a J2EE webserver. I believe its class loading is straightforward.

Summary

I have correctly followed the instructions necessary to create .gz archives.

I believe the only additional step required to create .xz archives is: I must provide at runtime the XZ for Java artefact. I have done this.

Am I missing something here? I am tempted to believe one of the following:

Upvotes: 3

Views: 1062

Answers (1)

Birchlabs
Birchlabs

Reputation: 8066

Remko Popma confirmed that this is a bug:

  • log4j-core accepted only *.xy as a matching pattern — whereas the docs suggested that *.xz was the required input.
  • "xy" was being passed into new CommonsCompressAction(…) instead of the required "xz".

These were both presumed to be typos: the proposed resolution was to change both to xz.

Gary Gregory wrote a fix. The fix is presently in master of org.apache.logging.log4j:log4j-core:2.6-SNAPSHOT, so should release with 2.6.

Upvotes: 2

Related Questions