使用jetty.sh通过systemd运行Jetty时丢失stdout的问题排查
解决Jetty通过systemd启动时标准输出丢失的问题
核心原因分析
- Type=forking的限制:你的systemd服务配置为
Type=forking,此时systemd仅追踪jetty.sh父进程的输出,而jetty.sh start会启动Jetty子进程后退出,子进程的stdout/stderr不会被systemd捕获——直接在ExecStart后加重定向只对父进程生效,自然不会生成目标文件。 - Jetty日志系统的优先级:从你的Jetty配置来看,已启用
logging/slf4j和jetty-slf4j-impl模块,Jetty的日志会通过SLF4J框架处理,而非直接输出到进程的stdout/stderr。
具体解决思路
1. 先检查Jetty默认日志位置
Jetty的jetty-slf4j-impl模块默认会将日志输出到Jetty Base目录下的logs文件夹,先去这里确认是否已有日志文件:
ls /var/jetty-base/logs/ cat /var/jetty-base/logs/jetty.log
2. 修改systemd服务,直接管理Jetty Java进程(推荐)
放弃使用jetty.sh,直接调用start.jar启动Jetty,这样systemd可以直接追踪Java进程的输出,配置更可控:
修改/etc/systemd/system/jetty.service为:
[Unit] Description=Jetty Web Application Server After=network.target [Service] Type=simple User=jetty Group=jetty Environment="JAVA=/etc/alternatives/jre_17/bin/java" "JETTY_BASE=/var/jetty-base/" "JETTY_HOME=/usr/local/jetty-home-10.0.17" WorkingDirectory=/var/jetty-base # 直接启动Jetty的start.jar ExecStart=/etc/alternatives/jre_17/bin/java -jar /usr/local/jetty-home-10.0.17/start.jar # 配置日志输出到文件 StandardOutput=append:/var/log/jetty/jetty.log StandardError=append:/var/log/jetty/jetty-error.log # 可选:设置进程崩溃后自动重启 Restart=on-failure [Install] WantedBy=multi-user.target
然后执行以下命令生效:
# 创建日志目录并设置权限 mkdir -p /var/log/jetty chown jetty:jetty /var/log/jetty # 重新加载systemd配置 systemctl daemon-reload # 重启Jetty服务 systemctl restart jetty.service
此时可以通过journalctl -u jetty.service -f查看实时日志,或者直接查看/var/log/jetty/jetty.log。
3. 若坚持使用jetty.sh的处理方式
如果必须用jetty.sh启动,需要修改jetty.sh脚本,让它将Jetty子进程的输出重定向到指定文件:
- 编辑
/usr/local/jetty-home/bin/jetty.sh,找到启动Jetty的java命令行,在末尾添加重定向:>> /var/log/jetty/jetty.log 2>&1 - 确保
/var/log/jetty目录存在且jetty用户有写入权限
4. 统一Java环境变量(重要)
注意到你的systemd服务中配置的JAVA=/etc/alternatives/jre_17/bin/java,但Jetty实际运行使用的是Java 11(从--list-config的java.home可见),这会导致环境不一致。建议:
- 确保
/etc/alternatives/jre_17指向正确的Java 17路径,或者直接在systemd配置中使用Java 11的绝对路径,保持与Jetty运行环境一致。
内容的提问来源于stack exchange,提问作者lschult2
相关产品推荐
相关产品推荐

