我们项目使用Dropwizard框架构建了一个API服务,服务运行在AWS的ECS上,该ECS服务关联了CloudWatch的一个LogGroup。
最近在定位问题的时候,发现日志中存在这样的现象,当服务打印的一条日志有多行文本,那么在Loggroup里会将该条日志截断为多个LogEvent,每一行生成一个LogEvent。
上图中error message是一段html,属于第一行的Log,但是被分成多个LogEvent。这样日志看起来不连续,阅读起来不方便。
通过查询CloudWatch的文档,发现AWS提供一个配置项,可以指定生成LogEvent的分割标记
- multi_line_start_pattern
Specifies the pattern for identifying the start of a log message. A log message is made of a line that matches the pattern and any following lines that don’t match the pattern. The valid values are regular expression or {datetime_format}. When using {datetime_format}, the datetime_format option should be specified. The default value is ‘^[^\s]’ so any line that begins with non-whitespace character closes the previous log message and starts a new log message.
可以看到在不指定datetime_format选项的前提下,系统使用multi_line_start_pattern来决定一条日志的起始和结束行。
multi_line_start_pattern的默认值是^[^\s]
,意味着一条LogEvent的起始行为以非空白字符打头的行,直到下一个以非空白字符打头的行。
如果同时指定datetime_format和multi_line_start_pattern,系统将优先选择datetime_format。
我们项目后面就是通过归一API服务的日志时间格式和CloudWatch日志时间格式,来达到让CloudWatch生成的LogEvent和原始日志条目相同的目的。
服务中配置日志Layout
ECS的容器日志格式配置