我们都有过上机器查日志的经历,当集群数量增多的时候,这种原始的操作带来的低效率不仅给我们定位现网问题带来极大的挑战,同时,我们也无法对我们服务框架的各项指标进行有效的量化诊断,更无从谈有针对性的优化和改进。这个时候,构建具备信息查找,服务诊断,数据分析等功能的实时日志监控系统尤为重要。

ELK (ELK Stack: ElasticSearch, LogStash, Kibana, Beats) 是一套成熟的日志解决方案,其开源及高性能在各大公司广泛使用。而我们业务所使用的服务框架,如何接入 ELK 系统呢?
业务背景
我们的业务框架背景:
我们将整个框架接入 ELK 简单归纳为下面几个步骤:
一、日志结构设计
传统的,我们在做日志输出的时候,是直接输出日志的等级(level)和日志的内容字符串(message)。然而我们不仅关注什么时间,发生了什么,可能还需要关注类似的日志发生了多少次,日志的细节与上下文,以及关联的日志。 因此我们不只是简单地将我们的日志结构化一下为对象,还要提取出日志关键的字段。
1. 将日志抽象为事件
我们将每一条日志的发生都抽像为一个事件。事件包含:
事件元字段
请求元字段
数据字段
不同类型的事件,需要输出的细节不尽相同,我们将这些细节(非元字段)统一放到d -- data,之中。使我们的事件结构更加清晰,同时,也能避免数据字段对元字段造成污染。
e.g. 如 client-init事件,该事件会在每次服务器接收到用户请求时打印,我们将用户的 ip, url等事件独有的统一归为数据字段放到 d 对象中
举个完整的例子
{
"datetime":"2018-11-07 21:38:09.271",
"timestamp":1541597889271,
"level":"INFO",
"event":"client-init",
"reqId":"rJtT5we6Q",
"reqLife":5874,
"reqUid": "999793fc03eda86",
"d":{
"url":"/",
"ip":"9.9.9.9",
"httpVersion":"1.1",
"method":"GET",
"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
"headers":"*"
},
"browser":"{"name":"Chrome","version":"70.0.3538.77","major":"70"}",
"engine":"{"version":"537.36","name":"WebKit"}",
"os":"{"name":"Mac OS","version":"10.14.0"}",
"content":"(Empty)",
"line":"middlewares/foo.js:14",
"server":"127.0.0.1"
}