【JAVA】SpringBoot + skywalking 将接口的入参、出参、异常等信息上报到skywalking 链路追踪服务器上
【JAVA】SpringBoot + skywalking 将接口的入参、出参、异常等信息上报到skywalking 链路追踪服务器上
1.下载SkyWalking APM
https://skywalking.apache.org/downloads/
jdk8 不支持 SkyWalking APM 9.3.0以上版本,所以这里我们下载 9.3.0版本


2.下载 Java Agent
https://skywalking.apache.org/downloads/
Java Agent 我们现在最新版本的 9.2.0

3.启动 SkyWalking APM 服务
3.1 windows环境
3.1.1 解压apache-skywalking-apm-9.3.0.tar.gz
3.1.2 进入解压后的bin目录,点击 startup.bat 启动SkyWalking APM服务

3.1.3 访问 http://127.0.0.1:8080/
如果访问出现空白页面,等待1分钟左右

3.2 linux环境
3.2.1 上传apache-skywalking-apm-9.3.0.tar.gz到服务器并解压
tar -zxvf apache-skywalking-apm-9.3.0.tar.gz
3.2.2 开放端口 8080,11800,12800
firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --zone=public --add-port=11800/tcp --permanent
firewall-cmd --zone=public --add-port=12800/tcp --permanent## 开放或者关闭,需要刷新防火墙规则
firewall-cmd --reload
3.2.3 启动SkyWalking APM,进入解压后的bin目录
sh startup.sh

3.2.4 访问 http://IP:8080/
如果访问出现空白页面,等待1分钟左右

4.SpringBoot项目中引入以下依赖
<!-- lombok ↓ --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- lombok ↑ --><!-- hutool ↓ --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.28</version></dependency><!-- hutool ↑ --><!-- aspectjrt 切面编程 ↓ --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId></dependency><!-- aspectjrt 切面编程 ↑ --><!-- skywalking-trace skyWalking监控相关 ↓ --><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-trace</artifactId><version>9.1.0</version></dependency><!-- skywalking-trace ↑ --><!-- skywalking-logback skyWalking中的traceId记录到logback日志 ↓ --><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-logback-1.x</artifactId><version>9.1.0</version></dependency><!-- skywalking-logback ↑ -->
4.1 resources文件夹下创建 logback-spring.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration><!-- 读取application.yml中的日志配置 --><springProperty scope="context" name="LOG_PATH" source="logging.file.path"/><springProperty scope="context" name="LOG_NAME" source="logging.file.log-name"/><springProperty scope="context" name="MAX_HISTORY" source="logging.file.days"/><!-- 定义控制台输出格式 --><appender name="CONSOLE" 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{50} - %msg%n</pattern></layout></encoder></appender><!--skywalking grpc 日志收集--><appender name="SKYWALKING" 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{50} -%msg%n</Pattern></layout></encoder></appender><!-- 定义每天生成一个日志文件,并归档生成压缩包 --><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>./${LOG_NAME}.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 每天生成一个日志文件 --><fileNamePattern>${LOG_PATH}/${LOG_NAME}.%d{yyyy-MM-dd}.log</fileNamePattern><!-- 最多保留指定天数的日志文件 --><maxHistory>${MAX_HISTORY}</maxHistory></rollingPolicy><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{50} -%msg%n</Pattern></layout></encoder></appender><!-- 日志级别设置 --><root level="INFO"><appender-ref ref="CONSOLE"/><appender-ref ref="SKYWALKING"/><appender-ref ref="FILE"/></root>
</configuration>
4.2 application.yml 文件中增加
# 日志配置
logging:file:# 日志生成的目录path: ./log# 日志文件名称log-name: log# 日志文件保留天数days: 3level:ROOT: info# com.xhs 包名称 com.xhs: info
4.2 定义 接口日志切面
package com.xhs.aspect;import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.apm.toolkit.trace.ActiveSpan;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;import javax.servlet.ServletRequest;/*** @desc: 接口日志切面,目的是将接口的入参、出参、异常等信息上报到SkyWalking链路追踪服务器上,以便我们进行日志分析* @projectName: spring-boot-skywalking* @author: xhs* @date: 2024-06-17 017 10:24* @version: JDK 1.8*/@Slf4j
@Aspect
@Component
public class ControllerLogAspect {public static final String BIG_STR_SUB_PATTERN = "(:s*\"[^,\":]{8192,}?\")";/*** API的切点,拦截所有controller*/@Pointcut("execution(public * com.xhs.controller.*.*(..))")public void apiPointcut() {}/*** 在方法执行前进行参数判断、在方法执行后记录日志** @param joinPoint 入参*/@Around("apiPointcut()")public Object executeFaceAspect(ProceedingJoinPoint joinPoint) throws Throwable {Object returnObj = null;Object[] parameters = joinPoint.getArgs();try {returnObj = joinPoint.proceed();} catch (Exception e) {log.error("SkyWalking aspect catch exception {}", TraceContext.traceId(), e);ActiveSpan.tag("异常", ExceptionUtil.getRootCauseMessage(e));throw e;} finally {if (parameters != null && parameters.length > 0) {for (int i = 0; i < parameters.length; i++) {try {Object nowObj = parameters[i];if (nowObj instanceof ServletRequest) {continue;}ActiveSpan.tag("入参" + i, replaceLog(JSON.toJSONString(nowObj)));} catch (Exception ignore) {}}}if (returnObj != null) {try {ActiveSpan.tag("出参", replaceLog(JSON.toJSONString(returnObj)));} catch (Exception ignore) {}}}return returnObj;}/** 格式化日志** @param logStr 入参* @return String*/public static String replaceLog(String logStr) {if (StringUtils.hasLength(logStr)) {return logStr.replaceAll(BIG_STR_SUB_PATTERN, ":\"*\"");}return StrUtil.EMPTY;}
}
4.3 创建测试接口,并添加jvm参数启动
# D:\soft-ware\skywalking-agent\skywalking-agent.jar 解压apache-skywalking-java-agent-9.2.0.tgz 后的skywalking-agent.jar jar包的地址
-javaagent:D:\soft-ware\skywalking-agent\skywalking-agent.jar
# xhs1.0: skywalking 服务的 service groups 名称
# spring-boot-skywalking:service names 名称
-Dskywalking.agent.service_name=xhs1.0::spring-boot-skywalking
# 127.0.0.1 skywalking apm 服务地址
-Dskywalking.collector.backend_service=127.0.0.1:11800
linux环境下需要把 apache-skywalking-java-agent-9.2.0.tgz上传到服务器解压,然后在启动命令后面加上上面的三个参数
#!/bin/bash# jar包名称
JAR_FILE="spring-boot-skywalking.jar"
# pid 名称
PID_FILE="spring-boot-skywalking.pid"
# skywalking-agent jar包地址
SKYWALKING_AGENT_URL="/root/skywalking-agent/skywalking-agent.jar"
# skywalking SERVICE_NAME
SKYWALKING_SERVICE_NAME="xhs1.0::spring-boot-skywalking"
# skywalking SERVICE_NAME
SKYWALKING_BACKEND_SERVICE="127.0.0.1:11800"start() {if [ -f "$PID_FILE" ]; thenecho "应用程序已在运行,PID: $(cat $PID_FILE) .........."else# 后台启动jar包,并将启动日志输出到log.log文件中nohup java -javaagent:$SKYWALKING_AGENT_URL -Dskywalking.agent.service_name=$SKYWALKING_SERVICE_NAME -Dskywalking.collector.backend_service=$SKYWALKING_BACKEND_SERVICE -jar -Dloader.path=.,3rd-li $JAR_FILE >/dev/null 2>&1 &echo $! > $PID_FILEecho "应用程序已成功启动,PID: $(cat $PID_FILE) .........."fi
}stop() {if [ -f "$PID_FILE" ]; thenkill -9 $(cat $PID_FILE)rm $PID_FILEecho "应用程序已成功停止.........."elseecho "应用程序未运行.........."fi
}restart() {echo "正在重启.........."stopstartecho "重启成功.........."
}case "$1" instart)start;;stop)stop;;restart)restart;;*)echo "使用: $0 {start|stop|restart} 命令"exit 1;;
esac
4.3 访问创建的测试接口,刷新浏览器查看 SkyWalking APM 服务

4.3.1 SpringBoot 日志

4.3.2 SkyWalking APM 服务查看接口调用的情况及日志信息


5. 项目源码地址
https://gitee.com/xhs101/spring-boot-skywalking.git
相关文章:
【JAVA】SpringBoot + skywalking 将接口的入参、出参、异常等信息上报到skywalking 链路追踪服务器上
【JAVA】SpringBoot skywalking 将接口的入参、出参、异常等信息上报到skywalking 链路追踪服务器上 1.下载SkyWalking APM https://skywalking.apache.org/downloads/ jdk8 不支持 SkyWalking APM 9.3.0以上版本,所以这里我们下载 9.3.0版本 2.下载 Java Agent …...
[xmake]构建静态库和动态库
xmake 静态库和动态库 在xmake中创建静态库和动态库的方法非常相似。以下是创建静态库和动态库的基本步骤: 创建xmake工程文件(xmake.lua)。 配置工程属性,包括工程名、版本等。 添加源代码文件到工程中。 设置是创建静态库还…...
功能测试 之 单模块测试----轮播图、登录、注册
单功能怎么测? 需求分析 拆解测试点 编写用例 1.轮播图 (1)需求分析 位置:后台--页面--广告管理---广告列表(搜索index页面增加广告位2) 操作完成后需要点击admin---更新缓存,前台页面刷新生效 (2)拆解…...
MyBatis-PageHelper 源码解说
归档 GitHub: MyBatis-PageHelper-源码解说 总说明 源码仓库: https://github.com/pagehelper/Mybatis-PageHelper克隆:git clone https://github.com/pagehelper/Mybatis-PageHelper.git切分支(tag):git checkout m…...
基于uni-app和图鸟UI的智慧校园圈子小程序开发实践
摘要: 随着教育信息化和“互联网教育”的快速发展,智慧校园建设已成为推动校园管理现代化、提高教育教学质量的重要手段。本文介绍了基于uni-app和图鸟UI开发的智慧校园圈子小程序,旨在通过一站式服务、个性化定制、数据互通和安全可靠等特点…...
STM32 keil工程移植到Visual Studio Code环境中编译
1、GCC Vscode 搭建 STM32 开发环境 GCC Vscode 搭建 STM32 开发环境(一)- 环境部署 - 知乎 (zhihu.com) 2、在原有keil工程下找到原本CUBEMX生成的.ioc工程文件 3、将.ioc文件复制一个新的文件夹下双击打开工程,将IDE选为Makefile&…...
细说CountDownLatch
CountDownLatch是Java中提供的一个同步辅助类,它允许一个或多个线程等待其他线程完成操作。在面试中,面试官经常会询问候选人是否在实际项目中使用过CountDownLatch,以评估其对多线程编程和并发控制的理解和经验。本文将详细介绍CountDownLat…...
java-克隆应用
5.2 创建复杂对象 对于某些复杂对象,通过克隆来创建其副本比通过构造函数创建新实例更加高效。例如,当对象包含大量字段或需要进行复杂初始化时,克隆可以显著提高性能。 java 复制代码 class ComplexObject implements Cloneable { private …...
RPC协议
3.8 既然有 HTTP 协议,为什么还要有 RPC 假设我们需要在 A 电脑的进程发一段数据到 B 电脑的进程,我们一般会在代码里使用 Socket 进行编程。 这时候,我们可选项一般也就 TCP 和 UDP 二选一。TCP 可靠,UDP 不可靠。 类似下面这…...
医疗器械3D全景展会在线漫游创造数字化时代的展览新篇章
在数字化浪潮的引领下,VR虚拟网上展会正逐渐成为企业展示品牌实力、吸引潜在客户的首选平台。我们与广交会携手走过三年多的时光,凭借优质的服务和丰富的经验,赢得了客户的广泛赞誉。 面对传统展会活动繁多、企业运营繁忙的挑战,许…...
IP_Endpoint类型在CAPL中的使用
在使用TCP/IP协议栈通信时,创建Socket套接字调用接口函数实现通信的整个过程成为一种主流且便捷的方式。在CAPL中,Client需要创建TCP或UDP套接字,绑定自己的IP地址和一个端口号,作为自己的通信端点。 on key c {clientsocket = tcpOpen(ipGetAddressAsNumber("192.16…...
数据资产与用户体验优化:深入挖掘用户数据,精准分析用户需求与行为,优化产品与服务,提升用户体验与满意度,打造卓越的用户体验,赢得市场认可
一、引言 在数字化时代,数据已经成为企业最宝贵的资产之一。通过深入挖掘和分析用户数据,企业能够精准把握用户需求和行为,从而优化产品与服务,提升用户体验和满意度。这不仅有助于企业在激烈的市场竞争中脱颖而出,还…...
基于TCAD与紧凑模型结合方法探究陷阱对AlGaN/GaN HEMTs功率附加效率及线性度的影响
来源:Investigation of Traps Impact on PAE and Linearity of AlGaN/GaN HEMTs Relying on a Combined TCAD–Compact Model Approach(TED 24年) 摘要 本文提出了一种新型建模方法,用于分析GaN HEMTs的微波功率性能。通过结合工…...
具身智能概念
具身智能作为人工智能发展的一个重要分支,伴随着大模型技术的爆发与硬件成本的降低,即软硬件技术走向成熟,正在成为广泛关注的热门,一时之间,具身智能机器人也成为了科技界新的风向标。 什么是具身智能? …...
C++ 43 之 自增运算符的重载
#include <iostream> #include <string> using namespace std;class MyInt{friend ostream& operator<< (ostream& cout , MyInt& int1); public:MyInt(){this->m_num 0;}// 前置自增: 成员函数实现运算符的重载 返回的是 引用&a…...
计算机网络:1概述、2物理层
目录 概述因特网网络、互连网(互联网)与因特网的区别与关系因特网发展的三个阶段因特网服务提供者(Internet Service Provider,ISP)因特网的标准化工作因特网的管理结构 三种交换电路交换分组交换报文交换 计算机网络性…...
【Ardiuno】实验使用ESP32接收电脑发送的串口数据(图文)
使用ESP32可以非常方便的与电脑进行串口通讯,一般我们可以用串口接收ESP32的输出作为调试使用,今天我们再来实验一下从电脑端向ESP32单片机发送数据。 发送数据程序代码: void setup() {Serial.begin(9600); }void loop() { if(Serial.ava…...
思科ospf+rip重发布配置命令
——————————————————————————————————————————— 基础配置 R1 Router>en #进入配置模式 Router#conf #进入配置模式 Router(config)#h…...
椭圆的矩阵表示法
椭圆的矩阵表示法 flyfish 1. 标准几何表示法 标准几何表示法是通过椭圆的几何定义来表示的: x 2 a 2 y 2 b 2 1 \frac{x^2}{a^2} \frac{y^2}{b^2} 1 a2x2b2y21其中, a a a 是椭圆的长半轴长度, b b b 是椭圆的短半轴长度。 2.…...
智慧乡村和美人家信息化系统
一、简介 智慧乡村和美人家信息化系统是一个综合管理平台,集成了首页概览、一张图可视化、数据填报、智能评估、便捷申报、公开公示、任务管理、活动发布和灵活配置等功能。该系统不仅提升了乡村管理效率,也优化了家庭生活的便捷性。通过一张图…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
