You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu服务未将错误日志写入指定独立文件问题排查

Java Telegram Bot的systemd日志分离问题:异常全进stdout而stderr为空的原因与解决办法

问题重现

配置systemd服务将标准输出和标准错误分别写入不同文件,但Java应用的异常全部进入log(标准输出文件),errorlog(标准错误文件)始终为空,服务配置如下:

[Unit]
Description=Telegram bot service daemon

[Service]
WorkingDirectory=/home/ubuntu/Telegram
ExecStartPre=/bin/touch /home/ubuntu/Telegram/errorlog
ExecStart=/usr/bin/java -jar /home/ubuntu/Telegram/TelegramBot.jar

StandardOutput=file:/home/ubuntu/Telegram/log
StandardError=file:/home/ubuntu/Telegram/errorlog

[Install]
WantedBy=multi-user.target

核心原因

你的Java应用(或其依赖的日志框架)默认将所有日志(包括错误信息、异常栈)都输出到了标准输出(stdout),而非标准错误(stderr)。systemd的StandardError仅能捕获写入stderr通道的数据,自然无法收集到任何内容。

解决办法

1. 调整日志框架配置(推荐,若使用日志框架)

如果你的Bot使用了Logback、Log4j等日志框架,需要单独配置ERROR级别的日志输出到stderr:
以Logback为例,在logback.xml中添加一个定向到System.err的appender,并指定仅输出ERROR及以上级别:

<appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender">
    <target>System.err</target>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
    </encoder>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>ERROR</level>
    </filter>
</appender>

<root level="INFO">
    <appender-ref ref="STDOUT"/> <!-- 原标准输出的appender -->
    <appender-ref ref="STDERR"/> <!-- 新增的标准错误appender -->
</root>

这样ERROR级别的日志会被定向到stderr,systemd会将其写入errorlog文件。

2. 检查代码中的异常输出逻辑

如果未使用日志框架,确保代码中异常输出指向stderr:

  • 替换默认的e.printStackTrace()(虽默认输出到stderr,但部分场景可能被篡改)为显式指定输出流:
    catch (Exception e) {
        e.printStackTrace(System.err);
    }
    
  • 检查代码中是否存在System.setErr(System.out)这类强制将stderr重定向到stdout的操作,如有则删除。

3. 验证配置生效

修改完成后,重启systemd服务:

sudo systemctl restart telegram-bot.service

触发一个Java异常(比如发送非法指令到Bot),查看/home/ubuntu/Telegram/errorlog是否已捕获到错误内容。


内容的提问来源于stack exchange,提问作者Javi Albors

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 04:52:34