Ubuntu 22.04 安装 Apache Chainsaw 指南
在 Ubuntu 22.04 上从零安装并验证 Apache Chainsaw 2.1.0 日志分析工具的全流程实录,涵盖 standalone 官方包安装、源码 Maven 构建、无显示器环境下 xvfb 虚拟帧缓冲的 GUI 验证与常见问题排障。
Ubuntu 22.04 安装 Apache Chainsaw 指南
目标:在一台 Ubuntu 22.04 服务器上完成 Apache Chainsaw 2.1.0 的下载、安装、启动配置与验证,包括无显示器环境下借助 X 虚拟帧缓冲(xvfb)完成的图形界面真实启动验证,以及不依赖图形界面的 headless 接收器验证。(以下全部命令与回显均来自真实环境实测)
Apache Chainsaw 是 Log4j 生态下的开源日志查看与分析工具(Swing 桌面程序),支持按格式模板解析文本日志文件、通过 UDP/组播/TCP 接收网络日志事件,并内置过滤表达式、颜色规则、事件收藏等分析功能。与常规后端服务不同,Chainsaw 是图形界面程序,安装后"能不能跑"必须通过图形栈验证;在无显示器的服务器上,需要用 xvfb 模拟一块虚拟显示。本文按 0→1 全流程记录每一步的真实命令与回显。
一、环境信息
本文实测所用服务器软硬件信息如下:
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS(x86_64) |
| Java 环境 | OpenJDK 17.0.20.1(apt 仓库 openjdk-17-jdk) |
| Chainsaw 版本 | 2.1.0(2021-06-12 发布,官方当前唯一版本) |
| 安装目录 | /opt/apache-chainsaw-2.1.0 |
| 实验目录 | /opt/chainsaw-headless |
| 图形栈 | Xvfb(虚拟帧缓冲)+ x11-utils(xwininfo/xdpyinfo) |
操作系统与基础环境确认:
cat /etc/os-release | head -3
实测回显:
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
uname -m
实测回显:
x86_64
二、前置条件
- 具备 root 权限或 sudo 免密(安装 JDK、Xvfb 与写 /opt 目录均需要)。
- 服务器可访问 downloads.apache.org(下载官方包)。连通性探测:
curl -sI --max-time 20 https://downloads.apache.org/logging/chainsaw/2.1.0/apache-chainsaw-2.1.0-standalone.tar.gz | head -5
实测回显:
HTTP/1.1 200 OK
Date: Thu, 15 Oct 2026 08:05:34 GMT
Server: Apache
Last-Modified: Sat, 12 Jun 2021 14:20:08 GMT
ETag: "2cf6e2-5c4925249ea69"
- Java 运行时版本要求:JDK 9 及以上。实测依据:官方 jar 的字节码主版本号为 53(Java 9+),主类 MANIFEST 中 Build-Jdk-Spec 为 11(验证方法见第八章)。推荐安装 OpenJDK 11 或 17,本文使用 17:
apt-get install -y openjdk-17-jdk
实测回显(首次安装时会出现下载与解包进度;若已装过则显示如下):
openjdk-17-jdk is already the newest version (17.0.20.1+1-1~22.04).
0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.
java -version
实测回显:
openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)
- 图形栈组件:无显示器的服务器需要 X 虚拟帧缓冲(xvfb)与 x11-utils(提供 xdpyinfo、xwininfo 用于验证):
apt-get install -y xvfb x11-utils
实测回显:
xvfb is already the newest version (2:21.1.4-2ubuntu1.7~22.04.16).
x11-utils is already the newest version (7.7+5build2).
- 磁盘空间约 100 MB(standalone 包 2.9 MB,解压后约 20 MB,加上源码构建缓存预留)。
三、版本选型说明
3.1 官方版本与发布渠道
官方下载目录 https://downloads.apache.org/logging/chainsaw/ 实测仅有 2.1.0 一个版本目录(2021-06-12 发布),包含 bin、standalone、src 三类包及对应的 .sha512 校验文件。本文全部实测基于 2.1.0。
一个重要的实测事实:Chainsaw 2.1.0 没有发布到 Maven Central。以下三个候选坐标在 Maven Central 中实测均不存在(HTTP 404):org.apache.logging.chainsaw:chainsaw、log4j:chainsaw、log4j:apache-chainsaw。因此无法通过 Maven 依赖坐标引入 Chainsaw,只能使用官方二进制包或从源码构建(源码包内 pom.xml 的坐标为 log4j:apache-chainsaw:2.1.0)。
另一个实测事实:Chainsaw 2.1.0 基于 log4j 1.x 生态而非 log4j2。standalone 包内嵌依赖仓库 repo/ 中是 log4j-1.2.16.jar 与 apache-log4j-extras-1.1.jar,根目录平铺 jar 亦同。也就是说,Chainsaw 自带完整的 log4j 1.2.16 运行时与扩展接收器(LogFilePatternReceiver、UDPReceiver 等都在主 jar 内),无需另配依赖。
3.2 三种官方包的差异(实测解包结论)
| 包名 | 大小 | 内容 | 适用场景 |
|---|---|---|---|
| apache-chainsaw-2.1.0-standalone.tar.gz | 2.9 MB | bin/chainsaw 启动脚本、bin/chainsaw.bat、repo/ 内嵌依赖仓库、根目录平铺 jar、src、site | 服务器直接安装运行(官方推荐) |
| apache-chainsaw-2.1.0-bin.tar.gz | 6.0 MB | 根目录平铺 jar、src、site、pom.xml、build.xml;无启动脚本、无 repo/ | 研究源码/二次开发 |
| apache-chainsaw-2.1.0-src.tar.gz | 2.1 MB | 纯源码 + pom.xml + build.xml | 源码构建 |
💡 技术拓展:日志查看/分析工具选型对比
工具 形态 定位 适用场景 Apache Chainsaw Swing GUI log4j 1.x 生态的本地日志接收与交互分析(接收器+过滤+着色) 服务器日志文件解析、网络事件实时分析、无中心化部署 Apache Log4j2 自带 GUI 无独立工具 log4j2 生态下需自研或借助第三方 log4j2 项目配套 tail/grep/awk 命令行 快速检索、即时性强 单文件简单查询,无结构化解析 Kibana Web 平台 ELK 集中式的检索与仪表盘 已建 ELK/EFK 体系的中大型环境 LogExpert/BareTail Windows GUI 本地文件追尾查看 Windows 工作站轻量场景 本文与整个专栏采用 Apache Chainsaw:它可以在不引入任何中心化组件的前提下,直接解析日志文件或接收 UDP/组播事件,在服务器上配合 xvfb 即可完成全部 GUI 功能验证。
四、方案 A:官方 standalone 包安装(推荐)
4.1 下载与完整性校验
cd /root
curl -sO https://downloads.apache.org/logging/chainsaw/2.1.0/apache-chainsaw-2.1.0-standalone.tar.gz
curl -sO https://downloads.apache.org/logging/chainsaw/2.1.0/apache-chainsaw-2.1.0-standalone.tar.gz.sha512
用官方 sha512 与本地文件比对:
sha512sum apache-chainsaw-2.1.0-standalone.tar.gz
实测回显:
1e2131c9e490551b5ec2ed4a9f9885bb28791b8f28585b6d70285e68985238da1c166cb84aac4a9b9d9acfa72e184b268bd1540875aad3de525a65acaf4ef926 apache-chainsaw-2.1.0-standalone.tar.gz
与 .sha512 文件内容一致,校验通过。
4.2 解压安装到 /opt
tar xzf apache-chainsaw-2.1.0-standalone.tar.gz -C /opt/
ls /opt/apache-chainsaw-2.1.0/
实测回显:
LICENSE
NOTICE
apache-chainsaw-2.1.0.jar
apache-log4j-extras-1.1.jar
bin
build.xml
commons-logging-1.1.1.jar
commons-vfs-1.0.jar
jmdns-3.4.1.jar
jsch-0.1.55.jar
log4j-1.2.16.jar
pom.xml
repo
site
src
xmlpull-1.1.3.1.jar
xpp3_min-1.1.4c.jar
xstream-1.4.11.1.jar
4.3 启动脚本与 JVM 参数位置
启动脚本为 /opt/apache-chainsaw-2.1.0/bin/chainsaw(对应 Windows 的 bin/chainsaw.bat),关键行为(阅读脚本得到的结论):
- 默认 JAVA_HOME 未设置时直接使用 PATH 中的 java;可用 JAVA_HOME 环境变量指定 JVM。
- classpath 优先取 $BASEDIR/repo 下的内嵌仓库(Maven 布局 jar),主类为
org.apache.log4j.chainsaw.LogUI(主 jar MANIFEST 中 Main-Class 实测一致)。 - JVM 参数通过 JAVA_OPTS 环境变量传入,脚本会把它拼在 java 命令之后——这就是修改堆大小的位置。官方脚本未预设堆参数,JVM 走默认值(通常为物理内存的 1/4);生产建议显式设置。
主 jar MANIFEST 关键字段(实测):
Implementation-Version: 2.1.0
Main-Class: org.apache.log4j.chainsaw.LogUI
Build-Jdk-Spec: 11
内嵌依赖仓库(实测清单):
/opt/apache-chainsaw-2.1.0/repo/com/jcraft/jsch/0.1.55/jsch-0.1.55.jar
/opt/apache-chainsaw-2.1.0/repo/com/thoughtworks/xstream/xstream/1.4.11.1/xstream-1.4.11.1.jar
/opt/apache-chainsaw-2.1.0/repo/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar
/opt/apache-chainsaw-2.1.0/repo/commons-vfs/commons-vfs/1.0/commons-vfs-1.0.jar
/opt/apache-chainsaw-2.1.0/repo/javax/jmdns/jmdns/3.4.1/jmdns-3.4.1.jar
/opt/apache-chainsaw-2.1.0/repo/log4j/apache-chainsaw/2.1.0/apache-chainsaw-2.1.0.jar
/opt/apache-chainsaw-2.1.0/repo/log4j/apache-log4j-extras/1.1/apache-log4j-extras-1.1.jar
/opt/apache-chainsaw-2.1.0/repo/log4j/log4j/1.2.16/log4j-1.2.16.jar
/opt/apache-chainsaw-2.1.0/repo/xmlpull/xmlpull/1.1.3.1/xmlpull-1.1.3.1.jar
/opt/apache-chainsaw-2.1.0/repo/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar
要点小结:standalone 包自含全部依赖,解压即可运行;JVM 参数位置就是 bin/chainsaw 读到的 JAVA_OPTS 环境变量。
五、方案 B:源码 Maven 构建与 jar 直跑
5.1 适用场景
无法直接下载二进制包但能拉取源码,或需要修改源码时,用源码构建。源码包同样来自官方下载目录。
5.2 下载与解压
cd /root
curl -sO https://downloads.apache.org/logging/chainsaw/2.1.0/apache-chainsaw-2.1.0-src.tar.gz
mkdir -p /root/chainsaw-src && tar xzf apache-chainsaw-2.1.0-src.tar.gz -C /root/chainsaw-src
ls /root/chainsaw-src | head -8
实测回显(前 8 项):
HOWTOBUILD.txt
LICENSE
NOTICE
build.xml
pom.xml
site
src
xdocs
5.3 Maven 构建(JDK 17 需追加模块开放参数)
源码包 pom.xml 中 maven.compiler.source 为 1.8,依赖 lombok 1.18.0。在 JDK 17 上直接 mvn package 会因强封装失败,实测报错:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project apache-chainsaw: Fatal error compiling: java.lang.ExceptionInInitializerError: Unable to make field private com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors com.sun.tools.javac.processing.JavacProcessingEnvironment.discoveredProcs accessible: module jdk.compiler does not "opens com.sun.tools.javac.processing" to unnamed module @dbdaa1d -> [Help 1]
解法:给 Maven 的 JVM 追加 jdk.compiler 模块的 --add-opens(这就是本文实测成功的构建命令)。另外直接 mvn package 只出主 jar,assembly 打包阶段要求先有 site 产物,需加 site 目标。完整实测命令:
cd /root/chainsaw-src
export MAVEN_OPTS="--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED"
mvn -B site package -DskipTests -Dmaven.javadoc.skip=true -Drat.skip=true
实测回显(结尾):
[INFO] BUILD SUCCESS
[INFO] Total time: 13:21 min
构建产物(实测清单):
target/apache-chainsaw-2.1.0-bin.tar.gz
target/apache-chainsaw-2.1.0.jar
target/apache-chainsaw-2.1.0-sources.jar
target/apache-chainsaw-2.1.0-standalone.tar.gz
构建出的 standalone 包与官方包结构一致,可按第四章同样方式安装。
5.4 jar 直跑(不装 GUI 也能用)
standalone 包解压后的 repo 目录就是完整 classpath。不启动 GUI,直接用其中的 jar 编译/运行 headless 程序(解析日志文件示例,完整代码见第八章 8.3):
mkdir -p /opt/chainsaw-headless/classes
cd /opt/chainsaw-headless
javac -encoding UTF-8 -cp /opt/apache-chainsaw-2.1.0/repo/log4j/apache-chainsaw/2.1.0/apache-chainsaw-2.1.0.jar:/opt/apache-chainsaw-2.1.0/repo/log4j/apache-log4j-extras/1.1/apache-log4j-extras-1.1.jar:/opt/apache-chainsaw-2.1.0/repo/log4j/log4j/1.2.16/log4j-1.2.16.jar -d classes LogFilePatternReceiverDemo.java
java -Dfile.encoding=UTF-8 -cp classes:/opt/apache-chainsaw-2.1.0/repo/log4j/apache-chainsaw/2.1.0/apache-chainsaw-2.1.0.jar:/opt/apache-chainsaw-2.1.0/repo/log4j/apache-log4j-extras/1.1/apache-log4j-extras-1.1.jar:/opt/apache-chainsaw-2.1.0/repo/log4j/log4j/1.2.16/log4j-1.2.16.jar LogFilePatternReceiverDemo
实测回显(业务事件部分):
EVENT level=INFO logger=com.example.service.OrderService thread=main msg=订单创建成功 orderId=1001
EVENT level=WARN logger=com.example.service.InventoryService thread=main msg=库存低于阈值 sku=SKU-1024
EVENT level=ERROR logger=com.example.service.PayService thread=main msg=支付网关超时 orderId=9001
业务事件总数=3
六、方案对比与选择建议
| 维度 | 方案 A:standalone 官方包 | 方案 B:源码构建 + jar 直跑 |
|---|---|---|
| 获取方式 | 官网直接下载 2.9 MB 包 | 下载 2.1 MB 源码包后 Maven 构建 |
| 安装耗时 | 解压即完成(秒级) | 实测构建 13 分 21 秒 |
| 启动脚本 | 自带 bin/chainsaw | 需自配 java -cp 命令或自行组装 |
| 版本一致性 | 与官方发布完全一致 | 受本机 JDK/Maven 影响较大 |
| 适用场景 | 绝大多数服务器安装 | 需改源码、内网无法直接下载二进制时 |
选择建议:优先方案 A;方案 B 用于无法获取二进制包或需定制源码的场景。两方案产物可共存于不同目录,互不影响。
七、基础配置
7.1 JVM 堆参数
Chainsaw 的 JVM 参数入口是 bin/chainsaw 读取的 JAVA_OPTS 环境变量。本文统一使用 256 MB 堆(日志分析负载不大时足够;若加载大日志文件可调至 512 MB)。写一个环境文件便于管理:
cat > /etc/profile.d/chainsaw.sh <<'EOF'
export CHAINSAW_HOME=/opt/apache-chainsaw-2.1.0
export JAVA_OPTS="-Xms256m -Xmx256m --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.base/java.time=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.desktop/java.awt=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED"
EOF
source /etc/profile.d/chainsaw.sh
修改方法:直接编辑 /etc/profile.d/chainsaw.sh,把 -Xms256m -Xmx256m 调整为目标值(如 -Xms512m -Xmx512m),重新 source 或重新登录后生效。--add-opens 系列参数的作用见第九章 FAQ 第一条。
7.2 无显示器服务器的启动方式
Chainsaw 是 Swing 程序,无显示器的服务器需要 X 虚拟帧缓冲(xvfb)。启动 Xvfb 并在指定显示号上运行 Chainsaw:
Xvfb :97 -screen 0 1280x1024x24 >/tmp/xvfb97.log 2>&1 &
sleep 2
cd /opt/apache-chainsaw-2.1.0
DISPLAY=:97 nohup bin/chainsaw >/tmp/chainsaw-gui.log 2>&1 &
要点小结:Xvfb 先于 Chainsaw 启动;DISPLAY 指向 Xvfb 的显示号;两者都是普通前台/后台进程,重启服务器后需按此顺序重新拉起(可写入 systemd unit 或开机脚本)。
八、安装验证
8.1 GUI 真实启动验证(xvfb + xwininfo)
按 7.2 启动约 20 秒后,用 xwininfo 检查虚拟显示器上是否真的出现了 Chainsaw 的窗口(窗口 WM_CLASS 实测为 org-apache-log4j-chainsaw-LogUI):
DISPLAY=:97 xwininfo -root -tree | grep -iE "chainsaw" | head -4
实测回显:
0x200166 "Pick a Color": ("org-apache-log4j-chainsaw-LogUI" "org-apache-log4j-chainsaw-LogUI") 523x343+379+341 +379+341
0x20016e "Content window": ("org-apache-log4j-chainsaw-LogUI" "org-apache-log4j-chainsaw-LogUI") 523x343+0+0 +379+341
0x200156 " ": ("org-apache-log4j-chainsaw-LogUI" "org-apache-log4j-chainsaw-LogUI") 644x516+0+0 +0+0
0x20015e "Content window": ("org-apache-log4j-chainsaw-LogUI" "org-apache-log4j-chainsaw-LogUI") 644x516+0+0 +0+0
统计窗口数:
DISPLAY=:97 xwininfo -root -tree | grep -c "org-apache-log4j-chainsaw-LogUI"
实测回显:
33
进程确认:
jps -l | grep -v Jps
实测回显:
8052 org.apache.log4j.chainsaw.LogUI
Chainsaw 启动过程的控制台输出(/tmp/chainsaw-gui.log 实测,均为正常信息):
Security framework of XStream not initialized, XStream is probably vulnerable.
Using basic font
Wanting to add a row, but GUI not initialized, waiting...
进一步的可视化验证:在装了 ImageMagick 的机器上执行 DISPLAY=:97 import -window root /tmp/chainsaw-97.png 可对虚拟显示器截图。本文实测截图中可见 Chainsaw v2 完整主界面:菜单栏 File、View、Current tab、Connect to、Help;标签页 Welcome、ZeroConf、chainsaw-log;欢迎页标题 "Chainsaw v2 - brought to you by the Log4j Dev team";Hot Keys 面板(F3 Find Next、CMD-F Find、CMD-N New tab 等快捷键列表);接收器配置对话框(Use fileappender entries from a log4j config file、Process a log file、Receive events from the network、Use a Chainsaw config file 四个选项)。GUI 验证通过。
8.2 字节码版本验证(Java 9+ 依据)
javap -verbose -cp /opt/apache-chainsaw-2.1.0/repo/log4j/apache-chainsaw/2.1.0/apache-chainsaw-2.1.0.jar org.apache.log4j.chainsaw.LogUI | grep -E "major|minor"
实测回显:
minor version: 0
major version: 53
major 53 对应 Java 9。这就是本文把 JDK 版本要求定为 9+、推荐 11/17 的实测依据。
8.3 headless 功能验证(不依赖图形栈)
用 jar 直跑方式验证核心解析能力。示例程序把 LogFilePatternReceiver 解析出的日志事件路由到自定义 Appender 并回显:
cat > /opt/chainsaw-headless/demo-log/app.log <<'EOF'
2026-10-15 09:30:00,123 INFO com.example.service.OrderService 订单创建成功 orderId=1001
2026-10-15 09:30:01,456 WARN com.example.service.InventoryService 库存低于阈值 sku=SKU-1024
2026-10-15 09:30:02,789 ERROR com.example.service.PayService 支付网关超时 orderId=9001
EOF
Java 源码(/opt/chainsaw-headless/LogFilePatternReceiverDemo.java):
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.varia.LogFilePatternReceiver;
public class LogFilePatternReceiverDemo {
static int bizCount = 0;
static class DumpAppender extends AppenderSkeleton {
@Override
protected void append(LoggingEvent e) {
System.out.println(" EVENT level=" + e.getLevel()
+ " logger=" + e.getLoggerName()
+ " thread=" + e.getThreadName()
+ " msg=" + e.getMessage());
if (e.getLoggerName().startsWith("com.example")) {
bizCount++;
}
}
@Override
public void close() {
}
@Override
public boolean requiresLayout() {
return false;
}
}
public static void main(String[] args) throws Exception {
Logger root = Logger.getRootLogger();
root.setLevel(Level.INFO);
root.addAppender(new DumpAppender());
LogFilePatternReceiver receiver = new LogFilePatternReceiver();
receiver.setName("demo-pattern-receiver");
receiver.setFileURL("file:///opt/chainsaw-headless/demo-log/app.log");
receiver.setLogFormat("TIMESTAMP LEVEL LOGGER MESSAGE");
receiver.setTimestampFormat("yyyy-MM-dd HH:mm:ss,SSS");
receiver.setTailing(false);
receiver.setUseCurrentThread(true);
receiver.setLoggerRepository(LogManager.getLoggerRepository());
receiver.activateOptions();
receiver.shutdown();
System.out.println("业务事件总数=" + bizCount);
}
}
编译运行命令与完整实测回显(见 5.4),此处列关键输出:
EVENT level=INFO logger=org.apache.log4j.varia.LogFilePatternReceiver thread=main msg=activateOptions
EVENT level=INFO logger=org.apache.log4j.varia.LogFilePatternReceiver thread=main msg=attempting to load file: file:///opt/chainsaw-headless/demo-log/app.log
EVENT level=INFO logger=com.example.service.OrderService thread=main msg=订单创建成功 orderId=1001
EVENT level=WARN logger=com.example.service.InventoryService thread=main msg=库存低于阈值 sku=SKU-1024
EVENT level=ERROR logger=com.example.service.PayService thread=main msg=支付网关超时 orderId=9001
业务事件总数=3
三条业务日志全部按格式模板解析为结构化事件,中文消息无损。安装验证全部通过。
要点小结:GUI 侧用 xvfb+xwininfo 拿到窗口级证据;headless 侧用接收器 API 拿到解析级证据,两者共同确认安装可用。
九、常见问题(FAQ)
9.1 JDK 17 启动 GUI 报 InaccessibleObjectException 崩溃
现象:不带 --add-opens 直接启动,进程立刻退出,控制台实测报错(节选):
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.thoughtworks.xstream.XStream.setupConverters(XStream.java:990)
at org.apache.log4j.chainsaw.ApplicationPreferenceModelSaver.loadSettings(ApplicationPreferenceModelSaver.java:53)
at org.apache.log4j.chainsaw.prefs.SettingsManager.configure(SettingsManager.java:302)
at org.apache.log4j.chainsaw.LogUI.main(LogUI.java:211)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.Comparator java.util.TreeMap.comparator accessible: module java.base does not "opens java.util" to unnamed module @4f51ab48
原因:Chainsaw 内嵌的 XStream 1.4.11.1 在 JDK 9+ 的模块强封装下无法反射 java.util 内部字段。解法:按 7.1 在 JAVA_OPTS 中加上文实测的 --add-opens 参数(java.base 的 util/lang/io/text/time/math/net/lang.reflect/util.concurrent 与 java.desktop 的 awt/awt.font),加齐后本文 GUI 启动验证一次通过。
9.2 JDK 8 报 UnsupportedClassVersionError
现象:用 JDK 8 运行 headless 演示,实测报错:
java.lang.UnsupportedClassVersionError: org/apache/log4j/varia/LogFilePatternReceiver has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0
原因:官方 jar 字节码为 major 53(Java 9+),JDK 8(52.0)无法加载。解法:升级到 JDK 11 或 17。
9.3 无显示器服务器 GUI 无法显示
现象:直接运行 bin/chainsaw 报 HeadlessException 或界面无法创建。解法:无显示器的服务器需要 X 虚拟帧缓冲(xvfb),先启动 Xvfb 再用 DISPLAY 环境变量指向它(见 7.2),本文在 :97 显示号上完成了全流程验证。
9.4 Maven 里搜不到 chainsaw 依赖
现象:在 pom 中引入 org.apache.logging.chainsaw:chainsaw 或 log4j:apache-chainsaw 报找不到构件。原因:Chainsaw 2.1.0 未发布到 Maven Central(实测三个候选坐标均 404)。解法:用官方 standalone 包,或下载源码包本地构建(见第五、六章)。
9.5 GUI 日志出现 Security framework of XStream not initialized
现象:启动日志持续出现 "Security framework of XStream not initialized, XStream is probably vulnerable."。原因:XStream 未配置安全框架时的常规告警。影响:本地单机分析工具,不监听网络端口,风险可控;如需消除可升级 XStream 或配置 XStream 安全白名单,属于进阶改造项。
十、卸载与清理
rm -rf /opt/apache-chainsaw-2.1.0
rm -rf /opt/chainsaw-headless
rm -f /etc/profile.d/chainsaw.sh
rm -f /root/apache-chainsaw-2.1.0-standalone.tar.gz /root/apache-chainsaw-2.1.0-standalone.tar.gz.sha512
rm -f /root/apache-chainsaw-2.1.0-src.tar.gz
rm -rf /root/chainsaw-src
如有不再使用的 Xvfb 实例,先停进程再按需卸载:
pkill -f "Xvfb :97"
apt-get remove -y xvfb x11-utils
apt-get autoremove -y
OpenJDK 17 如无其他应用使用,可一并卸载(卸载前确认没有其他服务依赖):
apt-get remove -y openjdk-17-jdk
apt-get autoremove -y
十一、参考链接
- 官方主页:https://logging.apache.org/chainsaw/
- 官方下载目录:https://downloads.apache.org/logging/chainsaw/
- Apache Logging Services 项目:https://logging.apache.org/
- Log4j 1.x extras(接收器实现来源):https://logging.apache.org/log4j/1.x/
- xvfb-run 手册页:https://manpages.ubuntu.com/manpages/jammy/en/man1/xvfb-run.1.html