如何为Java程序的stdout输出添加时间戳并记录异常?
给Java程序日志添加时间戳的几种实用方案
这问题我碰到过好几次,给你几个从简单到灵活的解决方案,按需选择就行:
1. 使用ts命令(最省心的方案)
ts是moreutils工具集里的小工具,专门用来给每行输出打时间戳,用法超直观。
先安装工具:
- Debian/Ubuntu 系统:
sudo apt install moreutils - CentOS/RHEL 系统:
sudo yum install moreutils
然后修改你的启动命令,让输出先经过ts处理再写入日志:
nohup sh -c '/my/program/start.sh 2>&1 | ts "[%Y-%m-%d %H:%M:%S]" >> /my/log.lg' &
ts "[%Y-%m-%d %H:%M:%S]"会给每一行日志加上类似[2024-05-20 14:30:00]的时间戳,格式可以自定义(比如用%F %T是上面格式的简写)。- 用
sh -c包裹整个管道命令是为了让nohup能正确处理后台运行的管道流程,避免部分输出丢失。
2. 用系统自带的awk实现(无需额外安装)
如果服务器上没法安装新工具,awk是所有类Unix系统都自带的,完全可以替代ts:
修改启动命令为:
nohup sh -c '/my/program/start.sh 2>&1 | awk "{print strftime(\"[%Y-%m-%d %H:%M:%S]\"), \$0}" >> /my/log.lg' &
strftime是awk的时间格式化函数,参数和ts的格式规则一致,部分awk版本还支持%3N来添加毫秒级时间戳(取决于系统环境)。- 注意引号的转义:因为是在
sh -c里,所以双引号要转义成\",避免语法错误。
3. 修改start.sh脚本(最精准的方案)
上面两种方法是给整个start.sh的输出加时间戳,如果脚本里还有其他操作的输出,也会被打上时间戳。如果你只想给Java程序的日志加时间戳,可以直接修改脚本里的Java启动命令:
假设原来的Java启动行是:
java -jar /path/to/your/app.jar
改成带时间戳的版本:
java -jar /path/to/your/app.jar 2>&1 | ts "[%Y-%m-%d %H:%M:%S]" >> /my/log.lg
或者用awk版本(无需安装工具):
java -jar /path/to/your/app.jar 2>&1 | awk '{print strftime("[%Y-%m-%d %H:%M:%S]"), $0}' >> /my/log.lg
这样只有Java程序的stdout/stderr会被打上时间戳,脚本里其他操作的输出不会被影响,更精准。
小提醒
- 不管用哪种方法,一定要确保
2>&1写在管道之前,这样stdout和stderr才会被合并处理,不会有日志遗漏。 - 如果日志文件会持续变大,建议配合
logrotate工具定期切割日志,避免单个文件过大难以管理。
内容的提问来源于stack exchange,提问作者MABeatty1978
相关产品推荐
相关产品推荐

