当前位置: 首页 > news >正文

【微服务】skywalking自定义链路追踪与日志采集

目录

一、前言

二、自定义链路追踪简介

2.1 自定义链路追踪应用场景

2.2 链路追踪几个关键概念

三、skywalking 自定义链路追踪实现

3.1 环境准备

3.2 集成过程

3.2.1 导入核心依赖

3.2.2 几个常用注解

3.2.3 方法集成

3.2.4 上报追踪信息

四、skywalking 自定义日志采集

4.1 概述

4.2 集成过程

4.2.1 引入核心依赖

4.2.2 配置logback文件

4.2.2 接口测试

五、写在文末


一、前言

在前面的分享中,详细了解了在微服务中集成skywalking进行服务链路追踪的过程,不管是使用dubbo还是springcloud做微服务治理,在集成skywalking时,往往关注的更多是不同服务之间的调用情况,但是在实际应用中,如果服务内部的链路调用比较复杂,跨度很长的情况下,是否也可以使用skywalking进行追踪呢?接下来将详细介绍下。

二、自定义链路追踪简介

2.1 自定义链路追踪应用场景

 在下面的场景下,可能需要在单应用内进行追踪:

  • 接口业务逻辑复杂,内含一些关键的远程接口调用;
  • 业务调用链路较长,内部方法调用栈比较深;
  • 需要监控某些关键执行业务逻辑的执行耗时,它们可能是性能瓶颈点;
  • ...

比如下面的一个接口,内部的逻辑调用链路比较深的情况下就需要自定义链路追踪

2.2 链路追踪几个关键概念

在具体学习自定义链路追踪之前,有下面几个概念需要了解

Trace

Trace就是链路,指一个请求经过所有服务的路径,服务间经过的局部链路构成了一条完整的链路,其中每一条局部链路都用一个全局唯一的traceid来标识。

Span

Span用于表示上下层父子关系,同一层级parent id相同,span id不同,span id从小到大表示请求的顺序。通过事先在日志中埋点,找出相同traceId的日志,再加上parent id和span id就可以将一条完整的请求调用链串联起来。

采样

由于每一个请求都会生成一个链路,为了减少性能消耗,避免存储资源的浪费,采集器并不会上报所有的span数据,而是使用采样的方式。举个例子,每秒有1000个请求访问系统,如果设置采样率为1/1000,那么只会上报一个请求到存储端。

存储

链路中的span数据经过收集和上报后会集中存储在一个地方,常用的存储有Mysql,ElasticSearch, HBase, In-memory DB等。

三、skywalking 自定义链路追踪实现

3.1 环境准备

  • 参照之前的文章提前搭建完skywalking 服务,并能访问web-ui界面;
  • 搭建一个springboot工程;
  • 启动nacos服务;

3.2 集成过程

下面演示如何在springboot工程中集成方法级的链路追踪信息并上报skywalking 。

3.2.1 导入核心依赖

在方法中记录追踪信息主要用到apm-toolkit-trace这个依赖,其提供了丰富的注解可供方法使用。

<dependencies><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-trace</artifactId><version>8.14.0</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>

3.2.2 几个常用注解

在使用apm-toolkit-trace时,通常使用其提供的注解用于标准方法和参数,下面来看看常用的几个注解使用。

使用方式

@Trace
@Tag(key = "tag1", value = "arg[0]")
@Tag(key = "tag2", value = "arg[1]")
@Tag(key = "username", value = "returnedObj.username")
@Tag(key = "age", value = "returnedObj.age")
public User getUser(String param1, String param2) {// ActiveSpan.setOperationName("Customize your own operation name, if this is an entry span, this would be an endpoint name");// ...
}

参数说明:

@Trace

用在方法上,表名这是一个方法级的trace,@Trace也可以定义名称,比如@Trace(operationName = "getUserInfo"),@Trace注解其只能在方法上进行注解,使用operationName属性指定Span的名字,若不指定,会使用方法名;

@Tags/ @Tag

使用@Tags/ @Tag注解添加Span的属性

1)key 属性名

2)value 属性值会是一个表达式,具体可以参考官方文档,具体可参考,参考文档

3)arg[0]代表入参的第一个对象,returnedObj即当前方法返回的对象;

3.2.3 方法集成

在工程中创建一个接口

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/get")public Object getUserInfo(String userId){Map userInfo = userService.getUserInfo(userId);return userInfo;}
}

业务实现

@Service
@Slf4j
public class UserServiceImpl implements UserService {@Override@Trace(operationName = "getUserInfo")@Tags({@Tag(key = "userId", value = "arg[0]"),@Tag(key = "user", value = "returnedObj")})public Map getUserInfo(String userId) {//获取自定义的上下文中的追踪信息String traceId = TraceContext.traceId();log.info("准备获取用户信息 ,traceId : [{}]", traceId);Map resMap = new HashMap();UserInfo userInfo = new UserInfo(userId, "jerry");resMap.put("user", userInfo);//获取用户所属的组织机构log.info("准备获取组织机构信息 ,traceId : [{}]", traceId);Depart depart = getDepart(userId);resMap.put("depart", depart);return resMap;}@Trace(operationName = "getDepart")@Tags(@Tag(key = "depart", value = "returnedObj"))private Depart getDepart(String userId) {if (userId == null) {return null;}return new Depart("001", "运维部");}
}

在该方法中,我们要实现的逻辑是,根据用户ID获取用户,同时在获取用户信息时还需要拿到组织机构信息,为了使用自定义追踪,在方法上添加了相关的注解,在不接入skywalking 的agent时启动测试接口

3.2.4 上报追踪信息

在启动参数中添加如下信息

-javaagent:E:\code-self\skywalking-agent\skywalking-agent.jar -DSW_AGENT_NAME=sky-service -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=skywalking IP:11800

再次启动服务,并调用上面的接口,从控制台可以看到此时当前接口请求就产生了一条追踪信息,可以看到输出的traceId;

同时在web-ui界面上,可以看到当前请求的处理方法中各个链路的详情,即从接口出发,到接口中处理的各个环节,包括调用的其他方法都能展示出来

点击到具体的方法中,比如点击getUserInfo这个方法中,能够看到追踪的该方法具体的信息,比如参数,返回值

四、skywalking 自定义日志采集

4.1 概述

在实际项目中,为了方便线上排查问题,尤其是微服务之间调用链路比较复杂的系统中,通过可视化日志的手段仍然是最直接也很方便的排查定位问题的手段,比如大家熟悉的ELK就是一种比较成熟的可视化日志展现方式,在skywalking UI界面上,在服务菜单栏中有Log一项,该项就是用于服务中集成日志,然后上报skywalking 进行链路的分析使用。

4.2 集成过程

微服务要通过skywalking 集成和上报日志信息,需要依赖logback日志,因此在集成过程中,需要按照规范定义logback的文件配置,整个过程分为下面几步:

  1. 引入logback依赖;

  2. 配置logback文件,按照规范输出日志信息;

  3. 导出日志并上报到skywalking ;

接下来以上一篇的springcloud接入skywalking 为例,在此基础上继续接入自定义的日志

4.2.1 引入核心依赖

在各个微服务模块中引入如下依赖

        <dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-logback-1.x</artifactId><version>8.14.0</version></dependency>

4.2.2 配置logback文件

参考下面的样例配置logback文件,核心配置说明:

  • 在第一个ConsoleAppender中,Pattern中定义的内容表示日志输出格式,其中最关键的就是tid,即通过日志追记录的traceId;

  • 第二个AsyncAppender使用的是异步方式追加,减少对主业务的性能影响;

  • GRPCLogClientAppender,以grpc的方式上报日志到skywalking 的oap服务;

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod=" 5 seconds"><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout"><Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern></layout></encoder></appender><appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"><discardingThreshold>0</discardingThreshold><queueSize>1024</queueSize><neverBlock>true</neverBlock><appender-ref ref="STDOUT"/></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.mdc.TraceIdMDCPatternLogbackLayout"><Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern></layout></encoder></appender><root level="INFO"><appender-ref ref="ASYNC"/><appender-ref ref="grpc-log"/></root>
</configuration>

4.2.2 接口测试

启动几个模块的微服务,nacos中可以看到服务已经注册进去

通过网关调用接口:localhost:9001/os/order/getById?id=001,可以看到接口能够响应数据

观察控制台的输出日志,不难发现,接口从order中发起,然后远程调用user服务中查询用户的逻辑,观察order服务的日志输出,产生了一个TID,即上午所说的traceId;

再检查user服务的控制台日志输出,同样输出了TID,细心的同学会发现,这个TID与上面的TID相同,因为是同一条链路的唯一ID;

此时再去WEB-UI界面,可以看到在Log这一栏中,就产生了相关的日志信息

可以在服务下拉框里面选择某个服务进行过滤,比如选择order服务之后点击某条日志进去检查,就能看到这条日志的详细信息

五、写在文末

通过上面的演示过程,演示了如何在微服务中自定义方法级的链路追踪,以及通过自定义输出格式的日志上报到skywalking的完整过程,在实际项目使用中,还需要结合实际需求进行细节上的调整,希望对看到的同学有用,本篇到此结束,感谢观看。

相关文章:

【微服务】skywalking自定义链路追踪与日志采集

目录 一、前言 二、自定义链路追踪简介 2.1 自定义链路追踪应用场景 2.2 链路追踪几个关键概念 三、skywalking 自定义链路追踪实现 3.1 环境准备 3.2 集成过程 3.2.1 导入核心依赖 3.2.2 几个常用注解 3.2.3 方法集成 3.2.4 上报追踪信息 四、skywalking 自定义日志…...

MYSQL基础问题

一&#xff0e;DBMS 是什么 DBMS&#xff08;Database Management System&#xff09;,数据库管理系统&#xff0c;是一种操纵和管理 数据库的大型软件&#xff0c;用于建立、使用和维护数据库。对数据库进行统一的管理和 控制&#xff0c;以保证数据库的安全性和完整性。 二…...

SpringBoot使用Guava实现日志脱敏(含源码)

点击下载《SpringBoot使用Guava实现日志脱敏&#xff08;含源码&#xff09;》 1. 摘要 本文将介绍如何使用Google Guava库进行日志脱敏&#xff0c;保护敏感数据的安全。我们将详细解释脱敏的必要性&#xff0c;然后介绍如何使用Guava中的Strings、Maps和CharMatcher类来进行…...

数据结构—动态查找

动态查找介绍 1. 动态查找的引入&#xff1a;当查找表以线性表的形式组织时&#xff0c;若对查找表进行插入、删除或排序操作&#xff0c;就必须移动大量的记录&#xff0c;当记录数很多时&#xff0c;这种移动的代价很大。 2. 动态查找表的设计思想&#xff1a;表结构本身是…...

Tarjan算法学习笔记

目录 无向图的割点与桥 时间戳&#xff1a; 搜索树&#xff1a; 追溯值&#xff1a; 割边判定法则&#xff1a; 割点判定法则&#xff1a; 无向图的双连通分量 定理&#xff1a; 边双连通分量(e-DCC)的求法&#xff1a; e-DCC的缩点&#xff1a; 有向图的连通性 追…...

vue 项目涉及的焦点聚焦、格式化日期、判断是否为对象或数组、判断是否为空、深拷贝、节流、防抖

焦点聚焦 import Vue from vue // 插件对象(必须有 install 方法, 才可以注入到 Vue.use 中) export default {install () {Vue.directive(fofo, {inserted (el) {el el.querySelector(input)el.focus()}})} }格式化日期格式 export const formatDate (time) > {// 将xx…...

软件工程知识梳理6-运行和维护

软件维护需要的工作量很大&#xff0c;大型软件的维护成本高达开发成本的4倍左右。所以&#xff0c;软件工程的主要目的就是要提高软件的可维护性&#xff0c;减少软件维护所需要的工作量&#xff0c;降低软件系统的总成本。 定义&#xff1a;软件已经交付使用之后&#xff0c;…...

docker- php7.4

安装 gd拓展 anzhuanga在Dockerfile里面安装php7.4的GD库 - 知乎 apt update apt install -y libwebp-dev libjpeg-dev libpng-dev libfreetype6-devdocker-php-source extractdocker-php-ext-configure gd \ --with-jpeg/usr/include \ --with-freetype/usr/include/docker-…...

开发一个Android App,在项目中完成添加联系人的功能,通过ContentResolver向系统中添加联系人信息。

实现步骤&#xff1a; &#xff08;1&#xff09;添加动态联系人的权限。 &#xff08;2&#xff09;创建Activity和布局文件&#xff0c;添加输入框和按钮等控件。 &#xff08;3&#xff09;完成添加联系人的功能。 代码文件如下&#xff1a; activity_main.xml文件 <!…...

Flume搭建

压缩包版本&#xff1a;apache-flume-1.9.0-bin.tar 百度盘链接&#xff1a;https://pan.baidu.com/s/1ZhSiePUye9ax7TW5XbfWdw 提取码&#xff1a;ieks 1.解压 tar -zxvf /opt/software/apache-flume-1.9.0-bin.tar.gz -C /opt/module/ 2. 修改文件名 [rootbigdata1 opt]…...

Web APIs 1 DOM操作

Web APIs 1 引入&#xff1a;const优先Web API 基本认知01 作用和分类02 什么是DOM03 DOM树04 DOM对象 获取DOM对象01 根据CSS选择器获取02 其他获取DOM元素方法 操作元素内容01 innerText 属性02 innerHTML 属性 操作元素属性操作元素的常用属性操作元素的样式属性操作表单元素…...

dvwa,xss反射型lowmedium

xss&#xff0c;反射型&#xff0c;low&&medium low发现xss本地搭建实操 medium作为初学者的我第一次接触比较浅的绕过思路high low 发现xss 本关无过滤 <script>alert(/xss/)</script> //或 <script>confirm(/xss/)</script> //或 <scr…...

从云计算到物联网:虚拟化技术的演变与嵌入式系统的融合

文章目录 一、硬件性能提升&#xff1a;摩尔定律与嵌入式虚拟化二、CPU多核技术&#xff1a;为嵌入式虚拟化提供支持三、业务负载整合&#xff1a;嵌入式虚拟化的核心需求四、降低硬件成本&#xff1a;虚拟化技术的经济效益五、软件重用与移植&#xff1a;虚拟化技术的优势六、…...

linux 文件查看 head 、 cat 、 less 、tail 、grep

查看文件详细信息 stat 文件 cat 》》适合显示小文件【行数比较少】&#xff0c;如果行数较多&#xff0c;屏幕显示不完整&#xff08;如果虚拟操作&#xff0c;是无法上下键的&#xff0c;或者滚动鼠标的&#xff0c;第三方 xsheel&#xff0c;crt 可以方向键查看&#xf…...

13.2 Web与Servlet进阶(❤❤)

13.2 Web与Servlet进阶 1. 请求与响应1.1 URL与URI1.2 HTTP请求的结构1. 结构2.后端获取访问工具类型:getHeader().toLowerCase方法1.3 响应的结构1. 结构2. 响应常见状态码3. 后端设置响应参数4. 响应的ContentType作用1.4 请求转发与响应重定向应用1. 请求转发:getRequestDis…...

记录解决报错--vue前后端分离,接口401(Unauthorized)

1.场景 前端访问不了后端接口。报错401。 2.解决步骤 ①在页面console.log(111)查看走到代码的位置没有。&#xff08;走到了&#xff0c;没问题&#xff09; ②查看vue.config.js配置。这段配置就是vue访问api的url。&#xff08;没问题&#xff09; devServer: {port: 80…...

【笔记】Android 常用编译模块和输出产物路径

模块&产物路径 具体编译到软件的路径要看编译规则的分区&#xff0c;代码中模块编译输出的产物基本对应。 Android 代码模块 编译产物路径设备adb路径Comment 模块device/mediatek/system/common/ 资源overlay/telephony/frameworks/base/core 文件举例res/res/values-m…...

部署私有知识库项目FastGPT

FastGPT 是一个基于 LLM 大语言模型的知识库问答系统,提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排,从而实现复杂的问答场景。 项目文档: [快速了解 FastGpt | FastGptFastGPT 是一个基于 LLM 大语言模型的知识库问答系统,提供开箱即…...

【2024-02-02】华为秋招笔试三道编程题解

恭喜发现宝藏&#xff01;搜索公众号【TechGuide】回复公司名&#xff0c;解锁更多新鲜好文和互联网大厂的笔经面经。 作者TechGuide【全网同名】 订阅专栏&#xff1a; 【专享版】2024最新大厂笔试真题解析&#xff0c;错过必后悔的宝藏资源&#xff01; 第一题&#xff1a;找…...

银行数据仓库体系实践(8)--主数据模型设计

主数据区域中保留了数据仓库的所有基础数据及历史数据&#xff0c;是数据仓库中最重要的数据区域之一&#xff0c;那主数据区域中主要分为近源模型区和整合&#xff08;主题&#xff09;模型区。上一节讲到了模型的设计流程如下图所示。那近源模型层的设计在第2.3和3这两个步骤…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...