optimize jvmattach

This commit is contained in:
huoyo 2022-10-01 20:02:31 +08:00
parent 0e4ee19b14
commit a59615e5f1
4 changed files with 59 additions and 27 deletions

View File

@ -6,7 +6,7 @@
<groupId>cn.langpy</groupId> <groupId>cn.langpy</groupId>
<artifactId>ko-time</artifactId> <artifactId>ko-time</artifactId>
<version>2.2.8</version> <version>2.2.9</version>
<name>KoTime</name> <name>KoTime</name>
<description>A springboot tool for tracking the paths of the methods,which can help you to find methods's performances easily.</description> <description>A springboot tool for tracking the paths of the methods,which can help you to find methods's performances easily.</description>
<licenses> <licenses>

View File

@ -4,8 +4,8 @@ import cn.langpy.kotime.annotation.Auth;
import cn.langpy.kotime.config.DefaultConfig; import cn.langpy.kotime.config.DefaultConfig;
import cn.langpy.kotime.constant.KoConstant; import cn.langpy.kotime.constant.KoConstant;
import cn.langpy.kotime.model.*; import cn.langpy.kotime.model.*;
import cn.langpy.kotime.service.ClassService;
import cn.langpy.kotime.service.GraphService; import cn.langpy.kotime.service.GraphService;
import cn.langpy.kotime.util.ClassUtil;
import cn.langpy.kotime.util.Context; import cn.langpy.kotime.util.Context;
import cn.langpy.kotime.util.InvalidAuthInfoException; import cn.langpy.kotime.util.InvalidAuthInfoException;
import cn.langpy.kotime.util.KoUtil; import cn.langpy.kotime.util.KoUtil;
@ -36,9 +36,6 @@ public class KoTimeController {
@Value("${ko-time.password:}") @Value("${ko-time.password:}")
private String password; private String password;
@Value("${ko-time.agent-path:}")
private String agentPath;
private static Logger log = Logger.getLogger(KoTimeController.class.toString()); private static Logger log = Logger.getLogger(KoTimeController.class.toString());
private final String uiKitCssText = getResourceText("kostatic/uikit.min.css"); private final String uiKitCssText = getResourceText("kostatic/uikit.min.css");
private final String uiKitJsText = getResourceText("kostatic/uikit.min.js"); private final String uiKitJsText = getResourceText("kostatic/uikit.min.js");
@ -281,16 +278,10 @@ public class KoTimeController {
map.put("message", "无法解析文件"); map.put("message", "无法解析文件");
return map; return map;
} }
File jar = null; final ClassService classService = ClassService.getInstance();
if (!StringUtils.hasText(agentPath)) { classService.updateClass(className,file.getAbsolutePath());
jar = ClassUtil.createJar();
agentPath = jar.getAbsolutePath();
}
ClassUtil.updateClass(agentPath,className,file.getAbsolutePath());
file.deleteOnExit(); file.deleteOnExit();
if (jar!=null) {
jar.deleteOnExit();
}
map.put("state", 1); map.put("state", 1);
map.put("message", "更新成功"); map.put("message", "更新成功");
return map; return map;

View File

@ -0,0 +1,31 @@
package cn.langpy.kotime.service;
import java.util.logging.Logger;
public interface ClassService {
void updateClass(String className, String classPath);
static ClassService getInstance() {
return ClassServiceFactory.getInstance();
}
}
class ClassServiceFactory {
private static Logger log = Logger.getLogger(ClassServiceFactory.class.toString());
private static ClassService instance = null;
public static ClassService getInstance() {
if (instance == null) {
synchronized (ClassService.class) {
if (instance == null) {
instance = new JvmAttachClassService();
}
}
}
return instance;
}
}

View File

@ -1,24 +1,34 @@
package cn.langpy.kotime.util; package cn.langpy.kotime.service;
import cn.langpy.kotime.util.Context;
import net.bytebuddy.agent.VirtualMachine; import net.bytebuddy.agent.VirtualMachine;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import java.io.*; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream; import java.util.jar.JarOutputStream;
import java.util.logging.Logger; import java.util.logging.Logger;
/** public class JvmAttachClassService implements ClassService{
* zhangchang private static Logger log = Logger.getLogger(JvmAttachClassService.class.toString());
*/
public class ClassUtil {
private static Logger log = Logger.getLogger(ClassUtil.class.toString()); private File agentJar;
public static void updateClass(String jarPath, String className, String classPath) { public JvmAttachClassService() {
this.agentJar = createAgentJar();
}
@Override
public void updateClass(String className, String classPath) {
try { try {
if (agentJar==null || !agentJar.exists()) {
agentJar = createAgentJar();
}
VirtualMachine virtualMachine = VirtualMachine.ForHotSpot.attach(Context.getPid()); VirtualMachine virtualMachine = VirtualMachine.ForHotSpot.attach(Context.getPid());
virtualMachine.loadAgent(jarPath, className + "-" + classPath); virtualMachine.loadAgent(agentJar.getAbsolutePath(), className + "-" + classPath);
Thread.sleep(500); Thread.sleep(500);
virtualMachine.detach(); virtualMachine.detach();
} catch (IOException e) { } catch (IOException e) {
@ -29,7 +39,7 @@ public class ClassUtil {
} }
} }
public static File createJar() { public File createAgentJar() {
File jarFile = null; File jarFile = null;
try { try {
jarFile = File.createTempFile("classTrans-", ".jar", new File(System.getProperty("java.io.tmpdir"))); jarFile = File.createTempFile("classTrans-", ".jar", new File(System.getProperty("java.io.tmpdir")));
@ -55,10 +65,11 @@ public class ClassUtil {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
jarFile.deleteOnExit();
return jarFile; return jarFile;
} }
private static void buildElement(JarOutputStream out, String[] fileNames, String[] filePaths) throws IOException { private void buildElement(JarOutputStream out, String[] fileNames, String[] filePaths) throws IOException {
for (int i = 0; i < fileNames.length; i++) { for (int i = 0; i < fileNames.length; i++) {
ClassPathResource classPathResource = new ClassPathResource(filePaths[i]); ClassPathResource classPathResource = new ClassPathResource(filePaths[i]);
addJarFile(out, fileNames[i], classPathResource.getInputStream()); addJarFile(out, fileNames[i], classPathResource.getInputStream());
@ -66,7 +77,7 @@ public class ClassUtil {
} }
private static void addJarFile(JarOutputStream out, String packagePath, InputStream in) { private void addJarFile(JarOutputStream out, String packagePath, InputStream in) {
try { try {
out.putNextEntry(new JarEntry(packagePath)); out.putNextEntry(new JarEntry(packagePath));
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
@ -81,5 +92,4 @@ public class ClassUtil {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }