AWS Elastic Beanstalk:将自定义日志添加到 CloudWatch?
AWS Elastic Beanstalk: Add custom logs to CloudWatch?
如何将自定义日志添加到 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
awslogs
代理在配置文件中查找它应该发送的日志文件。其中有一些默认值。您需要对其进行编辑并指定文件。
您可以检查和编辑位于以下位置的配置文件:
/etc/awslogs/awslogs.conf
确保重启服务:
sudo service awslogs restart
您可以在那里指定自己的文件并创建不同的组等等。
请参考以下link,您将能够立即获得您的日志。
资源:
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 存储桶中获取适当的配置文件。你可以在你的配置中做任何你想做的事情。
bundlelogs.d 和 taillogs.d 都是从管理控制台检索的日志。您要做的是将默认日志(例如 eb-activity.log)扩展到 CloudWatch Logs。为了扩展日志流,需要在/etc/awslogs/config/
下再增加一个配置。配置应该遵循Agent Configuration file Format。
我已经成功地为我的自定义 ubuntu/nginx/php 平台扩展了我的日志。这是我的 extension file FYI. Here is an 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*
归功于 and 。
这是我为我们的特定用例 .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 文档并不能立即看出这一点,但您需要做一些事情。
(我们的环境是 Amazon Linux AMI - Rails Ruby 2.6 Puma 平台上的应用程序。
首先,在 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 > 角色中)到您的 IAM 实例配置文件 和 服务角色 与您的 EB 环境相关联(检查环境的配置页面:Configuration > Security > IAM instance profile | Service Role)。
然后,在您的 .ebextensions
目录中提供一个 .config
文件,例如 setup_stream_to_cloudwatch.config
或 0x_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`
部署您的应用程序,您应该设置好了!
这里已经有一些很好的答案。
我在新的 Medium blog 中详细介绍了这一切的工作原理以及示例 .ebextensions 文件以及放置位置。
以下是您可能会用到的摘录,文章解释了如何确定 folder/file(s) 的直播权。
请注意,如果 /var/app/current/logs/* 包含许多不同的文件,这可能不起作用,例如如果你有
database.log
app.log
random.log
那么你应该考虑为每个添加一个流,但是如果你有
app.2021-10-18.log
应用程序.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
如何将自定义日志添加到 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
awslogs
代理在配置文件中查找它应该发送的日志文件。其中有一些默认值。您需要对其进行编辑并指定文件。
您可以检查和编辑位于以下位置的配置文件:
/etc/awslogs/awslogs.conf
确保重启服务:
sudo service awslogs restart
您可以在那里指定自己的文件并创建不同的组等等。
请参考以下link,您将能够立即获得您的日志。
资源:
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 存储桶中获取适当的配置文件。你可以在你的配置中做任何你想做的事情。
bundlelogs.d 和 taillogs.d 都是从管理控制台检索的日志。您要做的是将默认日志(例如 eb-activity.log)扩展到 CloudWatch Logs。为了扩展日志流,需要在/etc/awslogs/config/
下再增加一个配置。配置应该遵循Agent Configuration file Format。
我已经成功地为我的自定义 ubuntu/nginx/php 平台扩展了我的日志。这是我的 extension file FYI. Here is an 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*
归功于
这是我为我们的特定用例 .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 文档并不能立即看出这一点,但您需要做一些事情。
(我们的环境是 Amazon Linux AMI - Rails Ruby 2.6 Puma 平台上的应用程序。
首先,在 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 > 角色中)到您的 IAM 实例配置文件 和 服务角色 与您的 EB 环境相关联(检查环境的配置页面:Configuration > Security > IAM instance profile | Service Role)。
然后,在您的 .ebextensions
目录中提供一个 .config
文件,例如 setup_stream_to_cloudwatch.config
或 0x_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`
部署您的应用程序,您应该设置好了!
这里已经有一些很好的答案。
我在新的 Medium blog 中详细介绍了这一切的工作原理以及示例 .ebextensions 文件以及放置位置。
以下是您可能会用到的摘录,文章解释了如何确定 folder/file(s) 的直播权。
请注意,如果 /var/app/current/logs/* 包含许多不同的文件,这可能不起作用,例如如果你有
database.log app.log random.log
那么你应该考虑为每个添加一个流,但是如果你有
app.2021-10-18.log 应用程序.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