来自 ECS/EC2 上运行的容器化应用程序的 CloudWatch 多行日志消息

问题描述 投票:0回答:2

我有一个 Web Api (.Net Core 3.0),在 AWS 集群 (ECS) 上运行,带有 EC2 实例。在任务定义中,我在容器中配置了 awslog 驱动程序以将日志写入特定日志组/区域。

我遇到与 Web API 发出的多行日志消息相关的问题(每一行在 CloudWatch 中的不同日志消息中显示为 splittend)。经过研究,我找到了似乎与此事相关的信息,但有些地方我不确定。

我发现了一些有关 CloudWatch Agent 的信息,这些信息似乎与多行配置相关。 CloudWatch Agent 是否与我的容器化 Web API 发出的日志消息相关?我的意思是,我的 Web API 向控制台发送日志,并通过 awslog 驱动程序将它们自动抛出到 CloudWatch Logs。所以,我不知道特工在这种情况下是否会做任何事情。

重点是,在 CloudWatch Agent 文档中,我读到了与配置文件相关的内容,该文件似乎与多行问题相关:

multi_line_start_pattern:指定用于识别日志消息开始的模式”

我不知道Agent与awslog驱动程序有什么关系。关于 awslog 驱动程序,我发现这些与多行问题相关的属性可以包含在我的任务定义中:

awslogs-multiline-pattern:此选项使用正则表达式定义多行起始模式”

awslogs-datetime-format:此选项定义 Python strftime 格式的多行开始模式”

那么,CloudWatch Agent 和 awslog 驱动程序配置都可以解决多行问题吗?他们有关系吗?它们适用于不同的范围?

提前致谢。

amazon-web-services docker amazon-ec2 amazon-cloudwatchlogs
2个回答
4
投票

有同样的问题。通过在 logdriver 配置上使用 awslogs-multiline-pattern 属性修复了该问题。

我的应用程序具有 JSON 日志,这些日志可以是 INFO、DEBUG、WARN、ERROR 或 CRITICAL,因此使用此属性,我将每个日志分类为自己的行,如下所示:

LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-region: !Ref AWS::Region
              awslogs-group: some group
              awslogs-stream-prefix: ecs
              awslogs-multiline-pattern: '^(INFO|DEBUG|WARN|ERROR|CRITICAL)'

这是使用多行模式之前的样子:

这是之后:

希望有帮助。


0
投票

@Paras Thakur 的回答仅部分正确,而且原因错误。它引入了一个新问题,即日志在 CW 代理转储之前不会被发送(可能是因为占用了太多内存),在这种情况下,可能有数百个日志将具有相同的时间戳,并且可能会很晚到达。它们 do 被分成各自的消息,但我不认为这是明确的,因为如果正则表达式 - @Paras Thakur 的示例输出清楚地显示实际没有使用分隔符。

完整的解决方案是为日志添加正确的日志级别前缀。以 NodeJS 为例,我认为很多使用 Lambda 的人会认为

console.info
console.error
会为您创建前缀,但这是对 AWS 提供的 Lambda 运行时的自定义

在 ECS 中,您必须自己添加该前缀,因为您已经定义了 docker 映像,而不是 AWS。

在 TypeScript 中你可以像这样创建一个助手:

const log = {
    info(...args: Array<any>){
        console.log('INFO', ...args);
    },
    error(...args: Array<any>){
        console.log('ERROR', ...args);
    }
}

log.info('my log', some_object) // "INFO my log { a: 1 }" ...

这里的时间戳是正确的(注意

INFO
分隔符的存在)

作为奖励,在 AWS CDK 中,这看起来像:

taskDefinition.addContainer('MyContainer', {
    image: ecs.ContainerImage.fromDockerImageAsset(asset),
    memoryLimitMiB: 512,
    cpu: 256,
    logging: new ecs.AwsLogDriver({
        streamPrefix: 'my-logs',
        multilinePattern: '^(INFO|DEBUG|WARN|ERROR|CRITICAL)'
    })
});
© www.soinside.com 2019 - 2024. All rights reserved.