如何配置ElasticBeanstalk与Cloudwatch使用logback日志时间戳
Elastic Beanstalk Java SE 应用日志重复时间戳修复方案
问题背景
部署在AWS Elastic Beanstalk上的Java SE应用,日志默认输出到/var/log/web.stdout.log,经CloudWatch Agent采集同步到CloudWatch、OpenSearch后出现三层冗余时间戳,日志样例如下:
2022-07-10T13:00:24.248-07:00 Jul 10 20:00:19 ip-172-31-3-142 web: 20:00:19.401 "Some application log message"
三层时间戳来源:
- 最外层
2022-07-10T13:00:24.248-07:00:CloudWatch Agent采集时自动添加的日志接收时间,也是当前OpenSearch默认使用的时间戳 - 中间层
Jul 10 20:00:19 ip-172-31-3-142 web::Elastic Beanstalk Java SE平台默认rsyslog转发规则添加的syslog前缀 - 最内层
20:00:19.401:应用Logback组件生成的原生业务时间戳,为目标统一使用的时间字段
修复步骤
1. 移除Elastic Beanstalk添加的syslog日志前缀
EB Java SE平台默认通过rsyslog转发应用stdout/stderr输出到日志文件,转发时自动拼接syslog格式前缀,需要通过ebextensions配置覆盖默认转发规则,透传应用原始日志内容。
在应用源码的.ebextensions目录下新建01-fix-web-log-format.config文件,写入以下配置:
files: "/etc/rsyslog.d/10-web-redirect.conf": mode: "000644" owner: root group: root content: | $template RawLogFormat,"%msg%\n" $ActionFileDefaultTemplate RawLogFormat if $programname == 'web' then /var/log/web.stdout.log & stop commands: restart_rsyslog: command: "systemctl restart rsyslog"
配置生效后,新写入/var/log/web.stdout.log的内容将不再包含中间层的syslog时间、主机名、进程名前缀,仅保留应用原始输出。
2. 配置CloudWatch Agent解析应用原生时间戳
CloudWatch Agent默认不解析日志内容中的时间,直接使用日志采集时间作为时间戳,需要修改Agent采集规则,指定时间戳匹配规则,提取Logback生成的时间作为日志官方时间戳。
在.ebextensions目录下新建02-fix-cw-timestamp.config文件,写入以下配置:
files: "/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/web_log_custom.json": mode: "000644" owner: root group: root content: | { "logs": { "logs_collected": { "files": { "collect_list": [ { "file_path": "/var/log/web.stdout.log", "log_group_name": "/aws/elasticbeanstalk/${AWSEB_ENV_NAME}/var/log/web.stdout.log", "log_stream_name": "{instance_id}", "timestamp_format": "%H:%M:%S.%f", "timezone": "Local" } ] } } } } commands: reload_cw_agent: command: | export AWSEB_ENV_NAME=$(/opt/elasticbeanstalk/bin/get-config container -k environment_name) sed -i "s/\${AWSEB_ENV_NAME}/$AWSEB_ENV_NAME/g" /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/web_log_custom.json /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
关键配置说明:
timestamp_format:和Logback输出的时间格式对应,示例中匹配时:分:秒.毫秒格式,如果Logback输出带年月日的完整时间(如yyyy-MM-dd HH:mm:ss.SSS),将该值修改为%Y-%m-%d %H:%M:%S.%f即可timezone: Local:使用EC2实例本地时区解析时间,避免时区偏移;如果Logback输出带时区信息的ISO格式时间,可删除该字段,Agent会自动识别时区- 配置自动读取当前EB环境名称,和EB默认创建的CloudWatch日志组名称保持一致,不会生成额外日志组
校验规则
配置部署完成后做三步校验:
- 登录EC2实例查看
/var/log/web.stdout.log最新写入内容,确认已无syslog前缀,仅保留Logback输出的原始日志 - 进入CloudWatch Logs控制台查看对应日志组的最新日志,确认日志条目自带的时间戳和日志内容中Logback打印的时间完全一致,无时间偏差,无多层时间戳拼接问题
- 日志同步到OpenSearch后,默认
@timestamp字段将直接使用Logback生成的原生时间,无需额外配置索引pipeline做字段转换
注意:存量历史日志不会被自动修改,配置仅对生效后新生成的日志生效。如果Logback输出的时间不带年月日,建议同步调整Logback配置输出带完整日期的时间格式,避免跨天场景下出现日期识别错误。
内容的提问来源于stack exchange,提问作者user1280213
相关产品推荐
相关产品推荐

