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

简介: 看过我之前的文章的就可以一步一步搭建起日志传输到搜索引擎 不知道的 看下之前的文章 (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值不变  我们要融合成什么样子才能达到想要的目的的,这个就不好说了 ,通过表达式筛选已经很方便了还有么有必要这样做那,做了之后怎么避免副作用那!有待考究 

 

相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
8月前
|
数据可视化 Java BI
将 Spring 微服务与 BI 工具集成:最佳实践
本文探讨了 Spring 微服务与商业智能(BI)工具集成的潜力与实践。随着微服务架构和数据分析需求的增长,Spring Boot 和 Spring Cloud 提供了构建可扩展、弹性服务的框架,而 BI 工具则增强了数据可视化与实时分析能力。文章介绍了 Spring 微服务的核心概念、BI 工具在企业中的作用,并深入分析了两者集成带来的优势,如实时数据处理、个性化报告、数据聚合与安全保障。同时,文中还总结了集成过程中的最佳实践,包括事件驱动架构、集中配置管理、数据安全控制、模块化设计与持续优化策略,旨在帮助企业构建高效、智能的数据驱动系统。
421 1
将 Spring 微服务与 BI 工具集成:最佳实践
|
8月前
|
存储 安全 Java
管理 Spring 微服务中的分布式会话
在微服务架构中,管理分布式会话是确保用户体验一致性和系统可扩展性的关键挑战。本文探讨了在 Spring 框架下实现分布式会话管理的多种方法,包括集中式会话存储和客户端会话存储(如 Cookie),并分析了它们的优缺点。同时,文章还涵盖了与分布式会话相关的安全考虑,如数据加密、令牌验证、安全 Cookie 政策以及服务间身份验证。此外,文中强调了分布式会话在提升系统可扩展性、增强可用性、实现数据一致性及优化资源利用方面的显著优势。通过合理选择会话管理策略,结合 Spring 提供的强大工具,开发人员可以在保证系统鲁棒性的同时,提供无缝的用户体验。
186 0
|
8月前
|
消息中间件 Java 数据库
Spring 微服务中的数据一致性:最终一致性与强一致性
本文探讨了在Spring微服务中实现数据一致性的策略,重点分析了最终一致性和强一致性的定义、优缺点及适用场景。结合Spring Boot与Spring Cloud框架,介绍了如何根据业务需求选择合适的一致性模型,并提供了实现建议,帮助开发者在分布式系统中确保数据的可靠性与同步性。
560 0
|
8月前
|
消息中间件 Java Kafka
搭建ELK日志收集,保姆级教程
本文介绍了分布式日志采集的背景及ELK与Kafka的整合应用。传统多服务器环境下,日志查询效率低下,因此需要集中化日志管理。ELK(Elasticsearch、Logstash、Kibana)应运而生,但单独使用ELK在性能上存在瓶颈,故结合Kafka实现高效的日志采集与处理。文章还详细讲解了基于Docker Compose构建ELK+Kafka环境的方法、验证步骤,以及如何在Spring Boot项目中整合ELK+Kafka,并通过Logback配置实现日志的采集与展示。
1299 64
搭建ELK日志收集,保姆级教程
|
7月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
1284 2
Spring Boot 3.x 微服务架构实战指南
|
7月前
|
负载均衡 Java API
《深入理解Spring》Spring Cloud 构建分布式系统的微服务全家桶
Spring Cloud为微服务架构提供一站式解决方案,涵盖服务注册、配置管理、负载均衡、熔断限流等核心功能,助力开发者构建高可用、易扩展的分布式系统,并持续向云原生演进。
|
8月前
|
消息中间件 Java Kafka
消息队列比较:Spring 微服务中的 Kafka 与 RabbitMQ
本文深入解析了 Kafka 和 RabbitMQ 两大主流消息队列在 Spring 微服务中的应用与对比。内容涵盖消息队列的基本原理、Kafka 与 RabbitMQ 的核心概念、各自优势及典型用例,并结合 Spring 生态的集成方式,帮助开发者根据实际需求选择合适的消息中间件,提升系统解耦、可扩展性与可靠性。
602 1
消息队列比较:Spring 微服务中的 Kafka 与 RabbitMQ
|
8月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
1561 5
|
8月前
|
监控 安全 Java
Spring Cloud 微服务治理技术详解与实践指南
本文档全面介绍 Spring Cloud 微服务治理框架的核心组件、架构设计和实践应用。作为 Spring 生态系统中构建分布式系统的标准工具箱,Spring Cloud 提供了一套完整的微服务解决方案,涵盖服务发现、配置管理、负载均衡、熔断器等关键功能。本文将深入探讨其核心组件的工作原理、集成方式以及在实际项目中的最佳实践,帮助开发者构建高可用、可扩展的分布式系统。
519 1
|
8月前
|
jenkins Java 持续交付
使用 Jenkins 和 Spring Cloud 自动化微服务部署
随着单体应用逐渐被微服务架构取代,企业对快速发布、可扩展性和高可用性的需求日益增长。Jenkins 作为领先的持续集成与部署工具,结合 Spring Cloud 提供的云原生解决方案,能够有效简化微服务的开发、测试与部署流程。本文介绍了如何通过 Jenkins 实现微服务的自动化构建与部署,并结合 Spring Cloud 的配置管理、服务发现等功能,打造高效、稳定的微服务交付流程。
998 0
使用 Jenkins 和 Spring Cloud 自动化微服务部署