SkyWalking链路追踪技术
文章目录
一. 认识SkyWalking
SkyWalking解决了什么问题?-----》微服务架构中,各个服务之间调用关系错综复杂,所以需要一个能捋清复杂情况下调用关系的解决方案,这就是SkyWalking,目前最强大的链路追踪技术;
要使用SkyWalking,需要给我们的项目中绑定一个agent探针,绑定后,SkyWalking就会将你项目整体的监控数据反馈给SkyWalking oapservice,SkyWalking oapservice就是SkyWalking的服务端,oapservice会将这些监控数据做处理,然后存储到数据库中:SkyWalking支持的数据库有很多种:ES,Mysql等等很多都支持;然后SkyWalking 提供了一个前端的可视化ui界面,我们程序员可以通过这个ui界面方便的查看到我们项目整体的数据,因为这个前端界面会向oapservice发送请求查询数据;
二、下载SkyWalking
1.下载SkyWalking
下载网址:http://skywalking.apache.org/downloads/
点击Distribution选择要下载的版本----》我们可以看到skywalking它每一个版本都提供了两份:
其中v8.5.0 for ElasticSearch 6 是针对于es6的,也就是说它的oapservice收集到数据后并处理后,会将其存储到es6中;
另一个版本是针对于其他数据库进行存储,比如H2,Mysql,ES7等等(我也不知道为什么要把ES6,ES7分成两部分?)
2. 启动方式
下载好后,解压,然后打开bin文件夹,然后双击startup.bat命令就可以启动skywalking;
双击startup.bat—》它会帮我们同时启动oapservice.bat与webappService.bat;
假如你是用的liunx系统,那么你需要点击startup.sh进行启动,window系统下用startup.bat;
3. 目录文件解释
1.webapp文件夹
这个文件夹中放的是:skywalking的ui前端界面的jar包跟yaml配置文件;
如果你要修改它的前端ui界面的配置,就要在这个文件夹下的webapp.yaml中进行修改;
通过都是需要修改的,因为这个ui前端界面的默认端口号是8080,基本不会用这个端口,容易重复且易被攻击
这是前端界面配置文件打开后的样子;
2.config文件夹
这个文件夹中放的就是常用的配置文件
这里面最重要的文件就是这个application.yml
2.1 application.yml文件详解
2.1.1 监控数据存储方式修改
打开这个文件,里面有个
storage:
selector: ${SW_STORAGE: h2}
这个表示oapservice读取到的监控数据的存储方式,可以看到它默认的存储方式就是采用的h2数据库,这是一种基于内存的数据库,我们不用它,因为它基于内存,只要一重启skywalking,这些监控数据就会消失;
注意:skywalking最优的监控数据存储方式是es,但是很多人可能不懂es,也可以用mysql替代;
3. agent文件夹
这个文件夹里有个最重要的东西:skywalking-agent.jar,这个jar包到时候需要跟我们的微服务进行绑定,绑定后oapservice才能从我们的微服务中获取监控数据;
3. bin文件夹
这个文件夹里放的都是一些启动脚本;
5. oap-libs
这个文件夹下放的是:oapservice服务器所用的jar包
三、启动skywalking
1.启动成功界面
双击startup.bat命令后,出现下面这个界面就表示skywalking启动成功;
2.oapservice的日志文件
oapservice已经自己集成好了日志功能,它在使用过程中就会输出日志;
日志记录会被输出到logs文件夹中下的两个.log文件中,一个是记录的前端ui界面的日志,一个是记录后端oapservice的日志;
3. oapservice的端口
oapservice自动暴露了两个端口,11800端口和12800端口;
11800端口是oapservice用来收集微服务监控数据的端口,
12800是oapservice用来接收前端ui界面请求的端口;
我们也可以通过config文件夹下的application.yaml来修改这些端口号;
注意:在我们自己的微服务中,要将oapservice的端口号告诉给我们的微服务,否则我们自己的微服务是不知道oapservice的端口的,就没有传递监控数据给oapservice了
4. 打开前端ui界面
你在webapp文件夹下的webapp.yml中将前端ui界面的端口号配置好后,你可以直接在你的浏览器中使用 localhost:你配置好的端口号,来访问前端ui界面;
这就是打开后的样子;
5. 将skywalking与我们自己的微服务绑定
通过上面的操作:修改前端ui界面端口号,双击startup.bat,我们已经成功的启动好了前端ui界面,也成功了启动好了oapservice服务了;
现在还差的是:将我们自己的微服务与skywalking进行绑定,以便skywalking能从我们的微服务获取监控数据;
5.1 在windows环境下绑定skywalking
这种方式是在idea中配置,首先找到Edit Configuration,点击打开;
我们选择gateway这个服务,(这里只是以gateway服务作为一个例子用来讲解)
然后找到VM options,在里面按照图片中的格式进行配置;
注意点1:这里是通过jvm的参数来进行的配置,可以达到对代码无侵入的效果;
注意点2:下面截图中VM options中是写了注释的,这是为了我们学习时方便理解,你真正要去配的时候,不能往里面加注释,因为VM options中是识别不了的,会报错;
配置好后–》再点击ok完成配置
5.2.1 查看结果
我们进入到前端ui界面,点击右上角的刷新(我们可以点击左边的"自动",当"自动"变成蓝色后,前端ui界面就会按照你指定的频率每隔几秒刷新一次界面);
但是我们刷新后,只是在上面看到一个api-service,这是我们在gateway服务的VM options中给gateway服务取的名字,我们只看到了这个名字,刷新后下面的界面也看不到任何东西;
然后我们点击上方的拓扑图,
拓扑图里面也只是有一个服务名称,但是没有任何数据,这是为什么呢?
5.2.2 skywalking与gateway之间存在的问题
这里一定要注意:skywalking在默认情况下是不会显示gateway的,就算你把gateway服务跟skywalking的skywalking-agent.jar进行了绑定,在skywalking前端界面中也是不会显示gateway的任何信息的;
解决办法:
第一步:打开skywalking安装目录下的agent文件夹
第二步:再打开plugins文件夹,这个文件夹中是skywalking集成的所有插件,在这里面可以找到很多jar包,包括mysql,rocketmq等等很多,但你就是找不到gateway的jar包,所以才导致出现上面的问题;
所以你只需要将gateway的jar包放入plugins文件夹里面就可以了
第三步:gateway的jar包到哪里去拿呢?
其实skywalking已经帮我们准备好了gateway的jar包,在我们下载skywalking的安装包时,gateway的jar包已经包含在里面了;
我们找到optional-plugins文件夹,这个文件的意思是:可选的插件;
点开文件夹后,会看到里面就有gateway的jar包,有两个,我们可以选择2.1.x那个,这个更新一点;
然后将它复制一份,复制到plugins文件夹中,然后重启skywalking服务;这样就可以了;
5.2.3 再次查看结果
1. 全局响应时间与全局心跳时间
重启后,我们再次打开skywalking的前端ui界面,就能在下面的页面中看到两个板块;
左边的折线图表示:全局的响应时间
右边的图表示:全局的心跳时间
我们还可以点击界面下方的时间,选择最近多少分钟进行查看;
2. 服务,端点,实例
然后我们还可以看到下图圈起来的部分:
最左边的Services Load 表示当前服务的硬件性能,比如cpu等等;
Slow-Services表示慢加载;
Un-Health Services表示不健康的服务;
Slow Endpoints表示慢端点,就是慢接口的意思,就是说你当前服务有哪些接口比较慢;
然后还有个部分叫"当前实例",如果你当前这个服务是做了集群的,那么你点击当前实例是可以看到好几个实例的,下图只显示了一个,因为我们作为案例的这个gateway服务没有做集群;
3. 拓扑图
然后我们再点击拓扑图,就会显示成这个样子;
意思就是:User用户发送请求到了api-service,也就是gateway,然后gateway又调用一台192.168.65.106:8020的机器(这台机器实际上是订单服务),为什么订单服务在拓扑图中没有显示服务名称而是显示ip地址跟端口呢?这是因为我们现在只是将gateway服务与skywalking-agent.jar绑定了,订单服务没有跟它绑定,所以只是显示ip与端口;
4. 追踪
我们可以点到追踪界面,追踪界面有三种查看形式,列表,树结构,表格;
图中展示的是表格的显示形式:
图中红色圈起来这里有个"/order/get",意思就是你这次发起的请求是"/order/get",
然后发起这次请求,从上往下看,你首先经过了gateway的RoutingFilter接口,也就是经过了路由过滤器,
然后再经过了gateway的sendRequest接口,将请求发送了出去;
那既然是发送请求给订单服务的"/order/get"接口,那为什么sendRequest接口下面就没有显示了呢?
这是因为我们还没有把订单服务跟skywalking-agent.jar进行绑定,skywalking就不会显示在订单服务中的调用链路,所以这里调用链路只显示到了gateway;
5. 性能剖析,日志,告警
这三个部分如果我们要看的话,需要做单独的处理,这里还没处理所以看不到,后面再讲;
5.2 在linux环境下绑定skywalking
5.3 将多个服务与skywalking进行绑定
以上案例只将gateway一个服务与skywalking进行了绑定,实际开发过程中,我们会将很多服务都跟skywalking进行绑定,也很简单,还是只需要在每个服务的VM options中配置就行了;
6. skywalking中持久化数据到数据库
6.1 h2数据库:skywalking的默认存储方式
skywalking默认是将数据存储到h2数据库中的,这是一个内存数据库;
如果将这些监控数据存储到内存中,有两个弊端:
1.一旦你的skywalking重启,内存中的这些监控数据必然会丢失,但其实影响也不是很大,因为监控数据基本都是实时的,没有必要保存下来,更没有必要查看一个月以前的监控数据;就这个方面来说,h2数据库也不是不可以;
2.但是当我们skywalking长期启动,会有越来越多的监控数据被存入内存中,最终就会导致内存爆满,到时候我们依然要重启skywalking,所以从这个方面来说,h2数据库并不合适,所以可以采用mysql,存储到mysql后,我们定时去清空就好了;
6.2 skywalking的持久化方式
1. 修改配置文件
我们如何修改skywalking的存储数据库?—》找到config文件夹------》找到application.yml,找到110行,将h2改成mysql,----》最后找到172行,配置mysql的ip地址,端口号,数据库名称,账户密码等信息;
2. mysql中建数据库
然后在mysql中建好配置文件中的数据库,这个库名要跟我们配置文件中配置的名称swtest一致,建好库之后我们就不用管了,因为skywalking在被启动时,自动在我们建好的这个库中创建它需要的表;
3.skywalking启动时的bug
在我们修改好配置文件,将h2改成mysql后,再启动skywalking就会出现bug:双击startup.bat时出现闪退,无法启动成功,此时我们找到logs文件夹下的skywalking-oap-server.log这个日志文件,我们点进去拉到下面,就能看到如下报错提示:获取不到驱动实例;
造成这个bug的原因是什么呢?是因为skywalking的plugins文件夹下没有mysql的驱动jar包,我们可以到自己的maven仓库中找到mysql驱动包,复制到plugins文件夹下即可
maven仓库中mysql驱动包长这个样子
4. 再次启动skywalking
等我们处理好上面的bug后,我们再次启动skywalking,它就会自动在我们指定好的mysql数据库中建表;
下图是建好后的样子,可以看到skywalking建了非常多的表;
使用mysql作为skywalking存储数据的好处是什么呢? 当你重启skywalking后,之前的监控数据依然还在,也就是你打开前端ui界面,还能看到之前的数据;
7. 自定义skywalking的链路追踪
7.1 为什么需要自定义链路追踪?
什么意思呢?为什么要自定义skywalking的链路追踪呢?
在skywalking,只要你的服务跟skywalking进行了绑定,当你访问这些绑定后的服务时,我们就能在skywalking前端ui界面中的链路追踪板块中,看到本次请求完整的调用链路;就像下图所示,就是skywalking默认的调用链路;
但是:上面展示的调用链路中,skywalking只是展示了接口的url,比如关于/order/add这个请求,它就只是展示了/order跟/add,如果有一天,我还想它展示的更清楚,比如/add这个接口中,它最终调用了一个create方法,我还想skywalking把create方法也在调用链路中展示出来,并且还要将create方法的入参,返回值这些都记录展示出来,这就方便我们以后对问题做排查;
这时候就需要我们自定义调用链路了;
7.2 如何自定义链路追踪?
1. 第一步:引入依赖
我们需要在项目中引入依赖,你哪个服务需要跟skywalking绑定,你就在这个服务的pom文件中加入这个依赖;
或者你直接把这个依赖加到总pom文件中;
<!-- skywalking 工具类 -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.5.0</version>
</dependency>
这里需要注意一下这个工具的版本是8.5.0,这个工具的版本要跟你下载的skywalking版本保持一致,你skywalking下载的是8.5.0,那么你这个工具也要用8.5.0;
2. 在对应的业务方法上添加注解@Trace,@Tag,@Tags
现在你有一个订单服务,你已经将订单服务与skywalking绑定了,
并且你的Controller方法如下:
@RestController
@RequestMapping("/order")
public class orderContorller{
@RequestMapping("/get/{id}")
public order get(@PathVariable Integer id){
return orderService.get(id);
}
@RequestMapping("/all")
public List<Order> getAll() throws InterruptedException{
return orderService.all();
}
}
你的service层的方法如下:
@Override
public List<Order> all() throws InterruptedException{
TimeUnit.SECONDS.sleep(2);
return orderMapper.selectAll();
}
@Override
public Order get(Integer id){
return orderMapper.selectByPrimaryKey(id);
}
由于你已经将订单服务与skywalking进行了绑定,那么当你在调用订单服务的all接口时,你是可以在skywalking中看到"/order/all"的完整调用链路的;同理get请求也是一样;
但是controller中,你的all接口还调用了service层的all()方法,你此时在"/order/all"的调用链路中是看不到service层的all()方法的;
而skywalking已经帮我们提供好了解决方案,我们的目的是想在调用链路中也看到service层的all()方法与get()方法,
我们可以在service层的all()方法与get()方法上加上@Trace注解;
2.1 @Trace
@Trace的作用:被@Trace修饰的方法,只要这个方法在某个请求中被调用到了,那么这个方法也会被展示到skywalking的调用链路中,本身它是不展示的,因为skywalking的调用链路中本身只展示接口,你service层的方法又不是接口;
用法:直接写在你想要加入调用链路展示的方法上即可
2.2 @Tag,@Tags
@Tag的作用:上面的@Trace只是将方法加入到了调用链路中,但是我们还想要在调用链路中看到这个方法的入参,返回值,就需要用到@Tag;
这里要分两种情况:
第一种情况,你这个方法没有入参,只有返回值,我想在调用链路中展示这个方法的返回值,就要给@Tag指定一个key,一个value;key可以随便指定,如果你这个@Tag是要用来展示返回值的,你可以直接把key设置为"返回值";
这个key其实就是用来控制在skywalking中显示的东西的,就像下图这样:getAll这里就会变成"返回值",那么图中为什么会显示成getAll呢,这是因为我学习的教程的作者把这个key设置成了“getAll”,但实际上用getAll并不好区分,一眼看到它并不知道是什么意思,所以我给它换成了"返回值";
指定value时呢,就是固定的写法了,必须写成value = “returnObj” ,skywalking底层已经帮我们做好了,因为每个方法的返回值类型不一样,所以skywalking就干脆用returnObj来代替这个返回值,只要你写value = "returnObj"就代表你要在展示这个方法返回值的意思; 上图中被蓝色框起来这部分,实际上就是returnObj的值;
@Override
@Trace
@Tag(key = "返回值", value = "returnObj")
public List<Order> all() throws InterruptedException{
TimeUnit.SECONDS.sleep(2);
return orderMapper.selectAll();
}
第二种情况:你这个方法有入参,也有返回值,此时就必须用到@Tags,@Tag不够用;
@Tags中要用大括号包起来,里面要有两个@Tag,一个@Tag用来表示返回值,一个@Tag用来表示入参,表示入参时,value要用arg[0]来表示,为什么呢?因为get方法只有一个入参 Integer id,skywalking把入参封装成了一个数组,现在只有一个入参,所以下标0就表示Integer id这个参数,所以用arg[0]来表示;
注意:如果这个get方法有两个入参,那么在@Tags的大括号就要有三个@Tag才可以了,另一个入参就要用arg[1]来表示了;
注意:@Tags中的所有@Tag都是它的一个属性,在注解中,不同的属性之间,如果其中一个属性中有多个元素,就要用大括号将其装起来;
@Override
@Trace
@Tags({@Tag(key = "返回值", value = "returnObj"),@Tag(key = "参数1", value = "arg[0]")})
public Order get(Integer id){
return orderMapper.selectByPrimaryKey(id);
}
2.3 注意事项
- @Trace,@Tag,@Tags一定要写在业务方法上,写在controller的接口上是没有用的,因为skywalking默认展示的调用链路中本来就是展示的接口;
- 当我们在用@Trace,@Tag,@Tags自定义调用链路时,一定必须给业务方法先加上@Trace,再考虑加上@Tag,@Tags,如果没有先加上@Trace,那么@Tag,@Tags是不会起作用的,按照正常逻辑也能想通,你这个方法都没有添加进调用链路中,你怎么可能展示它的返回值与入参;
3. 检验结果
3.1 发起请求
我们先调用一次all接口,为什么要先调用一次?因为只有被调用了的接口才会有调用链路,你这个请求都没有发送,skywalking怎么展示这个请求的调用链路呢?
3.2 查看调用链路,点击清空,“持续时间”,“开始时间”
上面我们发起请求后,我们再打开ui前端界面的链路追踪界面;
这里要注意:此时可能看不到我们刚才发送的/order/all请求,因为可能有延迟;我们点击右上角的"清空"按钮;
然后再点击左边的"持续时间",将其换成"开始时间",“持续时间"的意思就是:将你所有的请求按照调用时间的长短进行排序,排在上面的请求,说明它消耗的时间越长,可以方便我们排查;
“开始时间"的意思是:按照这些请求的发生时间排序,排在上面的是最近一次发起的请求;所以这里为了我们学习的方便,我们将其换成"开始时间”,找到我们刚才发起的”/order/all"请求
3.3 查看调用链路中是否有显示业务方法
根据上面的操作后,我们在左边成功的看到了刚才发起的"/order/all"请求,点击它,然后看到右边它的调用链路;
首先第一行是一个"/order/all",这个可以不用管它,它只是skywalking为了方便我们区分每一个不同的请求,给这个调用链路取的一个标题;
第二行:就是可以看到,请求进来后,首先经过了gateway的RoutingFilter路由过滤器;RoutingFilter其实就是gateway中的一个接口,因为skywalking的调用链路中,如果没有经过@trace,@Tag,@Tags等自定义调用链路,它是只展示接口的;
第三行:然后经过了gateway的sendRequest接口;
第四行:再经过了oder服务的/order/all接口,也就是说这个请求被gateway分配到了订单服务的/order/all接口;
第五行:再经过了com.tulingxueyuan.order.service.impl.OrderServiceImpl.all()方法,这里就是显示的我们service层中的all方法了;
注意1:它这里显示的是这个业务方法的完全路径,com.tulingxueyuan包下的order模块下的service包下的impl包下的OrderServiceImpl类下的all()方法,它是这样显示的;
注意2:图中业务方法是没有显示完整的,我们左键点击它,就能够看到这个all方法的完整信息
这个就是点开all()方法后展示的样子,能看到服务名称,服务实例,端点,以及返回值;
服务名称与服务实例就不说了,
端点:其实就是指的接口,但是由于你这个all()方法是service层中的,接口是指controller里面的,所以all()并不能完全称为端点,但是不管service层的方法,还是controller层的方法都是属于方法,本质上没有区别,所以你service层中all()方法显示在端点这一栏也没有问题;
返回值:最后一项getAll那一栏就是表示all()方法的返回值;为什么这里显示的是getAll呢,这是因为我看的教程,作者它在给all()设置@Tag时,key使用的是"getAll" ,所以这里我们点开all()方法的最后一栏显示是getAll,而不是我们自己设置的"返回值";
最后还需要注意的是:这里最后一栏能显示为【Order{id=1,productId=1,totalAmount=90,status=1}】,这是因为你这个业务方法中的Order类是重写了toString方法的,如果没有重写,那么最后一栏这里显示的就是地址值;
最后我们再发送一个/order/get/1请求,那么我们点开它就是这个样子
8. 性能剖析
性能剖析就是图中的这个板块:
我们可以看到,在我们做完上面所有操作后,性能剖析这个界面依然是没有数据的,显示No Data;
1. 性能剖析的作用
当我们发送了一个skywalking管理返回内的请求,如果这个请求执行时间特别长,我们需要分析这里面到底是哪一句代码导致了它耗时特别长,这个时候就需要用到性能剖析了,这也是性能剖析的主要功能;
2. 新建监控任务,对接口进行监控
以/order/all这个接口为例子,我们发起了一个/order/all的请求,但是发现它特别慢;
这个时候,我们需要点击到性能剖析界面----》再点击右上角新建任务,就会弹出新建任务界面,需要我们设置参数;
首先:
服务:这一栏你要根据你要监控的那个接口所在的服务来指定,比如我现在要监控/order/all这个接口,它属于order-service这个服务,所以服务这一栏要选order-service
端点名称:你要监控/order/all这个接口,那么你这里就要填/order/all,注意前面是有斜杠的,不能少写一个/,写成 order/all;
监控时间:就选此刻,表示从现在开始监控;还可以设置时间,表示从什么时间才开始监控;
监控持续时间:我学习的教程里是选的默认的5min,不知道选其他的是否更合适;
起始监控时间:我学习的教程里就是用的默认值0,说实话,我也不知道这一项的意思;
监控间隔:我学习的教程里是用的默认的10ms,也就是每隔10ms监控一次;
最大采样数:这里设置的是5,也就是说你访问/order/all接口的请求数量必须达到5次,skywalking才会对其进行采样;
这些设置完后,我们再点击新建任务;
3. 测试
3.1 发送请求
上面设置的最大采样数是5,我们测试时该怎么操作呢?
我们在浏览器上发起请求,然后多点击几次刷新,只要发送请求数量超过5次就行;
3.2 查看是调用链路中是哪个接口执行慢
请求次数发送够后,我们再打开性能剖析界面刷新一下,就能看到性能剖析界面有数据了:
Task List:表示你现在有哪些任务;
Sampled Traces:表示采样样本,就是说在/order/all这个任务中,被skywalking捕捉到的关于/order/all的请求列表,我们可以看到左边被捕捉到了两次请求,一次消耗了2014ms,一次消耗了2016ms;
我们再点击第一个消耗了2014ms的/order/all,就可以看到右边的界面:start time表示本次调用的开始时间,第一行/order/all的Exc(ms)表示本次总的请求消耗了2014ms;
第二行all()方法中的Exc(ms)表示执行all()方法消耗了2012ms,Exc(%)表示执行时间的占比;
有了这个我们就能看到整个调用链路中,各个部分所消耗的执行时间了;
3.3 查看接口中是哪句代码执行慢
我们再点击分析:就能查看到底是哪句代码执行慢了;
点击分析后,下面就会显示出下面框起来这个界面
我们一直拉到最下面,就能看到被标绿的一行,这就是整个调用链路中,耗时最久的那句代码,它总共消耗了1986ms,下图这一行代码有两个1968,第一个1968是每一行都有的,后面第二个1968才表示当前这句代码消耗的时间;
第一个1968,是duration这一栏的,表示总持续时间;
第二个1968,是self duration这一栏的,表示自持续时间,也就是每一行的执行时间;
而我们再查看我们的代码,all方法里面确实有一行线程睡眠2秒的代码;
9. 日志
当我们发起一个请求后,我希望我的微服务的日志能针对本次请求,记录下来本次追踪链路的id,记录下来后,我们就可以在skywalking中根据链路的id将对应的调用链路记录给搜索出来,然后查看分析; 如果没有这个功能,我们在实际开发中发起一次请求后,没有链路追踪的id,很难找到对应的调用链路;
所以我们需要对我们项目的日志系统进行修改;
1. 三种日志框架
springboot默认的日志框架是logback,当然还有其他日志框架,比如log4j和log4j2
这里以logback作为案例来解释,下面是logback在我们项目中集成的案例,如果你们项目中是使用log4j或者log4j2作为日志框架,你们可以自己到网上搜索它们的配置方式;
1. 引入logback依赖
<!-- apm-toolkit-logback-1.x -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.5.0</version>
</dependency>
2. 添加logback-spring.xml文件
首先,你需要先在对应服务的resource目录下添加logback-spring.xml文件,也就是说你想在哪个服务中加你就加;
logback-spring.xml格式如下: 注意:这个文件的名称一定要叫logback-spring.xml,这是springboot约定大于配置约定好的;
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 引入springboot默认的logback XMl配置文件 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志的格式化,这里{magenta}后面加了一个[%tid],这个tid就是追踪链路的id,加了之后请求进来后,logback才能打印出这个追踪链路的id -->
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<Pattern>CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} [%tid] %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}</Pattern>
</layout >
</encoder>
</appender>
<appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdMDCPatternLogbackLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid} [%thread] %-5level %logger{36} -%msg%n]</Pattern>
</layout>
</encoder>
</appender>
<!-- 设置Appender -->
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="grpc-log"/>
</root>
<configuration>
3. 发送请求测试一下看日志是否有输出tid
我们前端发送一次请求,到后台查看,确实能看到一个TID,其中红色框圈起来的,就是tid,我们复制这个tid,然后拿到skywalking前端ui界面的追踪页面,用这个id查询到本次请求的调用链路;
4. 将输出到控制台的日志同步到skywalking的日志模块中
每次我们都到后台服务器的控制台查看日志非常不方便,我们可以将控制台输出的日志同步到skywalking的日志模块中,只需要在logback-spring.xml中加入下图红色圈起来这部分配置就行了,上面的logback-spring.xml文件中,我已经将这部分代码写进去了,直接粘贴即可;
有了这个功能后,我们以后就只需要在skywalking的日志模块统一的看日志就可以了,就不需要每次都切换到后台控制台查看;
5. 测试
上面的配置文件操作完后,我们再重启服务,再发送一下请求进行测试;
请求发送后,我们进入日志界面,如果没有看到东西,就可以点击右上角的搜索,这个搜索有一个刷新的功能;点击后就能看到下图这样的界面;
我们还可以点击右边的追踪ID,直接进入本次请求的调用链路中,比我们之前复制追踪id然后搜索来的更方便;
6. 注意事项:
如果你的skyalking服务器不是安装在本地的,那么你的项目是无法直接把日志信息传递到skywalking的日志模块的,需要你进行单独的配置;
首先打开你skywalking安装包下的agent文件夹
然后打开config文件夹
打开agent.config文件
然后将下图中红色框圈起来的部分,添加到配置文件中;
注意第一行的SERVER_HOST的ip地址这一栏,如果你的skywalking是在其他机器上,这个里就要填那台机器的ip地址;这一栏默认的地址是127.0.0.1,也就是它默认就是连的本机;
第二行的SEVER_POST这一栏就要填skywalking暴露出来对接agent的端口11800;这里默认就是11800
这样操作后,就完成了