我有一个 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 驱动程序配置都可以解决多行问题吗?他们有关系吗?它们适用于不同的范围?
提前致谢。
有同样的问题。通过在 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)'
这是使用多行模式之前的样子:
这是之后:
希望有帮助。
@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)'
})
});