spring cloud 微服务日志跟踪 sleuth logback elk 整合

本文涉及的产品
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 看过我之前的文章的就可以一步一步搭建起日志传输到搜索引擎 不知道的 看下之前的文章 (1) 记一次logback传输日志到logstash根据自定义设置动态创建ElasticSearch索引(2)关于” 记一次logback传输日志到logstash根据自定义设置动态创建ElasticSearc...

看过我之前的文章的就可以一步一步搭建起日志传输到搜索引擎 不知道的 看下之前的文章 

(1) 记一次logback传输日志到logstash根据自定义设置动态创建ElasticSearch索引

(2)关于” 记一次logback传输日志到logstash根据自定义设置动态创建ElasticSearch索引” 这篇博客相关的优化采坑记录

(3)日志收集(ElasticSearch)串联查询 MDC

这里我们结合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/logback/base.xml" />
    <!-- <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.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}</file>

        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

            <fileNamePattern>info-%d{yyyy-MM-dd}-%i.log
            </fileNamePattern>

            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.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="com.example.logback" level="warn" /> -->

</configuration>

与之前的logback.xml配置文件相比主要更改一下内容

     <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工程结构及代码

 

 

 1 package application;
 2 
 3 import org.slf4j.Logger;
 4 import org.slf4j.LoggerFactory;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.boot.SpringApplication;
 7 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 8 import org.springframework.boot.autoconfigure.SpringBootApplication;
 9 import org.springframework.cloud.netflix.feign.EnableFeignClients;
10 import org.springframework.web.bind.annotation.GetMapping;
11 import org.springframework.web.bind.annotation.RestController;
12 
13 @EnableAutoConfiguration
14 @EnableFeignClients
15 @RestController
16 @SpringBootApplication
17 public class ClientTestApplication {
18     protected final static Logger logger = LoggerFactory.getLogger(ClientTestApplication.class);
19 
20     public static void main(String[] args) {
21         SpringApplication.run(ClientTestApplication.class, args);
22     }
23     
24     @Autowired
25     servertest server;
26     
27     @GetMapping("/client")
28     public String getString(){
29         logger.info("开始调用服务端");
30         return server.getString();
31     }
32     @GetMapping("/client1")
33     public String getString1(){
34         logger.info("开始调用服务端1");
35         return server.getString1();
36     }
37 }
 1 package application;
 2 
 3 import org.springframework.cloud.netflix.feign.FeignClient;
 4 import org.springframework.http.MediaType;
 5 import org.springframework.web.bind.annotation.RequestMapping;
 6 import org.springframework.web.bind.annotation.RequestMethod;
 7 
 8 @FeignClient("SPRING-CLOUD-SERVER-TEST")
 9 public interface servertest {
10     @RequestMapping(value = "/server", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
11     public String getString();
12     @RequestMapping(value = "/server1", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
13     public String getString1();
14 }

spring-cloud-server-test工程及代码结构

 1 package application;
 2 
 3 import org.slf4j.Logger;
 4 import org.slf4j.LoggerFactory;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.boot.SpringApplication;
 7 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 8 import org.springframework.boot.autoconfigure.SpringBootApplication;
 9 import org.springframework.cloud.netflix.feign.EnableFeignClients;
10 import org.springframework.web.bind.annotation.GetMapping;
11 import org.springframework.web.bind.annotation.RestController;
12 
13 @EnableAutoConfiguration
14 @EnableFeignClients
15 @RestController
16 @SpringBootApplication
17 public class ServerTestApplication {
18     protected final static Logger logger = LoggerFactory.getLogger(ServerTestApplication.class);
19 
20     public static void main(String[] args) {
21         SpringApplication.run(ServerTestApplication.class, args);
22     }
23     
24     @Autowired
25     servertest server;
26     
27     @GetMapping("/server")
28     public String getString(){
29         logger.info("接收客户端的调用");
30         return server.getString();
31     }
32     @GetMapping("/server1")
33     public String getString1(){
34         logger.info("接收客户端的调用1");
35         return server.getString1();
36     }
37 }
 1 package application;
 2 
 3 import org.springframework.cloud.netflix.feign.FeignClient;
 4 import org.springframework.http.MediaType;
 5 import org.springframework.web.bind.annotation.RequestMapping;
 6 import org.springframework.web.bind.annotation.RequestMethod;
 7 
 8 @FeignClient("SPRING-CLOUD-SERVER1-TEST")
 9 public interface servertest {
10     @RequestMapping(value = "/server", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
11     public String getString();
12     @RequestMapping(value = "/server1", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
13     public String getString1();
14 }

spring-cloud-server1-test工程及代码结构

 1 package application;
 2 
 3 import org.slf4j.Logger;
 4 import org.slf4j.LoggerFactory;
 5 import org.springframework.boot.SpringApplication;
 6 import org.springframework.boot.autoconfigure.SpringBootApplication;
 7 import org.springframework.web.bind.annotation.GetMapping;
 8 import org.springframework.web.bind.annotation.RestController;
 9 
10 
11 @RestController
12 @SpringBootApplication
13 public class Server1TestApplication {
14     protected final static Logger logger = LoggerFactory.getLogger(Server1TestApplication.class);
15 
16     public static void main(String[] args) {
17         SpringApplication.run(Server1TestApplication.class, args);
18     }
19     
20     
21     @GetMapping("/server")
22     public String getString(){
23         logger.info("接收客户端的调用");
24         return "My is server";
25     }
26     @GetMapping("/server1")
27     public String getString1(){
28         logger.info("接收客户端的调用1");
29         return "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值不变  我们要融合成什么样子才能达到想要的目的的,这个就不好说了 ,通过表达式筛选已经很方便了还有么有必要这样做那,做了之后怎么避免副作用那!有待考究 

 

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
3月前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
880 31
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
3月前
|
Java 中间件
SpringBoot入门(6)- 添加Logback日志
SpringBoot入门(6)- 添加Logback日志
130 5
|
2月前
|
JSON Java API
利用Spring Cloud Gateway Predicate优化微服务路由策略
Spring Cloud Gateway 的路由配置中,`predicates`​(断言)用于定义哪些请求应该匹配特定的路由规则。 断言是Gateway在进行路由时,根据具体的请求信息如请求路径、请求方法、请求参数等进行匹配的规则。当一个请求的信息符合断言设置的条件时,Gateway就会将该请求路由到对应的服务上。
166 69
利用Spring Cloud Gateway Predicate优化微服务路由策略
|
30天前
|
搜索推荐 NoSQL Java
微服务架构设计与实践:用Spring Cloud实现抖音的推荐系统
本文基于Spring Cloud实现了一个简化的抖音推荐系统,涵盖用户行为管理、视频资源管理、个性化推荐和实时数据处理四大核心功能。通过Eureka进行服务注册与发现,使用Feign实现服务间调用,并借助Redis缓存用户画像,Kafka传递用户行为数据。文章详细介绍了项目搭建、服务创建及配置过程,包括用户服务、视频服务、推荐服务和数据处理服务的开发步骤。最后,通过业务测试验证了系统的功能,并引入Resilience4j实现服务降级,确保系统在部分服务故障时仍能正常运行。此示例旨在帮助读者理解微服务架构的设计思路与实践方法。
82 16
|
1天前
|
传感器 监控 安全
智慧工地云平台的技术架构解析:微服务+Spring Cloud如何支撑海量数据?
慧工地解决方案依托AI、物联网和BIM技术,实现对施工现场的全方位、立体化管理。通过规范施工、减少安全隐患、节省人力、降低运营成本,提升工地管理的安全性、效率和精益度。该方案适用于大型建筑、基础设施、房地产开发等场景,具备微服务架构、大数据与AI分析、物联网设备联网、多端协同等创新点,推动建筑行业向数字化、智能化转型。未来将融合5G、区块链等技术,助力智慧城市建设。
|
2月前
|
Java Nacos Sentinel
Spring Cloud Alibaba:一站式微服务解决方案
Spring Cloud Alibaba(简称SCA) 是一个基于 Spring Cloud 构建的开源微服务框架,专为解决分布式系统中的服务治理、配置管理、服务发现、消息总线等问题而设计。
378 13
Spring Cloud Alibaba:一站式微服务解决方案
|
2月前
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
191 5
|
2月前
|
Prometheus 监控 Java
如何全面监控所有的 Spring Boot 微服务
如何全面监控所有的 Spring Boot 微服务
104 3
|
2月前
|
存储 运维 数据可视化
如何为微服务实现分布式日志记录
如何为微服务实现分布式日志记录
112 1
|
3月前
|
Java 中间件
SpringBoot入门(6)- 添加Logback日志
SpringBoot入门(6)- 添加Logback日志
72 1