springcloud微服务⽇志跟踪sleuthlogbackelk整合
看过我之前的⽂章的就可以⼀步⼀步搭建起⽇志传输到搜索引擎不知道的看下之前的⽂章
(1)
(2)
(3)
这⾥我们结合sleuth 可以降服务之间的调⽤使⽤唯⼀标识串联起来已达到我们通过⼀个标识可以查看所有跨服务调⽤的串联⽇志,与上⼀篇的MDC不同sleuth 简单原理说下
就是在最初发起调⽤者的时候在请求头head中添加唯⼀标识传递到直接调⽤的服务上⾯
然后之后的服务做类似的操作
好了不多⽐⽐了
上代码
⾸先所有的服务或spring boot项⽬都引⼊以下包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>com.cwbase</groupId>
<artifactId>logback-redis-appender</artifactId>
<version>1.1.5</version>
</dependency>
⼀个是传输redis使⽤⼀个是调⽤链跟踪使⽤
下⾯是logback配置⽂件
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">
<include resource="org/springframework/boot/logging/l"/>
<!-- <jmxConfigurator/> -->
<contextName>logback</contextName>
<property name="log.path" value="\logs\logback.log"/>
<property name="log.pattern"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} -%5p ${PID} --- traceId:[%X{mdc_trace_id}] [%15.15t] %-40.40logger{39} : %m%n"/>
<appender name="file"
class="ch.olling.RollingFileAppender">
<file>${log.path}</file>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<rollingPolicy class="ch.olling.TimeBasedRollingPolicy">
<fileNamePattern>info-%d{yyyy-MM-dd}-%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.olling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>10</maxHistory>
</rollingPolicy>
</appender>
<appender name="redis" class="com.cwbase.logback.RedisAppender">
<tags>test</tags>
<host>IP</host><!--redis IP-->
<port>6379</port><!--redis端⼝-->
<key>test</key><!--redis队列名称-->
<!-- <mdc>true</mdc> -->
<callerStackIndex>0</callerStackIndex>
<location>true</location>
<additionalField>
<key>X-B3-ParentSpanId</key>
<value>@{X-B3-ParentSpanId}</value>
</additionalField>
<additionalField>
<key>X-B3-SpanId</key>
<value>@{X-B3-SpanId}</value>
</additionalField>
<additionalField>
<key>X-B3-TraceId</key>
<value>@{X-B3-TraceId}</value>
</additionalField>
</appender>
<root level="info">
<!-- <appender-ref ref="CONSOLE" /> -->
<!-- <appender-ref ref="file" /> -->
<!-- <appender-ref ref="UdpSocket" /> -->
<!-- <appender-ref ref="TcpSocket" /> -->
<appender-ref ref="redis"/>
</root>
<!-- <logger name="ample.logback" level="warn" /> -->
</configuration>
与之前的l配置⽂件相⽐主要更改⼀下内容
<additionalField>
<key>X-B3-ParentSpanId</key>
<value>@{X-B3-ParentSpanId}</value>
</additionalField>
<additionalField>
<key>X-B3-SpanId</key>
<value>@{X-B3-SpanId}</value>
</additionalField>
<additionalField>
<key>X-B3-TraceId</key>
<value>@{X-B3-TraceId}</value>
</additionalField>
⼀会在详细解释上述三个字段含义下⾯先看项⽬⽬录结构
⼀个⽗⼯程(pom⼯程)三个spring boot⼦项⽬⼦项⽬调⽤关系如下
三个⼦项⽬代码如下
spring-cloud-client-test⼯程结构及代码
1package application;
2
3import org.slf4j.Logger;
4import org.slf4j.LoggerFactory;
5import org.springframework.beans.factory.annotation.Autowired;
6import org.springframework.boot.SpringApplication;
7import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
8import org.springframework.boot.autoconfigure.SpringBootApplication;
9import org.springframework.cloudflix.feign.EnableFeignClients;
10import org.springframework.web.bind.annotation.GetMapping;
11import org.springframework.web.bind.annotation.RestController;
12
13 @EnableAutoConfiguration
14 @EnableFeignClients
15 @RestController
16 @SpringBootApplication
17public class ClientTestApplication {
18protected final static Logger logger = Logger(ClientTestApplication.class);
19
20public static void main(String[] args) {
21 SpringApplication.run(ClientTestApplication.class, args);
22 }
23
24 @Autowired
25 servertest server;
26
27 @GetMapping("/client")
28public String getString(){
29 logger.info("开始调⽤服务端");
String();
31 }
32 @GetMapping("/client1")
33public String getString1(){
34 logger.info("开始调⽤服务端1");
String1();
36 }
37 }
1package application;
2
3import org.springframework.cloudflix.feign.FeignClient;
4import org.springframework.http.MediaType;
5import org.springframework.web.bind.annotation.RequestMapping;
6import org.springframework.web.bind.annotation.RequestMethod;
7
8 @FeignClient("SPRING-CLOUD-SERVER-TEST")
9public interface servertest {
10 @RequestMapping(value = "/server", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) 11public String getString();
12 @RequestMapping(value = "/server1", method = RequestMethod.GET, consumes = MediaType.A
PPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) 13public String getString1();
14 }
spring-cloud-server-test⼯程及代码结构
1package application;
2
3import org.slf4j.Logger;
4import org.slf4j.LoggerFactory;
5import org.springframework.beans.factory.annotation.Autowired;
6import org.springframework.boot.SpringApplication;
7import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
8import org.springframework.boot.autoconfigure.SpringBootApplication;
9import org.springframework.cloudflix.feign.EnableFeignClients;
10import org.springframework.web.bind.annotation.GetMapping;
11import org.springframework.web.bind.annotation.RestController;
12
13 @EnableAutoConfiguration
14 @EnableFeignClients
15 @RestController
16 @SpringBootApplication
17public class ServerTestApplication {
18protected final static Logger logger = Logger(ServerTestApplication.class);
19
20public static void main(String[] args) {
21 SpringApplication.run(ServerTestApplication.class, args);
22 }
23
24 @Autowired
25 servertest server;
26
27 @GetMapping("/server")
28public String getString(){
29 logger.info("接收客户端的调⽤");
String();
31 }
32 @GetMapping("/server1")
33public String getString1(){
34 logger.info("接收客户端的调⽤1");
String1();
36 }
37 }
1package application;
2
3import org.springframework.cloudflix.feign.FeignClient;
4import org.springframework.http.MediaType;
5import org.springframework.web.bind.annotation.RequestMapping;
6import org.springframework.web.bind.annotation.RequestMethod;
7
8 @FeignClient("SPRING-CLOUD-SERVER1-TEST")
9public interface servertest {
10 @RequestMapping(value = "/server", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) 11public String getString();
12 @RequestMapping(value = "/server1", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) 13public String getString1();
14 }
spring-cloud-server1-test⼯程及代码结构
1package application;
2
3import org.slf4j.Logger;
4import org.slf4j.LoggerFactory;
5import org.springframework.boot.SpringApplication;
6import org.springframework.boot.autoconfigure.SpringBootApplication;
7import org.springframework.web.bind.annotation.GetMapping;
8import org.springframework.web.bind.annotation.RestController;
9
10
11 @RestController
12 @SpringBootApplication
13public class Server1TestApplication {
14protected final static Logger logger = Logger(Server1TestApplication.class);
15
16public static void main(String[] args) {
17 SpringApplication.run(Server1TestApplication.class, args);
18 }
springcloud和springboot19
20
21 @GetMapping("/server")
22public String getString(){
23 logger.info("接收客户端的调⽤");
24return "My is server";
25 }
26 @GetMapping("/server1")
27public String getString1(){
28 logger.info("接收客户端的调⽤1");
29return "My is server1";
30 }
31 }
好了全部代码就是以上这些下⾯看⽇志传输之后的效果
上图就是最后的结果
我们可以通过 X-B3-TraceId 串联所有的服务这个值每次请求都不⼀样但是会随着调⽤链⼀直传递下去
X-B3-SpanId 这个值属于⽅法级别的值也就是说⽅法调⽤⽅法是⽗⼦级别的传递(⽅便调⽤跟踪)
X-B3-ParentSpanId 这个值就是上⼀个⽅法的X-B3-SpanId 我说的不是很明⽩⼤家可以查阅相关资料了解
好了到这⾥就基本完成了
总结思考
使⽤sleuth我们可以很好的串联快服务的⽇志,结合MDC就可以出现很完美的调⽤流⽔查询但是我们要做到⼀次查询要么做表达式筛选要么查询两次。我们有没有办法将⼆者结合那,我想并不困难⾃⼰重写sleuth相关⽅法可以做到,但是我们要考虑这是有问题的,什么问题那就是同样的MDC key-value 调⽤ sleuth会变但是MDC值不变我们要融合成什么样⼦才能达到想要的⽬的的,这个就不好说了,通过表达式筛选已经很⽅便了还有么有必要这样做那,做了之后怎么避免副作⽤那!有待考究
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论