AWS Elastic Beanstalk:将自定义日志添加到 CloudWatch?

Posted

技术标签:

【中文标题】AWS Elastic Beanstalk:将自定义日志添加到 CloudWatch?【英文标题】:AWS Elastic Beanstalk: Add custom logs to CloudWatch? 【发布时间】:2017-10-18 13:02:35 【问题描述】:

如何将自定义日志添加到 CloudWatch?默认日志已发送,但如何添加自定义日志?

我已经添加了这样的文件:(在 .ebextensions 中)

files:
  "/opt/elasticbeanstalk/tasks/bundlelogs.d/applogs.conf" :
    mode: "000755"
    owner: root
    group: root
    content: |
      /var/app/current/logs/*

  "/opt/elasticbeanstalk/tasks/taillogs.d/cloud-init.conf" :
    mode: "000755"
    owner: root
    group: root
    content: |
      /var/app/current/logs/*

正如我所做的 bundlelogs.d 和 taillogs.d 一样,这些自定义日志现在可以从控制台或 Web 进行跟踪或检索,这很好,但它们不会持续存在并且不会在 CloudWatch 上发送。

在 CloudWatch 中,我有默认日志,例如/aws/elasticbeanstalk/InstanceName/var/log/eb-activity.log 我还想要一个这样的/aws/elasticbeanstalk/InstanceName/var/app/current/logs/mycustomlog.log

【问题讨论】:

【参考方案1】:

bundlelogs.dtaillogs.d 都是从管理控制台检索的日志。您想要做的是将默认日志(例如 eb-activity.log)扩展到 CloudWatch Logs。为了扩展日志流,您需要在/etc/awslogs/config/ 下添加另一个配置。配置应遵循Agent Configuration file Format。

我已经成功地为我的自定义 ubuntu/nginx/php 平台扩展了我的日志。这是我的extension file 仅供参考。这是official sample仅供参考。

在你的情况下,它可能是这样的

files:
  "/etc/awslogs/config/my_app_log.conf" :
    mode: "000600"
    owner: root
    group: root
    content: |
      [/var/app/current/logs/xxx.log]
      log_group_name = `"Fn::Join":["/", ["/aws/elasticbeanstalk",  "Ref":"AWSEBEnvironmentName" , "var/app/current/logs/xxx.log"]]`
      log_stream_name = instance_id
      file = /var/app/current/logs/xxx.log*

【讨论】:

这看起来像我需要的!谢谢塞巴斯蒂安! @Joël 谢谢。这仍然对我不起作用,但我后来想出了一种方法来完成这项工作。我必须附加或扩展 Elastic Beanstalk 服务角色(实例配置文件)的策略,以添加更多权限来处理 CloudWatch 日志。之后他们神奇地出现在 Cloudwatch 中。 您能解释一下log_group_name 的复杂功能吗? (found some documentation)。请告诉我 "Ref":"AWSEBEnvironmentName" 部分是否可以在log_stream_name 中使用,这是我需要做的。还有哪些"Ref" 值是可能的? @TorstenEngelbrecht 您能否告知您附加到 Elastic Beanstalk 服务角色的策略。我遇到了和你一样的问题。 @Arun 我认为此链接涵盖了要使用的政策:docs.aws.amazon.com/elasticbeanstalk/latest/dg/…。【参考方案2】:

应归功于Sebastian Hsu 和Abhyudit Jain。

这是我为.ebextensions 为我们的特定用例提出的最后一个config 文件。解释某些方面的注释在代码块下方。

files:
  "/etc/awslogs/config/beanstalklogs_custom.conf" :
    mode: "000600"
    owner: root
    group: root
    content: |
      [/var/log/tomcat8/catalina.out]
      log_group_name = `"Fn::Join":["/", ["/aws/elasticbeanstalk",  "Fn::Select" : [ "1",  "Fn::Split" : [ "-",  "Ref":"AWSEBEnvironmentName"  ]  ] , "var/log/tomcat8/catalina.out"]]`
      log_stream_name = `"Fn::Join":["--", [ "Ref":"AWSEBEnvironmentName" , "instance_id"]]`
      file = /var/log/tomcat8/catalina.out*

services:
  sysvinit:
    awslogs:
      files:
        - "/etc/awslogs/config/beanstalklogs_custom.conf"

commands:
  rm_beanstalklogs_custom_bak:
    command: "rm beanstalklogs_custom.conf.bak"
    cwd: "/etc/awslogs/config"
    ignoreErrors: true

log_group_name

我们的 EB 环境有一个标准命名方案,即 environmentName-environmentType。我使用 "Fn::Split" : [ "-", "Ref":"AWSEBEnvironmentName" ] 将其拆分为两个字符串(名称和类型)的数组。

然后我使用 "Fn::Select" : [ "1", <<SPLIT_OUTPUT>> ] 来获取类型字符串。您的需求显然会有所不同,因此您可能只需要以下内容:

      log_group_name = `"Fn::Join":["/", ["/aws/elasticbeanstalk",  "Ref":"AWSEBEnvironmentName" , "var/log/tomcat8/catalina.out"]]`

log_stream_name

我正在使用Fn::Join 函数将EB 环境名称与实例ID 连接起来。请注意,实例 ID 模板是一个字符串,它完全按照给定的方式回显。

服务

部署自定义conf 文件时,awslogs 服务会自动重启。

命令

files 块覆盖现有文件时,它会创建一个备份文件,例如beanstalklogs_custom.conf.bak。此块会擦除该备份文件,因为awslogs 服务会读取两个文件,可能会导致冲突。

结果

如果您登录到 EC2 实例并sudo cat 文件,您应该会看到类似这样的内容。请注意,所有Fn 函数都已解决。如果您发现 Fn 函数没有解析,请检查它是否有语法错误。

[/var/log/tomcat8/catalina.out]
log_group_name = /aws/elasticbeanstalk/environmentType/var/log/tomcat8/catalina.out
log_stream_name = environmentName-environmentType--instance_id
file = /var/log/tomcat8/catalina.out*

【讨论】:

旁注:您可以使用 AWS CLI 和一个名为 cwtail 的小实用程序来跟踪收集的日志。 我遵循相同的步骤并重复使用您的答案中提到的代码,但我在 /etc/awslogs/config 下找不到文件 beanstalklogs_custom.conf。我的 war 文件根目录中的 .ebextensions 文件夹。 eb 活动日志不显示任何错误。有什么具体要检查的吗? 似乎前缀“/etc/awslogs/config”对于让日志显示在 CloudWatch 中很重要。 感谢您指出备份文件,这个问题把我逼疯了!!! EB 一直使用备份中的配置而不是正常配置,因此它始终使用“以前的构建”配置。 awslogs 会知道使用文件“beanstalklogs_custom.conf”而不是“beanstalklogs.conf”吗?还是两者都读?【参考方案3】:

awslogs 代理在配置文件中查找它应该发送的日志文件。其中有一些默认值。您需要对其进行编辑并指定文件。

您可以检查和编辑位于以下位置的配置文件:

/etc/awslogs/awslogs.conf

确保重启服务:

sudo service awslogs restart

您可以在那里指定您自己的文件,并创建不同的组等等。

请参考以下链接,您将能够立即获得您的日志。

资源:

https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AgentReference.html

编辑:

由于您不想编辑实例上的文件,您可以将相关代码添加到代码根目录下的 .ebextensions 文件夹中。例如,这是我的01_cloudwatch.config

packages:
  yum:
    awslogs: []

container_commands:
  01_get_awscli_conf_file:
    command: "aws s3 cp s3://project/awscli.conf /etc/awslogs/awscli.conf"
  02_get_awslogs_conf_file:
    command: "aws s3 cp s3://project/awslogs.conf.$NODE_ENV /etc/awslogs/awslogs.conf"
  03_restart_awslogs:
    command: "sudo service awslogs restart"
  04_start_awslogs_at_system_boot:
    command: "sudo chkconfig awslogs on"

在此配置中,我根据 NODE_ENV 从 S3 存储桶中获取适当的配置文件。你可以在你的配置中做任何你想做的事情。

【讨论】:

谢谢 Abhyudit,但因为它是一个 Elastic Beanstalk 实例,所以我无法直接编辑文件...可以随时删除/替换实例! @Joël 您不必在实例上编辑文件。您必须将这些命令添加到 .ebextensions 中,并且无论何时部署代码,它都会处理这些。查看编辑。【参考方案4】:

查看 AWS 文档并不是很明显,但您需要做一些事情。

(我们的环境是 Amazon Linux AMI - Ruby 2.6 Puma 平台上的 Rails 应用程序)。

首先,在 IAM 中创建一个策略,让您的 EB 生成的 EC2 实例能够访问 CloudWatch 日志组并流式传输到它们 - 我们将其命名为“EB-Cloudwatch-LogStream-Access”。


    "Version": "2012-10-17",
    "Statement": [
        
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:DescribeLogStreams",
                "logs:CreateLogGroup",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:log-group:/aws/elasticbeanstalk/*:log-stream:*"
        
    ]

创建此内容后,请确保将策略附加(在 IAM > 角色中)到与您的 EB 环境关联的 IAM 实例配置文件服务角色 (检查环境的配置页面:配置 > 安全 > IAM 实例配置文件 | 服务角色)。

然后,在您的.ebextensions 目录中提供一个.config 文件,例如setup_stream_to_cloudwatch.config0x_setup_stream_to_cloudwatch.config。在我们的项目中,我们通过为0x 设置一个较高的数字(例如09_setup_stream_to_cloudwatch.config),使其成为部署期间运行的最后一个扩展.config 文件。

然后,提供以下内容,将 your_log_file 替换为适当的文件名,请记住,某些日志文件位于 Amazon Linux AMI 上的 /var/log 中,而某些(例如由您的应用程序生成的)可能位于路径如/var/app/current/log:

files:
  '/etc/awslogs/config/logs.conf':
    mode: '000600'
    owner: root
    group: root
    content: |
      [/var/app/current/log/your_log_file.log]
      log_group_name = `"Fn::Join":["/", ["/aws/elasticbeanstalk",  "Ref":"AWSEBEnvironmentName" , "var/app/current/log/your_log_file.log"]]`
      log_stream_name = instance_id
      file = /var/app/current/log/your_log_file.log*
commands:
  "01":
    command: chkconfig awslogs on
  "02":
    command: service awslogs restart # note that this works for Amazon Linux AMI only - other Linux instances likely use `systemd`

部署你的应用程序,你应该已经准备好了!

【讨论】:

【参考方案5】:

这里已经有一些很好的答案。

我在一个新的Medium blog 中详细介绍了这一切的工作原理以及一个示例 .ebextensions 文件及其放置位置。

以下是您可能会使用的摘录,该文章解释了如何确定要流式传输的正确文件夹/文件。

请注意,如果 /var/app/current/logs/* 包含许多不同的文件,这可能不起作用,例如如果你有

数据库.log 应用程序日志 随机日志

那么你应该考虑为每个添加一个流,但是如果你有

app.2021-10-18.log app.2021-10-17.log app.2021-10-16.log

然后你可以使用 /var/app/current/logs/app.*

packages:
  yum:
    awslogs: []

option_settings:
  - namespace: aws:elasticbeanstalk:cloudwatch:logs
    option_name: StreamLogs
    value: true
  - namespace: aws:elasticbeanstalk:cloudwatch:logs
    option_name: DeleteOnTerminate
    value: false
  - namespace: aws:elasticbeanstalk:cloudwatch:logs
    option_name: RetentionInDays
    value: 90

files:
  "/etc/awslogs/awscli.conf" :
    mode: "000600"
    owner: root
    group: root
    content: |
      [plugins]
      cwlogs = cwlogs
      [default]
      region = `"Ref":"AWS::Region"`

  "/etc/awslogs/config/logs.conf" :
    mode: "000600"
    owner: root
    group: root
    content: |
      [/var/app/current/logs]
      log_group_name = `"Fn::Join":["/", ["/aws/elasticbeanstalk",  "Ref":"AWSEBEnvironmentName" , "/var/app/current/logs"]]`
      log_stream_name = instance_id
      file = /var/app/current/logs/*

commands:
  "01":
    command: systemctl enable awslogsd.service
  "02":
    command: systemctl restart awslogsd

【讨论】:

以上是关于AWS Elastic Beanstalk:将自定义日志添加到 CloudWatch?的主要内容,如果未能解决你的问题,请参考以下文章

将第三方域映射到 aws elastic beanstalk

AWS Elastic Beanstalk:将容器日志流式传输到 CloudWatch 问题

将 Namecheap 域添加到 AWS Elastic Beanstalk

将后台工作人员添加到 AWS Elastic Beanstalk

将 AWS Elastic beanstalk 部署到不同区域的环境

如何将 express react 应用程序部署到 aws elastic beanstalk?