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

用javaagent和javassist实现Arthas的watch功能

一、被监控的服务 spring-boot-demo

 

1、 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.techhf</groupId><artifactId>spring-boot-demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.4.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId><version>2.3.4.RELEASE</version></dependency></dependencies></project>

2、DemoController

package com.techhf.demo.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author shiweijia* @date 2024/8/1 17:31*/
@RequestMapping("/demo")
@RestController
public class DemoController {@RequestMapping("/hello")public String hello(String name) {return "hello world " + name;}}

3、DemoApplication

 

package com.techhf.demo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @author shiweijia* @date 2024/8/1 17:30*/
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}

4、运行DemoApplication

-javaagent:D:/temp/jvm-agent-1.0-SNAPSHOT-jar-with-dependencies.jar 

 二、jvm-agent

1、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.techhf</groupId><artifactId>jvm-agent</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.30.2-GA</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>3.3.0</version><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><archive><manifestEntries><Premain-Class>com.techhf.agent.WatchAgent</Premain-Class><Agent-Class>com.techhf.agent.WatchAgent</Agent-Class><Can-Redefine-Classes>true</Can-Redefine-Classes><Can-Retransform-Classes>true</Can-Retransform-Classes></manifestEntries></archive></configuration><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin></plugins></build></project>

2、WatchAgent

package com.techhf.agent;import java.lang.instrument.Instrumentation;/*** @author shiweijia* @date 2024/8/1 16:00*/
public class WatchAgent {public static void premain(String agentArgs, Instrumentation inst) {agentArgs = "com.techhf.demo.controller.DemoController,hello";System.out.println("premain attached with args: " + agentArgs);transform(agentArgs, inst);}public static void agentmain(String agentArgs, Instrumentation inst) {System.out.println("agentmain attached with args: " + agentArgs);transform(agentArgs, inst);}private static void transform(String agentArgs, Instrumentation inst) {// 解析 agentArgs 来获取类名和方法名String[] parts = agentArgs.split(",");String className = parts[0];String methodName = parts[1];inst.addTransformer(new WatchTransformer(className, methodName));}}

3、WatchTransformer

package com.techhf.agent;import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;/*** @author shiweijia* @date 2024/8/3 16:56*/
public class WatchTransformer implements ClassFileTransformer {private String className;private String methodName;public WatchTransformer(String className, String methodName) {this.className = className;this.methodName = methodName;}@Overridepublic byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {className = className.replace('/', '.');if (this.className.equals(className)) {try {ClassPool pool = ClassPool.getDefault();CtClass cc = pool.get(className);CtMethod method = cc.getDeclaredMethod(methodName);String beforeCode = "{ System.out.print(\"Before Method Name: \" + \"" + method.getName() + "\" + \", Parameters: \"); " +"for (int i = 0; i < $args.length; i++) { " +"    System.out.print($args[i]); " +"} " +"System.out.println(); }";method.insertBefore(beforeCode);method.insertAfter("{ System.out.println(\"After Method Name: \"+\"" + method.getName()+ "\" + \", Return: \" + $_); }");return cc.toBytecode();} catch (Exception e) {e.printStackTrace();}}return classfileBuffer;}
}

三、启动时监控

如上述实例,运行时加入-javaagent相关参数即可。

四、运行时监控

import com.sun.tools.attach.VirtualMachine;/*** @author shiweijia* @date 2024/8/1 17:35*/
public class AttachLoader {public static void main(String[] args) {if (args.length < 2) {System.out.println("Usage: AttachLoader <pid> <agent-path> <agent-args>");System.exit(1);}String pid = args[0];String agentPath = args[1];String agentArgs = args[2];try {// 获取目标 JVM 进程VirtualMachine vm = VirtualMachine.attach(pid);vm.loadAgent(agentPath, agentArgs);// 可选:在需要时分离(detach)// vm.detach();System.out.println("Agent loaded into PID " + pid);} catch (Exception e) {e.printStackTrace();}}}

运行参数为:

34496 D:\temp\jvm-agent-1.0-SNAPSHOT-jar-with-dependencies.jar com.techhf.demo.controller.DemoController,hello

采用运行时监控需要注意:spring 是动态代理的,agentmain无法直接监控具体的类。需要优化相关的实现。

相关文章:

用javaagent和javassist实现Arthas的watch功能

一、被监控的服务 spring-boot-demo 1、 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&q…...

golang 图片转1bit color bmp图片

问题背景 一些打印机需要的都是1bit color bmp图片,但是golang中没有直接的办法,官方image库最低bpp为8,打印机无法使用。 在github上找到了很多资源,都没有直接能转的,突然看到一个老外,可以支持plattered图片转位1bit color bmp图片,然后自己先把图片转位plattered黑…...

Leetcode75-5 反转字符串的元音字母

本质上来说就是反转字符串 一部分需要反转 一部分不动 思路: 1.用String字符串倒序拼接 就是过滤掉不是元音字符 然后把所有的字符&#xff08;非元音的直接复制过来 元音字母直接从反转的字符串里边复制即可&#xff09; 2.看了题解发现自己写的啰嗦了 就是一个双指针问题用…...

static关键字在Java中的作用与用法

static关键字在Java中的作用与用法 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在Java中&#xff0c;static关键字是一个非常重要的概念&#xff0c;用于定义静态成员、方法和内部类。它的使用可…...

50etf期权行权采用什么交割方式 ?

50ETF期权是欧式期&#xff0c;要到期日当天才能行权交制&#xff0c;其交割方式是实物交割买卖双方在到期行权日时需要准备一手交钱&#xff0c;一手收货或是一手交&#xff0c;一手收钱&#xff0c;如果持有期权到达到期日之前&#xff0c;投资者认为行权并不划算&#xff0c…...

ts-node 报错 ERR_UNKNOWN_FILE_EXTENSION

问题 有个monorepo项目&#xff0c;在最外层一次性打包 3 个项目的脚本已经成功实现&#xff0c;如下&#xff1a; "build:test": "cross-env NODE_ENVtest vite build --mode test && esno ./build/script/postBuild.ts", "build:prod"…...

水域救援设备,保护水域安全_鼎跃安全

季作为一年中最炎热的季节&#xff0c;不仅带来了难耐的高温&#xff0c;也悄然间加剧了水域安全问题的严峻性。这一时期&#xff0c;正值学生群体享受悠长暑假的宝贵时光&#xff0c;他们往往倾向于寻找清凉之地以解酷暑&#xff0c;水域因此成为了不少学生的首选之地。然而&a…...

openmetadata本地编译环境搭建

openmetadata本地编译环境搭建 本地环境&#xff1a; Docker 20 or higher Java JDK 17 Antlr 4.9.2 - sudo make install_antlr_cli JQ - brew install jq (osx) apt-get install jq (Ubuntu) Maven 3.5.x or higher - (with Java JDK 11) Python 3.7, 3.8 or 3.9 Node…...

LeetCode Hard|【25. K 个一组翻转链表】

力扣题目链接 首先我们考虑一种很直观的思路&#xff1a; 遍历链表&#xff0c;统计链表长度遍历链表&#xff0c;进行翻转 对于每一组长度为 K 的节点&#xff0c;进行翻转如果剩余节点不足 K 个&#xff0c;则不进行翻转 连接翻转后的子链表 这里我们用的就是只用 O(1) 额外内…...

python爬虫预备知识三-多进程

python实现多进程的方法&#xff1a;fork、multiprocessing模块创建多进程。 os.fork方法 os.fork方法只适合于unix/linux系统&#xff0c;不支持windows系统。 fork方法调用一次会返回两次&#xff0c;原因在于操作系统将当前进程&#xff08;父进程&#xff09;复制出一份…...

【zlm】针对单个设备的音频的编码的设置

目录 结论 原理 测试 结论 为了防止zlm音频配置里设置成opus优先&#xff0c;在国标推流时&#xff0c;调用push时&#xff0c;默认加上codecpcma 如下 https://10.60.100.196:10443/index/api/webrtc?applive&streamtest&typepush&codecpcma 原理 测试 …...

文案人的梦工场,网易入职指南!

网易云对于咱们一些有点文艺的文案策划来说&#xff0c;简直就是梦中情司。 在这里工作锻炼机会很多&#xff0c;也很开拓眼界&#xff0c;能获得相当于在别处3倍能力的成长速度&#xff0c;福利待遇也是很好的。 要进入网易云音乐做文案策划&#xff0c;你可以按照以下步骤进…...

做一个能和你互动玩耍的智能机器人之七-接入对话和大模型

接入科大迅飞的语音识别&#xff1a; private void printResult(RecognizerResult results) {String text JsonParser2.parseIatResult(results.getResultString());String sn null;// 读取json结果中的sn字段try {JSONObject resultJson new JSONObject(results.getResult…...

阿里巴巴商家联系方式采集软件使用教程

以下是一个批量访问阿里巴巴商家店铺的Python代码示例&#xff1a; import requestsdef visit_shop(shop_url):try:response requests.get(shop_url)if response.status_code 200:print(f"成功访问店铺&#xff1a;{shop_url}")else:print(f"访问店铺失败&am…...

Golang | Leetcode Golang题解之第326题3的幂

题目&#xff1a; 题解&#xff1a; func isPowerOfThree(n int) bool {return n > 0 && 1162261467%n 0 }...

人大金仓(Kingbase)数据库高阶函数详解

人大金仓&#xff08;Kingbase&#xff09;数据库高阶函数详解 人大金仓&#xff08;Kingbase&#xff09;数据库是一款基于 PostgreSQL 的国产关系型数据库(PostgreSQL 高阶函数详解&#xff1a;全面深入的功能与实用示例 )&#xff0c;提供了丰富的高阶函数&#xff0c;以支…...

云原生真机实验

基于Proxmox VE构建中小企业云计算平台 首先Proxmox VE是什么&#xff1f;能用来做什么&#xff1f; Proxmox VE是一个完整的企业虚拟化开源平台。借助内置的 Web 界面&#xff0c;可以在单个解决方案上轻松管理 VM(开虚拟机的) 和容器、软件定义的存储和网络、高可用性群集以…...

【电子电路学习笔记】——模电笔记

关于专栏&#xff1a;本专栏用于分享学习电子电路过程中记录的笔记。模电部分使用的教材是高等教育出版社&#xff0c;华成英主编的《模拟电子技术基础&#xff08;第六版&#xff09;》&#xff08;其他版本的内容差不多&#xff0c;建议使用最新版教材&#xff09;&#xff1…...

部署伪分布式 Hadoop集群

部署伪分布式 Hadoop集群 一、JDK安装配置1.1 下载JDK1.2 上传解压1.3 java环境配置 二、伪分布式 Hadoop 安装配置2.1 Hadoop 下载2.2 上传解压2.3 Hadoop 文件目录介绍2.4 Hadoop 配置2.4.1 修改 core-site.xml 配置文件2.4.2 修改 hdfs-site.xml 配置文件2.4.3 修改 hadoop-…...

十九、虚拟机VMware Workstation(CentOSDebian)的安装

目录 &#x1f33b;&#x1f33b; 一、安装 VMware Workstation1.1 安装 VMware Workstation1.2 虚拟机上安装 CentOS1.3 虚拟机安装 Debian 二、配置Debian方便第三方工具远程连接2.1 配置debian2.2 安装远程SSH工具并连接 一、安装 VMware Workstation 官网下载 本地资源库…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

基于鸿蒙(HarmonyOS5)的打车小程序

1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

【深尚想】TPS54618CQRTERQ1汽车级同步降压转换器电源芯片全面解析

1. 元器件定义与技术特点 TPS54618CQRTERQ1 是德州仪器&#xff08;TI&#xff09;推出的一款 汽车级同步降压转换器&#xff08;DC-DC开关稳压器&#xff09;&#xff0c;属于高性能电源管理芯片。核心特性包括&#xff1a; 输入电压范围&#xff1a;2.95V–6V&#xff0c;输…...

python打卡day49@浙大疏锦行

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 一、通道注意力模块复习 & CBAM实现 import torch import torch.nn as nnclass CBAM(nn.Module):def __init__…...