如何在Java致命错误日志文件名中添加错误发生时的时间戳
问题根因
原有配置不生效的核心原因有两个:
-XX:OnError的参数值用双引号包裹时,串内的$(date +%F-%H%M%S)会在JVM启动的瞬间被外层执行命令的shell提前替换为当时的时间,不会等到JVM触发致命错误回调时再执行,所以拿到的永远是JVM启动时间。- 就算把双引号换成单引号避免启动时提前展开,JVM执行OnError配置的命令时,是直接通过操作系统
exec类系统调用拉起进程,不会自动启动shell解析命令替换、变量替换这类shell语法,直接写$(date)不会被识别为需要执行的命令,会被当成普通字符串传入。
可行实现方案
方案1:OnError显式调用shell执行重命名(零额外文件,最简便)
显式在OnError配置里拉起shell进程执行重命名逻辑,同时用单引号把整个OnError命令串包裹,避免启动阶段被外层shell提前展开:
java -XX:ErrorFile=/path/to/error.log \ -XX:OnError='bash -c "mv /path/to/error.log /path/to/error_store/error_$(date +%F-%H%M%S).log"' \ -jar /path/to/application.jar
如果运行环境没有bash,把bash替换为sh即可,用到的date格式化参数符合POSIX标准,通用shell环境都支持。
方案2:独立脚本封装错误处理逻辑(适合后续扩展)
如果后续需要给致命错误日志加压缩、告警、上报等额外处理,直接把逻辑写在独立脚本里,避免命令行参数转义出错:
- 新建错误处理脚本
/path/to/handle_jvm_crash.sh,赋予可执行权限:
#!/bin/bash ERROR_LOG="/path/to/error.log" STORE_PATH="/path/to/error_store" # 崩溃触发时才生成时间戳 CRASH_TIME=$(date +%F-%H%M%S) mv "$ERROR_LOG" "${STORE_PATH}/error_${CRASH_TIME}.log" # 可在此追加压缩、告警、上传等自定义逻辑
- JVM启动参数直接指定执行该脚本即可:
java -XX:ErrorFile=/path/to/error.log \ -XX:OnError=/path/to/handle_jvm_crash.sh \ -jar /path/to/application.jar
这个方案调整处理逻辑不需要修改JVM启动参数,排查问题也更方便。
注意事项
JVM本身不支持在-XX:ErrorFile的路径配置中解析时间戳类的占位符,直接在路径里写时间变量会被当成普通文件名字符处理,不要尝试直接通过ErrorFile参数实现时间戳命名。
内容的提问来源于stack exchange,提问作者SATO Yusuke
相关产品推荐
相关产品推荐

