温馨提示×

如何通过Ubuntu Java日志排查问题

小樊
50
2025-11-18 05:14:59
栏目: 编程语言

Ubuntu Java日志排查实用流程

一 定位日志来源与输出路径

  • 确认应用使用的日志框架:常见有 Log4j/Log4j2、Logback、java.util.logging(JUL)。不同框架的配置文件与级别命名不同,先识别再调整更高效。
  • 查看进程启动方式与参数:检查是否通过 systemd 启动(如 /etc/systemd/system/ 下的 service 文件),关注 ExecStart 中的 -Dlogging.config=-Dlogback.configurationFile=-Djava.util.logging.config.file= 等参数,它们决定了日志配置文件的加载路径。
  • 明确日志落盘位置:优先在应用工作目录、/var/log/ 或应用专属目录(如 logs/)查找;若为 Web 应用(如 Tomcat),同时检查其 logs/ 目录下的 catalina.out、localhost.log* 等文件。
  • 快速定位进程与日志:
    • 获取进程 PID:ps -ef | grep javajps -l
    • 实时看日志:tail -f app.logjournalctl -u your-app.service -f(systemd 场景)
  • 若日志过少,先临时提升日志级别(见下一节)并重启或热加载配置,再复现问题。

二 调整日志级别与输出格式

  • 常用日志级别(从低到高):DEBUG、INFO、WARN、ERROR、FATAL。问题排查阶段建议将根日志或关键包调到 DEBUG/TRACE,定位后再恢复,避免磁盘被占满。
  • 通过配置文件调整(推荐):
    • Logback 示例(logback.xml):将根日志设为 DEBUG,并输出到控制台与滚动文件;按时间滚动并保留 30 天。
      <configuration>
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
          <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
          </encoder>
        </appender>
        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
          <file>logs/application.log</file>
          <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/application.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
          </rollingPolicy>
          <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
          </encoder>
        </appender>
        <root level="DEBUG">
          <appender-ref ref="CONSOLE"/>
          <appender-ref ref="FILE"/>
        </root>
      </configuration>
      
    • Log4j2 示例(log4j2.xml):同时输出到控制台与滚动文件,单个文件 10MB,最多保留 10 个归档。
      <?xml version="1.0" encoding="UTF-8"?>
      <Configuration status="WARN">
        <Appenders>
          <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
          </Console>
          <RollingFile name="RollingFile" fileName="logs/app.log"
                       filePattern="logs/app-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
            <Policies>
              <SizeBasedTriggeringPolicy size="10MB"/>
            </Policies>
            <DefaultRolloverStrategy max="10"/>
          </RollingFile>
        </Appenders>
        <Loggers>
          <Root level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
          </Root>
        </Loggers>
      </Configuration>
      
  • 运行时动态调节(无需改代码/重启):
    • JUL 可在代码中设置:Logger.getLogger("your.logger").setLevel(Level.DEBUG); 或通过 LogManager 调整。
    • 生产上更推荐用配置中心或支持热更新的日志框架插件实现动态级别切换。

三 从日志定位常见问题的步骤

  • 崩溃与 OOM:
    • 检查应用日志中的 OutOfMemoryError 与异常栈;同时在 /var/log/syslog/var/log/messages 查找 OOM-killer 记录。
    • 启动时加上 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/dump.hprof,用 Eclipse MAT 分析泄漏对象与引用链。
  • GC 异常:
    • 打开 GC 日志:-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/var/log/java/gc.log,用 tail -f 观察 Full GC 频率与停顿。
    • jstat -gcutil <PID> 1000 持续查看 YGC/YGCT、FGC/FGCT 等指标,判断是否频繁 Full GC。
  • 线程问题(卡死、CPU 飙高):
    • 抓取线程栈:jstack <PID> > thread_dump.txt,多次抓取(如间隔 5–10 秒)对比阻塞/等待位置。
    • 结合 top -H -p <PID> 定位占用高的线程,将 nid=0x… 转成 10 进制后在 thread_dump 中查找对应线程。
  • Web 容器与部署:
    • 若为 Tomcat,同步查看 catalina.out、localhost.log、manager.*.log*,确认部署失败、类冲突、端口占用等。

四 高效检索与长期治理

  • 关键字检索与模式分析:在日志中搜索 ERROR、Exception、Caused by、OutOfMemoryError、deadlock、timeout 等关键词;对异常栈从 “Caused by” 最深一层向上定位根因。
  • 日志轮转与保留:配置 按时间/按大小滚动保留天数,避免磁盘被撑满(如 Logback 的 TimeBasedRollingPolicy 保留 30 天;Log4j2 SizeBasedTriggeringPolicy 10MBmax=10)。
  • 集中化与可视化:将日志接入 ELK(Elasticsearch、Logstash、Kibana)Graylog,便于跨实例检索、聚合分析与告警。
  • 辅助工具:使用 Java Mission Control(JMC) 做 CPU、内存、线程采样与诊断,结合日志交叉验证。

五 最小可用排查命令清单

  • 进程与日志定位:ps -ef | grep javajps -ltail -f app.logjournalctl -u your-app.service -f
  • 线程与内存:jstack <PID> > thread_dump.txtjstat -gcutil <PID> 1000
  • GC 日志采集:JVM 启动参数加入 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/var/log/java/gc.log
  • OOM 取证:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/dump.hprof,再用 Eclipse MAT 分析
  • 系统侧线索:/var/log/syslog/var/log/messagesdmesg | tail -n 50free -mdf -htop/htop

0