在 log4j2 中启用 LZMA(2)(即 `.xz`)压缩

Posted

技术标签:

【中文标题】在 log4j2 中启用 LZMA(2)(即 `.xz`)压缩【英文标题】:Enabling LZMA(2) (i.e. `.xz`) compression in log4j2 【发布时间】:2016-04-18 13:36:22 【问题描述】:

世界现状

目前log4j2.xml中的RollingFileAppender使用Gzip压缩:

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

目标

我想切换到 LZMA(2)(即.xz)压缩,以享受更高的压缩比。

尝试

我已尝试将 engine.log.%i.gz 更改为 engine.log.%i.xz — 根据 the documentation:

如果文件模式以 .gz.zip.bz2.deflate.pack200.xz 结尾,则生成的存档将使用与后缀匹配的压缩方案进行压缩。 bzip2、Deflate、Pack200 和 XZ 格式需要 Apache Commons Compress。另外,XZ需要XZ for Java。

此外,我已确保我对 XZ for Java 具有运行时依赖项——通过 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>

结果

当 RollingFileAppender 被触发时:创建的档案确实是命名 engines.log.1.xz — 根据需要。

然而,其内容不正确:

期待

engines.log.1.xz 应该包含 LZMA(2) 压缩文本

实际

engines.log.1.xz 包含纯文本,未压缩。

健全性检查

我确认org.tukaani:xzorg.apache.commons:commons-compress 已成功进入我的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/
…

此 Java 程序未部署到 J2EE 网络服务器。我相信它的类加载很简单。

总结

我已正确遵循创建.gz 档案所需的说明。

我相信创建.xz 档案所需的唯一额外步骤是:我必须在运行时提供XZ for Java 人工制品。我已经这样做了。

我在这里遗漏了什么吗?我很想相信以下其中一项:

功能已损坏 文档不完整/不正确 log4j2 无法在运行时发现类

【问题讨论】:

我找到了some evidence,也许我应该输入.xy而不是.xz。如果我使用.xy:log4j2 RollingAppender fails 生成档案。即:它创建空白的.xy 文件,并将未归档的明文保留为.log 文件。它闻起来像一个错误的实现。 这是我提供的来自org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy的代码:static enum FileExtensions XY(".xy") @Override Action createCompressAction(final String renameTo, final String compressedName, final boolean deleteSource, final int compressionLevel) // One of "gz", "bzip2", "xz", "pack200", or "deflate". return new CommonsCompressAction("xy", source(renameTo), target(compressedName), deleteSource); Issue raised with Apache to track this — 假设它确实是一个错误。 +10。这是一个错误,将在下一个版本中解决。感谢您提出这个问题! 【参考方案1】:

Remko Popma confirmed that this is a bug:

log4j-core 仅接受 *.xy 作为匹配模式 — 而文档建议 *.xz 是必需的输入。 "xy" 被传递到 new CommonsCompressAction(…) 而不是必需的 "xz"

这些都被认为是拼写错误:提议的解决方案是将两者都更改为xz

Gary Gregory wrote a fix。该修复程序目前位于 org.apache.logging.log4j:log4j-core:2.6-SNAPSHOTmaster 中,因此应与 2.6 一起发布。

【讨论】:

以上是关于在 log4j2 中启用 LZMA(2)(即 `.xz`)压缩的主要内容,如果未能解决你的问题,请参考以下文章

重新创建的 LZMA 在 332 字节后与原始 LZMA 不同 - 可能吗?

log4j2:包含PID

mac环境 python3.7 lzma.py 报错解决

第八周总结

Apache Log4j2远程代码执行漏洞处理

lzma解压