我们正在尝试将我们的 Java 应用程序从当前的 Elastic Beanstalk JDK 8 平台迁移到在 Amazon Linux 2 上运行 Corretto 11 的新平台。该应用程序运行良好,但处理日志的方式发生了变化。Web 进程的输出现在存储在/var/log/web.stdout.log
其中,每一行都以时间戳和进程名称为前缀,即:
May 20 17:00:00 ip-10-48-41-129 web: {"timestamp":"2020-05-20T17:00:00.035Z","message":"...","logger":"...","thread":"MessageBroker-2","level":"INFO"}
我们怎样才能摆脱前缀?这些日志流式传输到 CloudWatch,我们将它们以 JSON 格式输出到标准输出,以便我们以后可以使用 Logs Insights 查询它们。但是有了前缀,Insights 不会“看到” JSON,而只会将整行视为文本 blob。
我在 AWS 上找不到任何文档。几乎所有 Elastic Beanstalk 的文档都提到了 Amazon Linux 的第一个版本。
我找到了一个足够好的解决方案,所以我会在这里发布它以供后代使用。如果有人可以推荐一个更好的,请做。
Amazon Linux 2 上的 Elastic Beanstalk 依赖于
rsyslog
日志处理和输出。在部署期间有一个文件/opt/elasticbeanstalk/config/private/rsyslog.conf
被复制到/etc/rsyslog.d/web.conf
,它将应用程序的所有输出定向web
到/var/log/web.stdout.log
.该文件不包含任何自定义模板。它依赖于
rsyslog
的默认模板,该模板在 any 前面%msg%
加上时间戳和$programname
(web
在这种情况下)。我尝试通过
.ebextensions
config替换此文件,但这不起作用,因为 Elastic Beanstalk 似乎在.ebextensions
运行后覆盖了此文件。所以我添加了一个额外的平台挂钩来删除文件,保留我添加的自定义挂钩。这是
.ebextensions/logs.config
文件:和
.platform/hooks/predeploy/remove-default-rsyslog-conf.sh
(确保你chmod +x
这个):我使用Platform Hooks来实现这一点。唯一的
/etc/rsyslog.d/web.conf
问题是在应用程序和配置部署上都被替换了,所以你需要一个钩子。这种方法避免了弄乱 Elastic Beanstalk 的内部文件
/opt/elasticbeanstalk/config/private
(自之前的答案以来已更改 -rsyslog.conf
不再存在)。此外,平台挂钩现在比 ebextensions 更受欢迎。如果您使用 CodeBuild,请不要忘记
platformFiles
在输出工件中包含目录(或放置文件的任何位置)。注意:此代码假定进程的名称是
web
. 如果您在 中定义了不同的进程名称,请Procfile
改用它。但是,我认为rsyslog 配置应该始终在,/etc/rsyslog.d/web.conf
尽管进程名称。确保所有
.sh
文件都可以使用chmod +x
..platform/hooks/predeploy/10_logs.sh
.platform/confighooks/predeploy/10_logs.sh
platformFiles/setupLogs.sh
platformFiles/rsyslogWebConf.conf
推测
看起来
/opt/elasticbeanstalk/config/private/rsyslog.conf
被替换为/opt/elasticbeanstalk/config/private/rsyslog.conf.template
:基于此,我推测 Elastic Beanstalk 使用此模板生成单个
/etc/rsyslog.d/web.conf
文件,其中包含每个已定义进程名称的块。因为应用程序和配置部署都可以更改定义的流程,所以在两者之后重新创建此文件是有意义的。我将把我的解决方案放在这里,尽管它与 op 的问题有点不同 - 它围绕着相同的想法,并希望能回答一些其他评论者关于 nodejs 的问题。
这适用于运行 Node.js 12.x 的 Amazon Linux 2
问题:nodejs 标准输出日志与“web”下的 nginx 日志混合在一起,并且格式错误。
以前,在运行 Nodejs 的 Amazon Linux 1 中,这些日志分为
/var/log/nodejs/nodejs.log
和/var/log/nginx/access.log
。将它们组合在一起并以 IP 地址为前缀只会使它们变得一团糟。我按照提出的解决方案进行了一些修改。
正如另一位评论者指出的那样,我不确定他们是否希望您编辑此文件,因为它是私人的。如果您对此不满意,我建议您写入您自己的日志文件而不是标准输出。这样你就有更多的控制权。
如果您使用 lambda 将内容移动到 loggly 中(根据此处的文档https://documentation.solarwinds.com/en/success_center/loggly/content/admin/cloudwatch-logs.htm),您可以简单地将 lambda 修改为提取 JSON 并删除导致悲伤的前导字符串。这是我正在使用的 lambda,它可以很好地清理内容并发布我的 JSON 日志。
旁注,我使用 NodeJS - Fastify,它在引擎盖下包含 Pino 以获得漂亮的 JSON 日志。可以在此处找到有关设置日志的一些重要见解https://jaywolfe.dev/blog/setup-your-fastify-server-with-logging-the-right-way-no-more-express/