【发布时间】:2018-05-06 20:36:58
【问题描述】:
我的多行日志记录事件都以多事件结尾 - 每行一个事件。根据documentation:
对 LambdaLogger.log() 的每次调用都会导致 CloudWatch Logs 事件...
然后:
但是,请注意 AWS Lambda 会处理 System.out 返回的每一行 和 System.err 作为一个单独的事件。
查看LambdaAppender's source code 内部,它似乎继续将事件记录到System.out。那么这是否意味着多行消息总是会被分解为多个事件?
我已阅读有关配置 multi_line_start_pattern 的信息,但这似乎仅适用于您部署日志代理时,无法在 Lambda 中访问。
[编辑]LambdaAppender 记录到LambdaLogger,后者记录到System.out。
[编辑] 我发现了一些建议解决方法的帖子 - 在打印消息时使用 '\r' 作为 eol。这似乎适用于我的代码产生的消息。随处记录的堆栈跟踪仍然是个问题。
[编辑] 我一直在使用两种解决方法:
- 以 JSON 格式记录复杂的数据结构(例如,相当大的地图)。 CloudWatch 实际上可以识别日志事件中的 JSON 字符串,并漂亮地打印出来。
-
将“\n”替换为“\r”。对于堆栈跟踪,我创建了一个实用方法(这是在 Kotlin 中,但这个想法足够通用):
fun formatThrowable(t: Throwable): String { val buffer = StringWriter() t.printStackTrace(PrintWriter(buffer)) return buffer.toString().replace("\n", "\r") }
我认为从长远来看,更理想的解决方案是使用 Appender 实现来装饰 ConsoleAppender,这将对所有通过的消息进行 \r 替换。
【问题讨论】:
-
你在哪里看到它写信给
System.out?因为我看到它写入LambdaLogger实例,这是非分布式 AWS 运行时代码的一部分。 -
如果我没看错,
LambdaLogger源实际上在同一个项目中:github.com/aws/aws-lambda-java-libs/blob/master/…。 -
您当然似乎是正确的——在发表评论之前,我没有花时间查看 repo 中的其他项目。但是,我知道(或至少相信)我看到一个异常记录在与主要消息相同的 CloudWatch 事件中。这让我想知道
System.out是否可能是 AWS 特定的PrintStream,它基于写入而不是换行进行刷新。这完全是我的猜测,但很容易通过 (1)Class.getName()和 (2) 打印带有嵌入换行符的字符串来验证。
标签: amazon-web-services logging aws-lambda amazon-cloudwatch amazon-cloudwatchlogs