结构化日志,顾名思义不再是自由格式的日志,而是遵循了一定的结构:每一行日志就是一个JSON结构。好处显而易见:简化日志解析,使得日志的后续处理、分析或查询变得方便高效。
和结构化日志形成对比的就是传统的日志:一行或多行的字符串,字段之间主要是用空格等分隔符分隔开,输出格式自由定义。譬如下面是一个JAVA Spring-boot应用的几行日志:
所谓的输出格式可以自由定义意味着需要给上面这样的日志设置输出格式成:
%d{yyyy-MM-dd HH:mm:ss.SSS} %level ${application_name} trace=%X{X-B3-TraceId},span=%X{X-B3-SpanId} <%t> %c{40} - %msg%n
这种日志可以叫做是扁平化日志(flat log),缺点是不方便被ELK等日志系统处理,譬如Logstash里得配置grok正则表达式做好解析工作,转换出来的其实就是结构化了的日志,日志发送到Elasticsearch,然后我们就能跑Kibana里去查询。(既然最终发到Elasticsearch的就是结构化日志,那么干脆去掉解析?)。很明显,Logstash所做的解析的正确可靠与否对后续的日志分析和查找至关重要,其中的关键之一是grok正则表达式必须正确。问题在于正则表达式并不太好写,那么多日志格式,每种日志的每一个字段都要把grok正则表达式写正确才能解析,听上去就头大,写得正确不容易,写得要效率高更不容易,所以维护grok正则表达式是个又累又烦还容易出错的‘脏活’。到了现实中,大家还会这么想:反正Elasticsearch可以做全文检索,解析得精确不精确不会导致没法继续干活,那就不如不做解析直接扔给Elasticsearch得了。所以,在现实中,能做到把其中几个关键字段解析出来已经算是可以的了,根本就没有解析都不算少见 – 常常是把整行日志作为一坨文本直接扔给了ELK,于是Kibana上查出来的日志就会这模样:
上面这条日志,连日志的时间和级别这样的基础字段都是混在了日志消息字段