在 Ubuntu 部署 Java 服务时,日志往往既关系排障效率,也直接影响后续的轮转、归档和集中采集。与其让应用单独写散落文件,不如把输出接到系统现成的日志体系里。下面按接入难度和适用规模,整理几种常见做法,并给出配置示例与选型判断,方便你根据现有运维方式直接落地。
用 Systemd 先打通最基础的日志接入
如果 Java 应用本来就是用 Systemd 管理,最直接的办法就是让服务的标准输出和标准错误进入系统日志。这种方式改动小,适合先把服务纳入统一管理,再通过 journalctl 查看运行日志。

创建并配置服务文件
在 /etc/systemd/system/ 下新建 myapp.service,把 Java 进程作为 Systemd 服务启动,同时指定日志输出到 syslog:
[Unit]
Description=My Ja va Application
After=network.target
[Service]
User=myuser
Group=mygroup
ExecStart=/usr/bin/ja va -jar /path/to/myapp.jar
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=myapp
[Install]
WantedBy=multi-user.target
这里比较关键的是三项配置:
StandardOutput=syslog:把标准输出交给系统日志处理。StandardError=syslog:把错误输出也纳入同一条链路。SyslogIdentifier=myapp:为日志打上程序名标识,后面做筛选和分流会更方便。
重新加载并启动服务
服务文件写好后,需要让 Systemd 重新读取配置,然后启动应用:
sudo systemctl daemon-reload
sudo systemctl start myapp
如果这是长期运行的服务,通常也会继续补上开机自启,但本文的重点是日志接入本身,核心链路到这里已经建立。
查看接入后的日志
完成启动后,可以直接用下面的命令确认日志是否已经进入 Systemd 的日志系统:
sudo journalctl -u myapp
如果你的目标只是让运维侧统一用系统命令看日志,这一步往往已经足够。它适合中小型服务,优点是配置简单、接入快,缺点是日志结构化能力和跨主机集中分析能力有限。
把 Log4j 或 Logback 直接接到 Syslog
如果项目里已经明确使用 Log4j 或 Logback,那么也可以不只依赖进程标准输出,而是让日志框架直接把消息发到 syslog。这样做的好处是应用层可以继续保留原有日志格式控制,并更清楚地指定设施类型和输出模式。
Log4j 配置示例
在 log4j.properties 中加入如下配置:
log4j.rootLogger=INFO, syslog
log4j.appender.syslog=org.apache.log4j.net.SyslogAppender
log4j.appender.syslog.SyslogHost=localhost
log4j.appender.syslog.Facility=LOCAL0
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
log4j.appender.syslog.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
这组配置里,SyslogHost=localhost 表示先发往本机 syslog,Facility=LOCAL0 则方便后续在系统日志侧做规则区分。日志格式继续由 PatternLayout 控制,不会因为接入系统日志而失去应用层格式能力。
Logback 配置示例
如果项目使用的是 Logback,可以在 logback.xml 中添加对应 appender:
localhost
LOCAL0
%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n
和 Log4j 的思路一样,Logback 也是把日志主动投递给本地 syslog,再由 Ubuntu 的日志组件继续处理。这种方式更适合已经稳定使用日志框架、并希望保留统一输出格式的项目。
用 rsyslog 做分类收集和落盘
当日志已经进入 syslog 体系后,下一步常见需求就是按应用名分流,把某个 Java 服务的日志单独写入文件。Ubuntu 环境里如果已经使用 rsyslog,这一步通常只需要补一条规则。

添加 rsyslog 规则
编辑 /etc/rsyslog.conf 或 /etc/rsyslog.d/50-default.conf,加入下面的配置:
if $programname == 'myapp' then /var/log/myapp.log
& stop
这条规则的含义很直接:当日志中的 $programname 等于 myapp 时,把内容写到 /var/log/myapp.log,随后用 & stop 阻止它继续匹配后面的规则。这样既能单独留存应用日志,也能避免重复写入。
重启 rsyslog 使配置生效
规则保存后,重启 rsyslog:
sudo systemctl restart rsyslog
别忽略应用输出方式
这里有一个容易漏掉的前提:Java 程序需要把日志输出到标准输出,也就是 stdout,这样 rsyslog 才能沿着系统日志链路接收到内容。换句话说,rsyslog 负责收集和分流,但前面的日志入口必须先打通。
如果你的目标是“系统统一收集,同时为单个应用保留独立日志文件”,那 Systemd 加 rsyslog 往往就是最实用的组合,部署复杂度也比较可控。
日志量更大时,再接 Fluentd 或 Logstash
如果应用规模继续扩大,或者运维侧已经有集中检索、跨节点分析、告警和可视化需求,仅靠本机 syslog 和 rsyslog 就不够了。这时可以在系统日志链路之外,引入 Fluentd 或 Logstash 做进一步采集和转发。
安装采集组件
示例安装命令如下:
sudo apt-get install fluentd
# 或者 logstash
安装完成后,再根据你的环境配置它们把 Java 应用日志发送到 Elasticsearch 等集中存储。原文没有展开具体转发规则,但思路很明确:本机负责产生和初步收集,日志平台负责集中存储与检索分析。
结合日志框架插件输出
如果你希望应用侧和采集平台结合得更紧,可以在日志框架里使用对应插件。例如:
- Log4j 可使用
fluentd-log4j-appender - Logback 可使用
logstash-logback-encoder
这类做法更适合日志量大、字段较多,或者需要直接进入集中式日志平台的场景。相应地,部署和维护成本也会比前几种方案更高。
怎么选更合适的整合方式
把 Java 日志接入 Ubuntu,并没有唯一标准答案,关键看你想解决的是哪一层问题。

- 如果只是想让服务日志进入系统统一查看链路,优先用 Systemd。
- 如果项目已经深度依赖 Log4j 或 Logback,并希望继续掌控日志格式和设施分类,可以直接对接 Syslog。
- 如果需要把不同应用日志单独分流落盘,rsyslog 会更顺手。
- 如果已经进入集中检索、跨节点采集和分析阶段,再考虑 Fluentd 或 Logstash。
实际落地时,这几种方式也并不冲突。很多环境里常见的路径就是:Java 应用先进入 Systemd 或 Syslog,再交给 rsyslog 分类,最后按需要汇入 Fluentd、Logstash 或 Elasticsearch。这种分层接入方式,既保留了 Ubuntu 原生日志管理能力,也给后续扩展留出了空间。







