Skywalking 调用链路 & 集成日志

背景

目前公司的项目日志虽然是有traceId的,但是只能去kibana里查询,不能清晰的表达出这个traceId经过了哪几个节点(包括redis,mysql及其它组件)以及对应的耗时,只能拿着traceId一个个筛选索引模式然后去搜索,并且目前这个traceId是后端用uuid生成的。

目标

  1. 接入skywalking,根据traceId查看具体请求的调用链路。

  2. 根据traceId查看具体请求在链路上的日志。

  3. 同一个请求在skywalking上显示的traceId要和ELK上的traceId要一样。

skywalking

1. 安装jdk11稳定版的

稳定版带jps,好用点。 因为我安装的skywalking版本有点新,依赖jdk11.

 

bash

代码解读

复制代码

sudo yum install -y java-11-openjdk-devel

2. 下载skywalking

如果用的是jdk8,那么别下载这个skywalking-apm。最新的要jdk11才能运行。

 

bash

代码解读

复制代码

wget https://archive.apache.org/dist/skywalking/9.4.0/apache-skywalking-apm-9.4.0.tar.gz

3. 下载探针
 

bash

代码解读

复制代码

wget https://dlcdn.apache.org/skywalking/java-agent/9.3.0/apache-skywalking-java-agent-9.3.0.tgz

4. 分别解压
 

bash

代码解读

复制代码

tar -zxvf apache-skywalking-apm-9.4.0.tar.gz tar -zxvf apache-skywalking-java-agent-9.3.0.tgz

5. 修改skywaking的配置文件

如果没有存储数据的需求或者说只是想临时看下效果,这一步可以忽略。

 

bash

代码解读

复制代码

vim /root/apache-skywalking-apm-bin/config/application.yml # 根据自己下载的路径来,不一定是这个 # 和下面这段配置对齐(也可以不配,默认是h2内存数据库来存储,但是我这边已经启动了es了就配置一下) storage: selector: ${SW_STORAGE:elasticsearch} elasticsearch:   namespace: ${SW_NAMESPACE:"my_elasticsearch_cluster"} # 这里的name可以方法问elasticsearch9200页面进行查看

6.启动skywalking
 

python

代码解读

复制代码

/root/apache-skywalking-apm-bin/bin/startup.sh

mysql 8.x (可忽略)

安装mysql 8.x数据库。这里有数据库的就不用装,我是没有,所以装一下,主要目的是为了让等会测试的调用链长一点,调用链路不需要走到mysql的直接跳过

1. 下载 mysql 源安装包
 

sql

代码解读

复制代码

wget http://dev.mysql.com/get/mysql80-community-release-el7-8.noarch.rpm

2. 安装mysql源
 

arduino

代码解读

复制代码

yum localinstall -y mysql80-community-release-el7-8.noarch.rpm

3. 安装mysql
 

css

代码解读

复制代码

yum -y install mysql-community-server --nogpgcheck

4. 启动mysql
 

bash

代码解读

复制代码

sudo systemctl start mysqld sudo systemctl enable mysqld

5. 查看 MySQL 生成的临时密码
 

c

代码解读

复制代码

sudo grep 'temporary password' /var/log/mysqld.log

6. 使用临时密码登录 MySQL
 

bash

代码解读

复制代码

mysql -uroot -p'临时密码'

7. 设置新密码 & 刷新权限
 

lua

代码解读

复制代码

ALTER USER 'root'@'localhost' IDENTIFIED BY 'rootA1234;'; flush privileges; exit;

8. 开启远程访问
 

sql

代码解读

复制代码

create user 'root'@'%' identified with mysql_native_password by 'rootA1234;'; grant all privileges on *.* to 'root'@'%' with grant option; flush privileges;

参考文章

测试

pom

项目中引入依赖

 

xml

代码解读

复制代码

<!--德鲁伊数据源连接池依赖--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.8</version> </dependency> <!--要获取skywalking的traceId--> <dependency> <groupId>org.apache.skywalking</groupId> <artifactId>apm-toolkit-trace</artifactId> <version>9.3.0</version> </dependency>

logback.xml

由于我测试项目用的日志框架是 logback 所以这里只贴 logback.xml的内容:

 

xml

代码解读

复制代码

<?xml version="1.0" encoding="UTF-8"?> <configuration> <property name="LOG_HOME" value="/data/log/service/logs/app"/> <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{traceId}] [%thread] %-5level %logger{36} -%msg%n" /> <!-- 控制台输出 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <Pattern>${LOG_PATTERN}</Pattern> </encoder> </appender> <!-- 输出到指定文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/fang.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 日志文件的命名规则 --> <FileNamePattern>${LOG_HOME}/fang.%d{yyyy-MM-dd}.log</FileNamePattern> </rollingPolicy> <encoder> <Pattern>${LOG_PATTERN}</Pattern> </encoder> </appender> <!-- skyWalking日志采集 --> <appender name="APM_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.mdc.TraceIdMDCPatternLogbackLayout"> <Pattern>${LOG_PATTERN}</Pattern> </layout> </encoder> </appender> <root level="INFO"> <appender-ref ref="STDOUT"/> <appender-ref ref="FILE"/> <appender-ref ref="APM_LOG"/> </root> </configuration>

微服务调用链

我测试用的是两个微服务wl和fang,主要调用链是:wl -> fang -> 数据库,并且在请求走到对应节点上打印相应日志。

启动微服务

fang:

 

bash

代码解读

复制代码

java -jar -javaagent:"/root/skywalking-agent/skywalking-agent.jar" -Dskywalking.agent.service_name=wl -Dskywalking.collector.backend_service=127.0.0.1:11800 wl-1.0.0-SNAPSHOT.jar

wl:

 

bash

代码解读

复制代码

java -jar -javaagent:"/root/skywalking-agent/skywalking-agent.jar" -Dskywalking.agent.service_name=fang -Dskywalking.collector.backend_service=127.0.0.1:11800 fang-0.0.1-SNAPSHOT.jar

skywalking trace 界面

用traceId 查询具体请求调用链

skywalking log 界面

用traceId 查询具体请求调用链对应的日志

到这里为止我们其实已经完成了我们的目标1和目标2了。

接下来,我们继续来完成我们的目标3:同一个请求在skywalking上显示的traceId要和ELK上的traceId要一样。

项目里新增traceFilter

主要代码如下:

 

java

代码解读

复制代码

@Component @Order(1) public class TraceIdFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest; String traceId = httpServletRequest.getHeader(LogConstant.TRACE_ID); if (traceId != null) { MDC.put(LogConstant.TRACE_ID, traceId); } else { MDC.put(LogConstant.TRACE_ID, TraceContext.traceId()); } filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { MDC.clear(); } }

这个类的主要作用是:

  • 如果请求头里没有traceId(说明这个服务是链路中的第一个服务节点),将skywalking的traceId放入当前线程的日志上下文中,这样在打印日志的时候就会自动打印出来(前面logback.xml中的traceId取的就是MDC中的traceId)。
  • 如果请求头里有traceId(说明这个服务是链路中的非第一个服务节点,复用上个节点的traceId),那么直接用请求头里的traceId。
kibana 查询日志

用skywalking里的traceId去kibana里查询日志

如果对ELK搭建和日志收集有兴趣的话可以看我前面的文章:ELK 搭建 & 日志集成

总结

  1. 接入skywalking,根据traceId查看具体请求的调用链路。
  2. 根据traceId查看具体请求在链路上的日志。
  3. 同一个请求在skywalking上显示的traceId要和ELK上的traceId要一样。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值