将Python日志记录器添加到Fargate中流式传输日志到CloudWatch

4
我有一个装有Python 3.8脚本的Docker容器,并通过Airflow(ECSOperator)在AWS Fargate上执行。该脚本使用任务定义中定义的awslog驱动程序将多个日志流式传输到Cloudwatch。我能够在Cloudwatch中正确地看到所有日志,但问题是日志始终附加在主日志消息中,也就是说,我的日志在另一个日志消息中显示。
以下是一条日志的示例,其中前3列是自动注入的,而消息的其余部分是指我的自定义日志:
[2021-11-04 17:23:22,026] {{ecs.py:317}} INFO - [2021-11-04T17:22:47.719000] 2021-11-04 17:22:47,718 - myscript - WARNING - testing log message

因此,无论我设置哪个日志级别,第一条日志消息始终为INFO。这似乎是Fargate自动添加的内容。我希望我的日志消息能够直接流式传输到Cloudwatch,而不被传递到另一个日志消息中,只需:

[2021-11-04T17:22:47.719000] 2021-11-04 17:22:47,718 - myscript - WARNING - testing log message

我认为我没有正确配置记录器,或者需要获取另一个记录器,但我不知道如何正确操作。这是我遵循的一些方法以及我得到的结果。

打印信息

如果在我的代码中使用打印命令,日志消息会被放置在标准输出(stdout)中,因此它们通过awslog驱动程序流式传输到Cloudwatch。

[2021-11-04 17:23:22,026] {{ecs.py:317}} INFO - testing log message

无需配置的日志记录

如果我使用已配置任何ConsoleHandler或StreamHandler的记录器,生成的日志信息与使用print创建的信息相同。

import logging
logger = logging.getLogger(__name__)
logger.warning('testing log message')

[2021-11-04 17:23:22,026] {{ecs.py:317}} INFO - testing log message

使用 StreamHandler 记录日志

如果我使用格式化程序配置一个 StreamHandler ,那么我的日志将连接到主要日志中,如前所述。因此,它只会用新的格式化日志消息替换字符串消息(最后一列)。

import logging
logger = logging.getLogger(__name__)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.warning('testing log message')

[2021-11-04 17:23:22,026] {{ecs.py:317}} INFO - [2021-11-04T17:22:47.719000] 2021-11-04 17:22:47,718 - myscript - WARNING - testing log message

以下是任务定义中定义的日志配置:

"logConfiguration": {
   "logDriver": "awslogs",
   "secretOptions": [],
   "options": {
      "awslogs-group": "/ecs/my-group",
      "awslogs-region": "eu-west-1",
      "awslogs-stream-prefix": "ecs"
}

编辑 1

我一直在调查Cloudwatch日志,发现这些日志流式传输到两个不同的日志组,因为我正在使用Airflow启动fargate。

  • Airflow组:Airflow会自动创建一个名为<airflow_environment>-Task的日志组,将任务生成的日志放在这里。在这里,似乎Airflow将我的自定义日志包装在它自己的日志中,这些日志始终是INFO级别。当从Airflow UI可视化日志时,它显示来自此日志组获取的日志。

  • ECS组:这是在TaskDefinition中定义的日志组(/ecs/my-group)。在该组中,日志会按原样流式传输,而不进行包装。

因此,问题似乎出在Airflow上,因为它将日志包装在自己的记录器中,并在Airflow UI中显示这些日志。无论如何,日志在TaskDefinition中定义的日志组中已正确传递和格式化。

1个回答

0

可能有点晚了,你可能已经解决了,但我认为解决方案在这里。可能Fargate像Lambda一样预先配置了日志处理程序,考虑到任务定义中有awslogs的配置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接