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

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
云原生网关 MSE Higress,422元/月
简介: 看过我之前的文章的就可以一步一步搭建起日志传输到搜索引擎 不知道的 看下之前的文章 (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日志并进行多维度分析。
相关文章
|
10天前
|
Java 对象存储 开发者
解析Spring Cloud与Netflix OSS:微服务架构中的左右手如何协同作战
Spring Cloud与Netflix OSS不仅是现代微服务架构中不可或缺的一部分,它们还通过不断的技术创新和社区贡献推动了整个行业的发展。无论是对于初创企业还是大型组织来说,掌握并合理运用这两套工具,都能极大地提升软件系统的灵活性、可扩展性以及整体性能。随着云计算和容器化技术的进一步普及,Spring Cloud与Netflix OSS将继续引领微服务技术的发展潮流。
23 0
|
8天前
|
负载均衡 Java 网络架构
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
21 5
|
7天前
|
前端开发 API 微服务
SpringCloud微服务之间使用Feign调用不通情况举例
SpringCloud微服务之间使用Feign调用不通情况举例
37 2
|
10天前
|
Java API 对象存储
微服务魔法启动!Spring Cloud与Netflix OSS联手,零基础也能创造服务奇迹!
这段内容介绍了如何使用Spring Cloud和Netflix OSS构建微服务架构。首先,基于Spring Boot创建项目并添加Spring Cloud依赖项。接着配置Eureka服务器实现服务发现,然后创建REST控制器作为API入口。为提高服务稳定性,利用Hystrix实现断路器模式。最后,在启动类中启用Eureka客户端功能。此外,还可集成其他Netflix OSS组件以增强系统功能。通过这些步骤,开发者可以更高效地构建稳定且可扩展的微服务系统。
26 1
|
21天前
|
监控 Java Nacos
SpringCloud基础5——微服务保护、Sentinel
sentinel、雪崩问题、流量控制、隔离和降级、授权规则、规则持久化
SpringCloud基础5——微服务保护、Sentinel
|
27天前
|
前端开发 Java UED
"揭秘!如何以戏剧性姿态,利用SpringCloud铸就无懈可击的异常处理铁壁,让你的微服务架构稳如泰山,震撼业界!"
【9月更文挑战第8天】随着微服务架构的普及,Spring Cloud作为一套完整的微服务解决方案被广泛应用。在微服务架构中,服务间调用频繁且复杂,异常处理成为保障系统稳定性和用户体验的关键。传统的异常处理方式导致代码冗余,降低系统可维护性和一致性。因此,基于Spring Cloud封装统一的异常处理机制至关重要。这样不仅可以减少代码冗余、提升一致性,还增强了系统的可维护性,并通过统一的错误响应格式优化了用户体验。具体实现包括定义全局异常处理器、自定义业务异常以及在服务中抛出这些异常。这种方式体现了微服务架构中的“服务治理”和“契约先行”原则,有助于构建健壮、可扩展的系统。
48 2
|
29天前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
58 2
|
10天前
|
Java 对象存储 开发者
微服务世界的双雄争霸:Spring Cloud与Netflix OSS——谁将引领下一次企业级应用变革的风暴?
Spring Cloud与Netflix OSS是微服务架构的核心组件集,分别以其与Spring Boot的紧密集成及为大规模分布式系统设计的特性,在Java开发社区中广受青睐。前者通过Eureka提供服务发现机制,简化服务注册与定位;后者借助Hystrix增强系统弹性和可靠性,避免雪崩效应。此外,二者还包含负载均衡(Ribbon)、声明式HTTP客户端(Feign)及API网关(Zuul)等功能,共同构建强大微服务体系,助力开发者聚焦业务逻辑,提升系统灵活性与性能。
24 0
|
10天前
|
Cloud Native Java 对象存储
揭秘微服务架构之争:Spring Cloud与Netflix OSS巅峰对决,谁将称霸弹性云原生时代?
近年来,微服务架构成为企业应用的主流设计模式。本文对比了两大热门框架Spring Cloud和Netflix OSS,探讨其在构建弹性微服务方面的表现。Spring Cloud依托Spring Boot,提供全面的微服务解决方案,包括服务注册、配置管理和负载均衡等。Netflix OSS则由一系列可独立或组合使用的组件构成,如Eureka、Hystrix等。两者相比,Spring Cloud更易集成且功能完善,而Netflix OSS则需自行整合组件,但灵活性更高。实际上,两者也可结合使用以发挥各自优势。通过对两者的对比分析,希望为企业在微服务架构选型上提供参考。
29 0
|
2月前
|
Kubernetes Ubuntu Windows
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
下一篇
无影云桌面