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

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

 package application;

 import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; @EnableAutoConfiguration
@EnableFeignClients
@RestController
@SpringBootApplication
public class ClientTestApplication {
protected final static Logger logger = LoggerFactory.getLogger(ClientTestApplication.class); public static void main(String[] args) {
SpringApplication.run(ClientTestApplication.class, args);
} @Autowired
servertest server; @GetMapping("/client")
public String getString(){
logger.info("开始调用服务端");
return server.getString();
}
@GetMapping("/client1")
public String getString1(){
logger.info("开始调用服务端1");
return server.getString1();
}
}
 package application;

 import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; @FeignClient("SPRING-CLOUD-SERVER-TEST")
public interface servertest {
@RequestMapping(value = "/server", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public String getString();
@RequestMapping(value = "/server1", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public String getString1();
}

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

 package application;

 import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; @EnableAutoConfiguration
@EnableFeignClients
@RestController
@SpringBootApplication
public class ServerTestApplication {
protected final static Logger logger = LoggerFactory.getLogger(ServerTestApplication.class); public static void main(String[] args) {
SpringApplication.run(ServerTestApplication.class, args);
} @Autowired
servertest server; @GetMapping("/server")
public String getString(){
logger.info("接收客户端的调用");
return server.getString();
}
@GetMapping("/server1")
public String getString1(){
logger.info("接收客户端的调用1");
return server.getString1();
}
}
 package application;

 import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; @FeignClient("SPRING-CLOUD-SERVER1-TEST")
public interface servertest {
@RequestMapping(value = "/server", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public String getString();
@RequestMapping(value = "/server1", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public String getString1();
}

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

 package application;

 import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
@SpringBootApplication
public class Server1TestApplication {
protected final static Logger logger = LoggerFactory.getLogger(Server1TestApplication.class); public static void main(String[] args) {
SpringApplication.run(Server1TestApplication.class, args);
} @GetMapping("/server")
public String getString(){
logger.info("接收客户端的调用");
return "My is server";
}
@GetMapping("/server1")
public String getString1(){
logger.info("接收客户端的调用1");
return "My is server1";
}
}

好了 全部代码就是以上这些 下面看日志传输之后的效果

上图就是最后的结果

我们可以通过 X-B3-TraceId 串联所有的服务  这个值每次请求都不一样但是会随着调用链一直传递下去

X-B3-SpanId 这个值属于方法级别的值 也就是说 方法调用方法是父子级别的传递(方便调用跟踪)

X-B3-ParentSpanId 这个值就是上一个方法的X-B3-SpanId  我说的不是很明白大家可以查阅相关资料了解

好了到这里就基本完成了

总结思考

使用sleuth我们可以很好的串联快服务的日志,结合MDC就可以出现很完美的调用流水查询但是我们要做到一次查询 要么做表达式筛选要么查询两次 。我们有没有办法将二者结合那,我想并不困难自己重写sleuth相关方法可以做到,但是我们要考虑这是有问题的,什么问题那 就是 同样的MDC key-value 调用 sleuth会变 但是MDC值不变  我们要融合成什么样子才能达到想要的目的的,这个就不好说了 ,通过表达式筛选已经很方便了还有么有必要这样做那,做了之后怎么避免副作用那!有待考究

spring cloud 微服务日志跟踪 sleuth logback elk 整合的更多相关文章

  1. Spring Cloud微服务实战:手把手带你整合eureka&zuul&feign&hystrix

    转载自:https://www.jianshu.com/p/cab8f83b0f0e 代码实现:https://gitee.com/ccsoftlucifer/springCloud_Eureka_z ...

  2. Spring Cloud 微服务六:调用链跟踪Spring cloud sleuth +zipkin

    前言:随着微服务系统的增加,服务之间的调用关系变得会非常复杂,这给运维以及排查问题带来了很大的麻烦,这时服务调用监控就显得非常重要了.spring cloud sleuth实现了对分布式服务的监控解决 ...

  3. Spring Cloud微服务学习笔记

    Spring Cloud微服务学习笔记 SOA->Dubbo 微服务架构->Spring Cloud提供了一个一站式的微服务解决方案 第一部分 微服务架构 1 互联网应用架构发展 那些迫使 ...

  4. 一张图了解Spring Cloud微服务架构

    Spring Cloud作为当下主流的微服务框架,可以让我们更简单快捷地实现微服务架构.Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟.经得起实际考验的服务框架组合起来 ...

  5. Spring Cloud 微服务架构解决方案

    1 理解微服务 1.1 软件架构演进 软件架构的发展经历了从单体结构.垂直架构.SOA架构到微服务架构的过程. 1.1.1 单体架构 特点: 1.所有的功能集成在一个项目工程中. 2.所有的功能打一个 ...

  6. spring cloud 微服务介绍(转)

    一.理解微服务   我们通过软件架构演进过程来理解什么是微服务,软件架构的发展经历了从单体结构.垂直架构.SOA架构到微服务架构的过程. 1. 单体架构 1.1 特点(1)所有的功能集成在一个项目工程 ...

  7. Spring Cloud微服务系列文,服务调用框架Feign

    之前博文的案例中,我们是通过RestTemplate来调用服务,而Feign框架则在此基础上做了一层封装,比如,可以通过注解等方式来绑定参数,或者以声明的方式来指定请求返回类型是JSON.    这种 ...

  8. Dubbo和Spring Cloud微服务架构比较

    Dubbo 出生于阿里系,是阿里巴巴服务化治理的核心框架,并被广泛应用于中国各互联网公司:只需要通过 Spring 配置的方式即可完成服务化,对于应用无入侵,设计的目的还是服务于自身的业务为主. 微服 ...

  9. 在阿里云容器服务上开发基于Docker的Spring Cloud微服务应用

    本文为阿里云容器服务Spring Cloud应用开发系列文章的第一篇. 一.在阿里云容器服务上开发Spring Cloud微服务应用(本文) 二.部署Spring Cloud应用示例 三.服务发现 四 ...

随机推荐

  1. python面向对象入门(1):从代码复用开始

    本文从代码复用的角度一步一步演示如何从python普通代码进化到面向对象,并通过代码去解释一些面向对象的理论.所以,本文前面的内容都是非面向对象的语法实现方式,只有在最结尾才给出了面向对象的简单语法介 ...

  2. Hyperledger Fabric链码之三

    在<Hyperledger Fabric链码之一>和<Hyperledger Fabric链码之二>中我们介绍了链码的定义,并通过dev网络测试了测试了自己编写的链码程序. 本 ...

  3. Javascript 组合继承 原型链继承 寄生继承

    Javascript继承通常有三种方式. 第一种:组合式继承: function SuperType(name) { this.name = name; this.colors = ["re ...

  4. 【转载】阿里云服务器为网站选配Https证书

    数字证书是一个经权威授权机构数字签名.包含公开密钥拥有者信息以及公开密钥的文件,是权威机构颁发给网站的可信凭证.最简单的证书包含一个公开密钥.证书名称以及证书授权中心的数字签名,只在特定的时间内有效. ...

  5. Html5游戏开发-图形与动画(一)

    最近研究了一下出来了很久的HTML5,总结了一下,准备来个系列,文中也许有很多问题,欢迎大家指正. Canvas介绍 canvas用于在网页中绘制图形的一个元素,具体内容请查看 -> HTML5 ...

  6. $_POST和$GLOBALS['HTTP_RAW_POST_DATA'] 的区别

    HTTP 协议是建立在 TCP/IP 协议之上的应用层规范,它把 HTTP 请求分为三个部分:请求行.请求头.消息主体.协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协 ...

  7. laravel的时间日期处理包Carbon用法

    时间日期处理包--Carbon Carbon – 是继承自 PHP DateTime 类的 API 扩展,它使得处理日期和时间更加简单.Laravel 中默认使用的时间处理类就是 Carbon. La ...

  8. Java中net.sf.json包关于JSON与对象互转的坑

    在Web开发过程中离不开数据的交互,这就需要规定交互数据的相关格式,以便数据在客户端与服务器之间进行传递.数据的格式通常有2种:1.xml:2.JSON.通常来说都是使用JSON来传递数据.本文正是介 ...

  9. Mac下写博客工具MarsEdit相关资料

    参考资料: https://www.maoshu.cc/967.html 下载地址: https://www.red-sweater.com/marsedit/ 博客园的配置: http://www. ...

  10. Netty 系列三(ByteBuf).

    一.概述和原理 网络数据传输的基本单位总是字节,Netty 提供了 ByteBuf 作为它的字节容器,既解决了 JDK API 的局限性,又为网络应用程序提供了更好的 API,ByteBuf 的优点: ...