【问题标题】:No logs appear on Cloudwatch log group for elastic beanstalk environment弹性 beanstalk 环境的 Cloudwatch 日志组上没有日志
【发布时间】:2019-12-20 06:02:57
【问题描述】:

我有一个弹性 beanstalk 环境,它正在运行一个具有节点 js API 的 docker 容器。在 AWS 控制台上,如果我选择我的环境,然后转到配置/软件,我有以下内容:

  • 日志组:/aws/elasticbeanstalk/my-environment
  • 日志流:启用
  • 保留:3 天
  • 生命周期:终止后保留

但是,如果我在 Cloudwatch 控制台上单击该日志组,我有一个几周前的上次事件时间(我相信它对应于创建环境的时间)并且没有内容在日志上。

由于这是一个 dockerized 应用程序,服务器本身的日志应位于 /aws/elasticbeanstalk/my-environment/var/log/eb-docker/containers/eb-current-app/stdouterr.log。 如果我通过再次进入我的 EB 环境直接从实例获取日志,单击“日志”,然后单击“请求最后 100 行”,则日志记录正确发生。使用 CloudWatch 时我什么都看不到。

非常感谢任何帮助

【问题讨论】:

  • 您是否一直在重新部署您的应用程序,即:启动一个新容器?如果是这样,我认为您的问题与stackoverflow.com/questions/57464585/… 有关
  • Yes 似乎相关,但不幸的是那里没有答案。如果我查看我的 CloudWatch 日志组,我有类似的内容:/aws/elasticbeanstalk/my-env/var/log/eb-docker/containers/eb-current-app/stdouterr.log 但是,如果我直接提取日志,我会观察到以下内容:/var/log/eb-docker/containers/eb-current-app/eb-"hexstring"-stdouterr.log

标签: node.js docker logging amazon-elastic-beanstalk amazon-cloudwatch


【解决方案1】:

对于 64 位 Amazon Linux 2,设置略有不同。

为了传送日志,AWS CloudWatch 代理安装在 /opt/aws/amazon-cloudwatch-agent 中,Elastic Beanstalk 配置在 /opt/aws/amazon-cloudwatch-agent/etc/beanstalk.json 中。假设有一个名为 stdouterr.log 的文件,它被设置为记录容器的输出,这是配置的 sn-p:

{
  "file_path": "/var/log/eb-docker/containers/eb-current-app/stdouterr.log",
  "log_group_name": "/aws/elasticbeanstalk/EB-ENV-NAME/var/log/eb-docker/containers/eb-current-app/stdouterr.log",
  "log_stream_name": "{instance_id}"
}

但是,当我查找 file_path 时,它并不存在,而是我有一个文件路径来编码当前 docker 容器 ID /var/log/eb-docker/containers/eb-current-app/eb-e4e26c0bc464-stdouterr.log

这个日志文件是由eb-docker-log服务启动的脚本/opt/elasticbeanstalk/config/private/eb-docker-log-start创建的,这个文件的默认内容是:

EB_CONFIG_DOCKER_CURRENT_APP=`cat /opt/elasticbeanstalk/deployment/.aws_beanstalk.current-container-id | cut -c 1-12`
mkdir -p /var/log/eb-docker/containers/eb-current-app/
docker logs -f $EB_CONFIG_DOCKER_CURRENT_APP >> /var/log/eb-docker/containers/eb-current-app/eb-$EB_CONFIG_DOCKER_CURRENT_APP-stdouterr.log 2>&1

要临时修复日志记录,您可以手动运行(替换 docker ID),然后日志将开始出现在 CloudWatch 中:

ln -sf /var/log/eb-docker/containers/eb-current-app/eb-e4e26c0bc464-stdouterr.log /var/log/eb-docker/containers/eb-current-app/stdouterr.log

为了使这个永久存在,我添加了一个.ebextension 来修复eb-docker-log 服务,因此它重新创建了这个链接,因此在.ebextensions 的源代码中创建一个名为fix-cloudwatch-logging.config 的文件并将其内容设置为:

files:
  "/opt/elasticbeanstalk/config/private/eb-docker-log-start" :
    mode: "000755"
    owner: root
    group: root
    content: |
      EB_CONFIG_DOCKER_CURRENT_APP=`cat /opt/elasticbeanstalk/deployment/.aws_beanstalk.current-container-id | cut -c 1-12`
      mkdir -p /var/log/eb-docker/containers/eb-current-app/
      ln -sf /var/log/eb-docker/containers/eb-current-app/eb-$EB_CONFIG_DOCKER_CURRENT_APP-stdouterr.log /var/log/eb-docker/containers/eb-current-app/stdouterr.log
      docker logs -f $EB_CONFIG_DOCKER_CURRENT_APP >> /var/log/eb-docker/containers/eb-current-app/eb-$EB_CONFIG_DOCKER_CURRENT_APP-stdouterr.log 2>&1
commands:
  fix_logging:
    command: systemctl restart eb-docker-log.service
    cwd: /home/ec2-user
    test: "[ ! -L /var/log/eb-docker/containers/eb-current-app/stdouterr.log ] && systemctl is-active --quiet eb-docker-log"

【讨论】:

  • 这对我有用!为了澄清一点,我将.ebextensions 目录放在项目目录中,而不是.elasticbeanstalk 目录中。
  • 我已经删除了对elasticbeanstalk的引用,这是因为我在本地安排项目的方式,感谢您指出这一点。
  • 好吧,AWS 似乎修复了这个问题,并且使用“Amazon Linux 2/3.2.3”不再需要它。我不知道它是什么时候修复的。
  • 无论何时修复,他们都会在“file_path”中添加*:“/var/log/eb-docker/containers/eb-current-app/*stdouterr.log “,”。不过,知道他们在哪里记录了这样的修复仍然会很酷。
【解决方案2】:

我能够解决这个问题。 所以 CloudWatch 根据你的日志文件的第一行和日志流键做一个哈希,问题是我在 stdouterr.log 文件上的第一行实际上是一个空行!

在玩了几天并从优秀的 AWS 支持团队获得帮助后,我首先通过 SSH 连接到与 EB 环境关联的 EC2 实例,您需要将以下行添加到 /etc/awslogs /config/beanstalklogs.conf 文件,紧跟在“file=/var/log/eb-docker/containers/eb-current-app/stdouterr.log”行之后: p>

file_fingerprint_lines=1-20

通过这些,您可以告诉 AWS 服务它应该使用日志文件中的第 1 行到第 20 行来计算哈希值。您可以根据您的日志记录内容将 20 更改为更大或更小的数字;但是我不知道该值是否有上限。

完成后,您需要重启实例上的AWS Logs Service

为此,您将执行:

  • sudo 服务 awslogs 停止
  • sudo 服务 awslogs 启动

或更简单:

sudo 服务 awslogs 重启

在这些步骤之后,我开始使用我的环境,并且日志记录现在可以正确地流式传输到 CloudWatch 控制台! 但是,如果进行了新部署、替换了 EC2 实例或自动扩展组生成了另一个实例,则此方法将不起作用。

要解决此问题,可以在部署之前通过 .ebextensions 目录添加日志配置,该目录位于应用程序的根目录。

我在新创建的.ebextensions目录中添加了一个名为logs.config的文件,并放置了以下内容:

files:
  "/etc/awslogs/config/beanstalklogs.conf":
    mode: "000644"
    user: root
    group: root
    content: |
      [/var/log/eb-docker/containers/eb-current-app/stdouterr.log]
      log_group_name=/aws/elasticbeanstalk/EB-ENV-NAME/var/log/eb-docker/containers/eb-current-app/stdouterr.log
      log_stream_name={instance_id}
      file=/var/log/eb-docker/containers/eb-current-app/*stdouterr.log
      file_fingerprint_lines=1-20

commands:
  01_remove_eb_stream_config:
    command: 'rm /etc/awslogs/config/beanstalklogs.conf.bak'
  02_restart_log_agent:
    command: 'service awslogs restart'

当然EB-ENV-NAME改成我在 EB 上的环境名称。

希望它可以帮助别人!

【讨论】:

  • 很好地解决了这个问题,因为我也遇到了同样的问题。您的日志语句是否包含时间戳?有人建议我更改我的应用程序日志配置,以便日志消息具有时间戳。因为任何哈希值总是不同的,您不必像以前那样提供任何额外的 Beanstalk 日志记录配置。
  • @kierans 这也可以解决我所知道的问题。问题是我使用的框架默认将日志的第一行输出为空行,所以我猜这是 AWS 日志代理比较的框架,这就是为什么我不得不依赖修改“ file_fingerprint_lines"
  • @FaridHajnal 这个配置不应该删除 beanstalklogs.conf 中现有的日志设置吗?
  • 这不适用于我的 NodeJS 单 Docker 实例(Docker 在 64 位 Amazon Linux 2/3.0.3 上运行)。
  • @ArielFrischer 你好。我正在为我的服务器应用程序使用 NestJs 框架,该框架也在单个 docker 实例环境中运行
猜你喜欢
  • 2017-11-05
  • 2016-08-17
  • 1970-01-01
  • 2019-01-23
  • 1970-01-01
  • 2023-04-06
  • 2021-04-08
  • 1970-01-01
  • 2017-09-19
相关资源
最近更新 更多