Python CloudWatch Logging
项目描述
Watchtower是Amazon Web Services CloudWatch Logs的日志处理器。
CloudWatch Logs是AWS内置的日志管理服务。它在概念上类似于Splunk、Datadog和Loggly等服务,但更轻量级、更便宜,并与AWS的其余部分紧密集成。
反过来,Watchtower是Python日志系统和CloudWatch Logs之间的轻量级适配器。它使用boto3 AWS SDK,并允许您直接将应用程序日志连接到CloudWatch,无需安装系统范围的日志收集器如awscli-cwlogs,并绕过实例的syslog进行日志轮转。它将日志汇总成批次,以避免为每条日志消息发送API请求,同时保证交付截止日期(默认为60秒)。
安装
pip install watchtower
概述
安装awscli并设置您的AWS凭证(运行aws configure)。
import watchtower, logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
logger.addHandler(watchtower.CloudWatchLogHandler())
logger.info("Hi")
logger.info(dict(foo="bar", details={}))
运行示例后,您可以在AWS控制台的watchtower日志组下查看日志输出。
IAM权限
运行Watchtower进程需要访问IAM凭证以调用CloudWatch Logs API。加载和配置凭证的标准程序在Boto3凭证文档中描述。在EC2实例或其他AWS计算资源上运行Watchtower时,boto3会自动从实例元数据(IMDS)或容器凭证提供者(AWS_WEB_IDENTITY_TOKEN_FILE或AWS_CONTAINER_CREDENTIALS_FULL_URI)中加载凭证。为与这些凭证关联的IAM角色授予正确的权限的最简单方法是将AWS管理IAM策略附加到该角色。虽然AWS没有提供通用的管理CloudWatch Logs写入策略,但我们建议您使用具有恰到好处的权限而不太广泛的arn:aws:iam::aws:policy/AWSOpsWorksCloudWatchLogs管理策略。
日志组标记
Watchtower支持日志组的标记。这可以通过将log_group_tags参数添加到CloudWatchLogHandler构造函数中来实现。此参数应是将应用于日志组的标记的字典。
如果您要向日志组添加标记,您需要添加对logs:TagResource操作的权限到您的策略。这需要除AWSOpsWorksCloudWatchLogs策略之外。注意:旧的logs:TagLogGroup权限是用于即将弃用的tag_log_group()调用,而Watchtower不使用该调用。
示例:使用Watchtower进行Flask日志记录
使用以下配置将Flask日志发送到名为“loggable”的CloudWatch Logs流
import watchtower, flask, logging
logging.basicConfig(level=logging.INFO)
app = flask.Flask("loggable")
handler = watchtower.CloudWatchLogHandler(log_group_name=app.name)
app.logger.addHandler(handler)
logging.getLogger("werkzeug").addHandler(handler)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
示例:使用Watchtower进行Django日志记录
这是Watchtower与Django集成的示例。在您的Django项目中,将以下内容添加到settings.py
import boto3
AWS_REGION_NAME = "us-west-2"
boto3_logs_client = boto3.client("logs", region_name=AWS_REGION_NAME)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'root': {
'level': 'DEBUG',
# Adding the watchtower handler here causes all loggers in the project that
# have propagate=True (the default) to send messages to watchtower. If you
# wish to send only from specific loggers instead, remove "watchtower" here
# and configure individual loggers below.
'handlers': ['watchtower', 'console'],
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
'watchtower': {
'class': 'watchtower.CloudWatchLogHandler',
'boto3_client': boto3_logs_client,
'log_group_name': 'YOUR_DJANGO_PROJECT_NAME',
# Decrease the verbosity level here to send only those logs to watchtower,
# but still see more verbose logs in the console. See the watchtower
# documentation for other parameters that can be set here.
'level': 'DEBUG'
}
},
'loggers': {
# In the debug server (`manage.py runserver`), several Django system loggers cause
# deadlocks when using threading in the logging handler, and are not supported by
# watchtower. This limitation does not apply when running on production WSGI servers
# (gunicorn, uwsgi, etc.), so we recommend that you set `propagate=True` below in your
# production-specific Django settings file to receive Django system logs in CloudWatch.
'django': {
'level': 'DEBUG',
'handlers': ['console'],
'propagate': False
}
# Add any other logger-specific configuration here.
}
}
使用此配置,Django的日志将发送到名为YOUR_DJANGO_PROJECT_NAME的日志组中。要在开发中为此配置提供AWS凭证,请使用aws configure设置您的AWS CLI配置文件设置。在生产环境中或在EC2实例上运行时,为您的实例分配IAM角色,这将导致boto3自动从实例元数据中获取IAM角色凭证。
(也请参阅Django日志记录文档。)
示例:查询CloudWatch日志
本节并非特定于Watchtower。它展示了使用awscli和jq在命令行中读取和搜索CloudWatch日志的使用方法。
对于上面的Flask示例,您可以使用以下两个命令检索应用程序日志
aws logs get-log-events --log-group-name watchtower --log-stream-name loggable | jq '.events[].message' aws logs get-log-events --log-group-name watchtower --log-stream-name werkzeug | jq '.events[].message'
除了原始get-log-events API之外,CloudWatch Logs支持将日志提取到S3存储桶,使用查询语言进行日志分析,以及基于度量过滤器的警报和仪表板,这些是提取信息并馈送到警报和仪表板图标的模式规则。如果您想通过命令行使用这些功能,Watchtower的作者已经发布了一个名为aegea的开源CLI工具包,其中包括aegea logs和aegea grep命令,以便轻松访问S3导出和洞察功能。
示例:Python 日志配置
Python 的 logging.config 模块具有提供配置文件的能力,该文件可以被加载以将日志配置与代码分离。
以下是用 PyYAML 加载的两种示例 YAML 配置文件。结果 dict 对象可以随后加载到 logging.config.dictConfig。第一个示例是一个基本示例,它依赖于 boto3 提供的默认配置
# Default AWS Config
version: 1
disable_existing_loggers: False
handlers:
console:
class: logging.StreamHandler
level: DEBUG
stream: ext://sys.stdout
logfile:
class: logging.handlers.RotatingFileHandler
level: DEBUG
filename: watchtower.log
maxBytes: 1000000
backupCount: 3
watchtower:
class: watchtower.CloudWatchLogHandler
level: DEBUG
log_group_name: watchtower
log_stream_name: "{logger_name}-{strftime:%y-%m-%d}"
send_interval: 10
create_log_group: False
root:
level: DEBUG
propagate: True
handlers: [console, logfile, watchtower]
loggers:
botocore:
level: INFO
urllib3:
level: INFO
如果可以使用 boto3 的默认凭证配置,或者依赖于环境变量,上述方法运行良好。然而,有时可能需要为日志使用与用于其他功能的凭证不同的凭证;在这种情况下,可以使用 Watchtower 的 boto3_profile_name 选项来提供 boto3 配置文件名
# AWS Config Profile
version: 1
...
handlers:
...
watchtower:
boto3_profile_name: watchtowerlogger
...
最后,以下展示了如何将配置加载到工作应用程序中
import logging.config
import flask
import yaml
app = flask.Flask("loggable")
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
with open('logging.yml') as log_config:
config_yml = log_config.read()
config_dict = yaml.safe_load(config_yml)
logging.config.dictConfig(config_dict)
app.run()
日志流命名
对于使用进程池的高容量日志应用程序,建议您保留默认的日志流名称({machine_name}/{program_name}/{logger_name}/{process_id}),或者使用这些模板变量的组合使每个源具有唯一性。由于日志必须按顺序提交到每个日志流,因此独立进程向同一日志流发送日志将遇到序列令牌同步错误,并消耗额外资源来自动恢复。随着进程数量的增加,这种开销将增长,直到日志无法传递并丢失(导致在 stderr 上发出警告)。通过按源将日志流分区可以避免这种竞争。
Boto3/botocore/urllib3 日志
因为 watchtower 使用 boto3 发送日志,因此发送日志的行为会产生 boto3 依赖项 botocore 和 urllib3 的许多 DEBUG 级别日志消息。为了避免生成自我维持的日志消息流,watchtower.CloudWatchLogHandler 将一个 过滤器附加到自身,丢弃这些库的所有 DEBUG 级别消息,并在关闭时(特别是在 watchtower.CloudWatchLogHandler.flush() 和 watchtower.CloudWatchLogHandler.close() 中)丢弃所有级别的消息。该过滤器不应用于您可能用于处理消息的任何其他处理程序,因此以下基本配置会导致 botocore 调试日志打印到 stderr 但不会打印到 Cloudwatch
import watchtower, logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger()
logger.addHandler(watchtower.CloudWatchLogHandler())
AWS Lambda
Watchtower 不适用于 AWS Lambda 上运行的应用程序,也不是必需的。所有 AWS Lambda 日志(即 Lambda 运行时打印到 stderr 的所有行)都会自动发送到 CloudWatch Logs,进入 以 /aws/lambda/ 前缀下的日志组。
AWS Lambda 在调用完成后和下一个调用(如果有)之前暂停(冻结)其执行环境中的所有进程。这意味着任何异步后台进程和线程(包括 watchtower),都将被暂停且无法工作,因此 watchtower 不能在执行模型中正常工作。
链接
错误
请在 GitHub 上报告错误、问题、功能请求等。
版本控制
此软件包遵循 语义版本控制 2.0.0 标准。为了控制更改,建议应用程序开发人员固定软件包版本,并使用 pip-tools 或类似工具进行管理。对于库开发人员,建议固定主版本。
许可证
根据 Apache 许可证 2.0 版本许可。
项目详情
下载文件
下载适用于您平台的文件。如果您不确定该选择哪个,请了解有关安装包的更多信息。
源分布
构建分布
watchtower-3.3.1.tar.gz的哈希
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 5e654f52b54b39e279592d6c18a033b22cfbffda676f5b3cf6dfef712ed5738c |
|
MD5 | f41f8cdc0897ec678444e1cca8084290 |
|
BLAKE2b-256 | 7da6a065d12081d72a6de62f19afc895ffa2c20e43fc77596fdb4c06d3cc47bd |
watchtower-3.3.1-py3-none-any.whl的哈希
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 72d4f3f2ec906302e0478c042a2076611eb22f5a491ceda6411fec531aa2ee85 |
|
MD5 | 7bda8a34b1584ce9aaefee82fd7257f8 |
|
BLAKE2b-256 | a38110564975a4fce5af80e275fe7ea322380a214fea47237b643e8bed312102 |