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实时生图绘板
相关文章
|
存储 Java 文件存储
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— logback.xml 配置文件解析
本文解析了 `logback.xml` 配置文件的详细内容,包括日志输出格式、存储路径、控制台输出及日志级别等关键配置。通过定义 `LOG_PATTERN` 和 `FILE_PATH`,设置日志格式与存储路径;利用 `&lt;appender&gt;` 节点配置控制台和文件输出,支持日志滚动策略(如文件大小限制和保存时长);最后通过 `&lt;logger&gt;` 和 `&lt;root&gt;` 定义日志级别与输出方式。此配置适用于精细化管理日志输出,满足不同场景需求。
3411 1
|
Java 微服务 Spring
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录——使用Logger在项目中打印日志
本文介绍了如何在项目中使用Logger打印日志。通过SLF4J和Logback,可设置不同日志级别(如DEBUG、INFO、WARN、ERROR)并支持占位符输出动态信息。示例代码展示了日志在控制器中的应用,说明了日志配置对问题排查的重要性。附课程源码下载链接供实践参考。
1574 0
|
SQL Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— application.yml 中对日志的配置
在 Spring Boot 项目中,`application.yml` 文件用于配置日志。通过 `logging.config` 指定日志配置文件(如 `logback.xml`),实现日志详细设置。`logging.level` 可定义包的日志输出级别,例如将 `com.itcodai.course03.dao` 包设为 `trace` 级别,便于开发时查看 SQL 操作。日志级别从高到低为 ERROR、WARN、INFO、DEBUG,生产环境建议调整为较高级别以减少日志量。本课程采用 yml 格式,因其层次清晰,但需注意格式要求。
1686 0
|
Java API 开发者
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录——slf4j 介绍
在软件开发中,`System.out.println()`常被用于打印信息,但大量使用会增加资源消耗。实际项目推荐使用slf4j结合logback输出日志,效率更高。Slf4j(Simple Logging Facade for Java)是一个日志门面,允许开发者通过统一方式记录日志,无需关心具体日志系统。它支持灵活切换日志实现(如log4j或logback),且具备简洁占位符和日志级别判断等优势。阿里巴巴《Java开发手册》强制要求使用slf4j,以保证日志处理方式的统一性和维护性。使用时只需通过`LoggerFactory`创建日志实例即可。
993 0
|
Prometheus 监控 Java
日志收集和Spring 微服务监控的最佳实践
在微服务架构中,日志记录与监控对系统稳定性、问题排查和性能优化至关重要。本文介绍了在 Spring 微服务中实现高效日志记录与监控的最佳实践,涵盖日志级别选择、结构化日志、集中记录、服务ID跟踪、上下文信息添加、日志轮转,以及使用 Spring Boot Actuator、Micrometer、Prometheus、Grafana、ELK 堆栈等工具进行监控与可视化。通过这些方法,可提升系统的可观测性与运维效率。
1096 1
日志收集和Spring 微服务监控的最佳实践
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
2023 5
|
机器学习/深度学习 XML Java
【spring boot logback】日志logback格式解析
在 Spring Boot 中,Logback 是默认的日志框架,它支持灵活的日志格式配置。通过配置 logback.xml 文件,可以定义日志的输出格式、日志级别、日志文件路径等。
2136 5
|
开发框架 运维 监控
Spring Boot中的日志框架选择
在Spring Boot开发中,日志管理至关重要。常见的日志框架有Logback、Log4j2、Java Util Logging和Slf4j。选择合适的日志框架需考虑性能、灵活性、社区支持及集成配置。本文以Logback为例,演示了如何记录不同级别的日志消息,并强调合理配置日志框架对提升系统可靠性和开发效率的重要性。
781 5
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
1032 6
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
576 1