1.概述
前面两篇文章分别描述了将链路追踪信息存储到MySQL和存储到Kafka和Logstash中,本文将基于上文的基础上,演示将链路追踪数据直接存储到logstash中,并通过kibana进行日志搜索查看。
2.Sleuth+Zipkin+ELK整合
本文与上篇文章的主要区别在于:上文在业务服务与logstash之间增加了一个消息中间件Kafka。事实上,也可以直接通过logback的一个TCP Appender将产生结构化的Json日志数据发送到logstash监听的TCP端口,然后由logstash将收到的日志信息再发送到elasticsearch,最后可以结合Kibana进行链路追踪信息可视化展示,具体架构图如下所示:
2.1 配置Logback
2.1.1 引入pom文件
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>6.3</version>
</dependency>
这个pom文件的主要作用如下:
1.提供logback的编码器,布局(layouts)和追加器,来输出到json形式的日志;
2.logstash原始输入就支持输入成json形式,但是logstash的json形式输出已经发展成更高的可配置性,更加常用化的json形式日志输出器(当然是指输出到elasticsearch和其他接收者),json输出的结构和json包含的结构是完全可控制的。
说的简单一点就是定义指定格式的json日志,写入到logstash,便于logstash解析。
2.1.2 配置logback
logback中核心配置代码如下:
<appender name="LOGSTASH_PATTERN" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>192.168.228.130:9250</destination> <!-- Logstash的ip和端口,logback就是通过这个地址把日志发送给logstash-->
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<pattern>
<!--这里是具体的日志格式,包含链路信息日志级别、服务名称、traceId、spanId、parentId、产生日志的进程、线程、所在类等-->
<pattern>
{
"severity": "%level",
"service": "${springAppName:-}",
"trace": "%X{X-B3-TraceId:-}",
"span": "%X{X-B3-SpanId:-}",
"parent": "%X{X-B3-ParentSpanId:-}",
"exportable": "%X{X-Span-Export:-}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"rest": "%message"
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>
<!-- 不同环境使用不同的输出 </root>-->
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="DEBUG_FILE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="WARN_FILE"/>
<appender-ref ref="ERROR_FILE"/>
<appender-ref ref="LOGSTASH_PATTERN"/>
</root>
至此,我们业务服务所需要的内容已经配置完成了,所有参与调用的服务都需要配置此内容。
2.2 编写logstash配置文件
2.2.1 log-to-es.config
input{
// 监听一个9250的TCP端口接收数据
tcp {
mode => "server"
host => "0.0.0.0"
port => 9250
}
}
filter {
ruby {
code => "event.set('timestamp',event.get('@timestamp').time.localtime + 8*60*60)"
}
ruby {
code => "event.set('timestamp',event.get('timestamp'))"
}
mutate {
remove_field => ['timestamp']
}
}
output {
//输出到elasticsearch的地址
elasticsearch {
hosts => ["192.168.228.130:9200"]
index => "applog"
}
}
2.2.2 启动logstash
利用下述命令启动logstash:
nohup ./bin/logstash -f ./config/log-to-es.conf &
logstash启动成功之后,会默认在ES中创建一个 applog* 的索引模版。
2.3 测试应用
分别启动gateway-server(网关服务)、eureka-server(主注册中心)、eureka-server01(从注册中心)、MicroService1(服务1,负责调用服务2和服务3)、MicroService2(服务2,商品服务)和MicroService3(服务3,订单服务)。在kabana中创建索引,如下图所示:
设置索引模式名,创建时会默认搜索elasticsearch中已存在的索引,elasticsearch存在才能创建。此处创建的索引实质上是建立kibana与elasticsearch的索引关联,并不是直接在elasticsearch中创建索引。
选择一个字段来过滤日志,这里选择时间戳作为过滤条件。
索引创建成功后,会显示索引的一些信息,如下图所示:
请求一次服务地址:
http://{网关服务ip}:9000/micro-service1/micro1/productLists
整个调用的链路信息都被收集到elk中,通过kibana查看链路日志信息如下:
3.小结
1.本文主要演示了配置logback将产生的链路追踪数据直接存储到logstash中,需要注意的是要在logback中配置logstash的地址,以及日志格式;
2.logstash需要监听日志发送的端口,方便日志收集与转化,同时指定过滤完成后需要发送的elasticsearch地址;
3.kibana在关联elasticsearch,需要通过创建索引关联。
4.参考文献
1.https://www.jianshu.com/p/a26da0c55255
5.附录
1.https://gitee.com/Marinc/spring-boot-sleuth-zipkin