Skip to content

Commit 038ca70

Browse files
committed
add class info
1 parent 830df89 commit 038ca70

File tree

4 files changed

+237
-89
lines changed

4 files changed

+237
-89
lines changed

scouter.agent.java/src/scouter/agent/netio/request/handle/AgentClassHandle.java

Lines changed: 118 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
package scouter.agent.netio.request.handle;
18-
17+
package scouter.agent.netio.request.handle;
18+
1919
import java.io.File;
2020
import java.io.InputStream;
2121
import java.net.JarURLConnection;
@@ -26,91 +26,122 @@
2626
import scouter.lang.pack.MapPack;
2727
import scouter.lang.pack.Pack;
2828
import scouter.lang.value.BlobValue;
29+
import scouter.lang.value.ListValue;
30+
import scouter.lang.value.MapValue;
31+
import scouter.lang.value.Value;
2932
import scouter.net.RequestCmd;
33+
import scouter.util.ClassUtil;
3034
import scouter.util.FileUtil;
31-
32-
public class AgentClassHandle {
33-
34-
@RequestHandler(RequestCmd.OBJECT_LOAD_CLASS_BY_STREAM)
35-
public Pack loadClassAsStream(Pack param) {
36-
MapPack p = (MapPack) param;
37-
String className = p.getText("class");
38-
InputStream is = null;
39-
try {
40-
Class clazz = getClass(className);
41-
if (clazz == null) {
42-
p.put("error", "Not found class " + className);
43-
return p;
44-
}
45-
String clsAsResource = "/" + className.replace('.', '/').concat(".class");
46-
is = clazz.getResourceAsStream(clsAsResource);
47-
p.put("class", new BlobValue(FileUtil.readAll(is)));
48-
} catch (Throwable th) {
49-
Logger.println("A126",th);
50-
p.put("error", th.getMessage());
51-
return p;
52-
} finally {
53-
FileUtil.close(is);
54-
}
55-
return p;
56-
}
57-
58-
private Class getClass(String className) {
59-
Class[] loadedClasses = JavaAgent.getInstrumentation().getAllLoadedClasses();
60-
for (Class c : loadedClasses) {
61-
if (c.getName().equals(className)) {
62-
return c;
63-
}
64-
}
65-
return null;
66-
}
67-
68-
@RequestHandler(RequestCmd.OBJECT_CHECK_RESOURCE_FILE)
69-
public Pack checkJarFile(Pack param) {
70-
MapPack p = (MapPack) param;
71-
String resource = p.getText("resource");
72-
MapPack m = new MapPack();
73-
try {
74-
URL url = new URL(resource);
75-
JarURLConnection connection = (JarURLConnection) url.openConnection();
76-
File file = new File(connection.getJarFileURL().toURI());
77-
if (file.exists() == false) {
78-
m.put("error", "Cannot find jar file.");
79-
} else {
80-
if (file.canRead()) {
81-
m.put("name", file.getName());
82-
m.put("size", file.length());
83-
} else {
84-
m.put("error", "Cannot read jar file.");
85-
}
86-
}
87-
} catch (Exception e) {
88-
m.put("error", e.toString());
89-
}
90-
return m;
91-
}
92-
93-
@RequestHandler(RequestCmd.OBJECT_DOWNLOAD_JAR)
94-
public Pack downloadJar(Pack param) {
95-
MapPack p = (MapPack) param;
96-
String resource = p.getText("resource");
97-
MapPack m = new MapPack();
98-
try {
99-
URL url = new URL(resource);
100-
JarURLConnection connection = (JarURLConnection) url.openConnection();
101-
File file = new File(connection.getJarFileURL().toURI());
102-
if (file.exists() == false) {
103-
m.put("error", "Cannot find jar file.");
104-
} else {
105-
if (file.canRead()) {
106-
m.put("jar", new BlobValue(FileUtil.readAll(file)));
107-
} else {
108-
m.put("error", "Cannot read jar file.");
109-
}
110-
}
111-
} catch (Exception e) {
112-
m.put("error", e.toString());
113-
}
114-
return m;
115-
}
35+
36+
public class AgentClassHandle {
37+
38+
@RequestHandler(RequestCmd.OBJECT_LOAD_CLASS_BY_STREAM)
39+
public Pack loadClassAsStream(Pack param) {
40+
MapPack p = (MapPack) param;
41+
String className = p.getText("class");
42+
InputStream is = null;
43+
try {
44+
Class clazz = getClass(className);
45+
if (clazz == null) {
46+
p.put("error", "Not found class " + className);
47+
return p;
48+
}
49+
String clsAsResource = "/" + className.replace('.', '/').concat(".class");
50+
is = clazz.getResourceAsStream(clsAsResource);
51+
p.put("class", new BlobValue(FileUtil.readAll(is)));
52+
} catch (Throwable th) {
53+
Logger.println("A126", th);
54+
p.put("error", th.getMessage());
55+
return p;
56+
} finally {
57+
FileUtil.close(is);
58+
}
59+
return p;
60+
}
61+
62+
@RequestHandler(RequestCmd.OBJECT_CLASS_DESC)
63+
public Pack getClassInfo(Pack param) {
64+
MapPack p = (MapPack) param;
65+
String className = p.getText("class");
66+
try {
67+
Class clazz = getClass(className);
68+
if (clazz == null) {
69+
p.put("error", "Not found class " + className);
70+
return p;
71+
}
72+
p.put("class", ClassUtil.getClassDescription(clazz));
73+
} catch (Throwable th) {
74+
Logger.println("A126", th);
75+
p.put("error", th.getMessage());
76+
return p;
77+
}
78+
return p;
79+
}
80+
81+
private ListValue toValue(Class[] inf) {
82+
ListValue v = new ListValue();
83+
for (int i = 0; i < inf.length; i++) {
84+
v.add(inf[i].getName());
85+
}
86+
return v;
87+
}
88+
89+
private Class getClass(String className) {
90+
Class[] loadedClasses = JavaAgent.getInstrumentation().getAllLoadedClasses();
91+
for (Class c : loadedClasses) {
92+
if (c.getName().equals(className)) {
93+
return c;
94+
}
95+
}
96+
return null;
97+
}
98+
99+
@RequestHandler(RequestCmd.OBJECT_CHECK_RESOURCE_FILE)
100+
public Pack checkJarFile(Pack param) {
101+
MapPack p = (MapPack) param;
102+
String resource = p.getText("resource");
103+
MapPack m = new MapPack();
104+
try {
105+
URL url = new URL(resource);
106+
JarURLConnection connection = (JarURLConnection) url.openConnection();
107+
File file = new File(connection.getJarFileURL().toURI());
108+
if (file.exists() == false) {
109+
m.put("error", "Cannot find jar file.");
110+
} else {
111+
if (file.canRead()) {
112+
m.put("name", file.getName());
113+
m.put("size", file.length());
114+
} else {
115+
m.put("error", "Cannot read jar file.");
116+
}
117+
}
118+
} catch (Exception e) {
119+
m.put("error", e.toString());
120+
}
121+
return m;
122+
}
123+
124+
@RequestHandler(RequestCmd.OBJECT_DOWNLOAD_JAR)
125+
public Pack downloadJar(Pack param) {
126+
MapPack p = (MapPack) param;
127+
String resource = p.getText("resource");
128+
MapPack m = new MapPack();
129+
try {
130+
URL url = new URL(resource);
131+
JarURLConnection connection = (JarURLConnection) url.openConnection();
132+
File file = new File(connection.getJarFileURL().toURI());
133+
if (file.exists() == false) {
134+
m.put("error", "Cannot find jar file.");
135+
} else {
136+
if (file.canRead()) {
137+
m.put("jar", new BlobValue(FileUtil.readAll(file)));
138+
} else {
139+
m.put("error", "Cannot read jar file.");
140+
}
141+
}
142+
} catch (Exception e) {
143+
m.put("error", e.toString());
144+
}
145+
return m;
146+
}
116147
}

scouter.common/src/scouter/net/RequestCmd.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class RequestCmd {
3030
public static final String OBJECT_ENV = "OBJECT_ENV";
3131
public static final String OBJECT_CLASS_LIST = "OBJECT_CLASS_LIST";
3232
public static final String OBJECT_LOAD_CLASS_BY_STREAM = "OBJECT_LOAD_CLASS_BY_STREAM";
33+
public static final String OBJECT_CLASS_DESC = "OBJECT_CLASS_INFO";
3334
public static final String OBJECT_CHECK_RESOURCE_FILE = "OBJECT_CHECK_RESOURCE_FILE";
3435
public static final String OBJECT_DOWNLOAD_JAR = "OBJECT_DOWNLOAD_JAR";
3536
public static final String OBJECT_STAT_LIST = "OBJECT_STAT_LIST";

scouter.common/src/scouter/util/ClassUtil.java

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015 the original author or authors.
2+
* Copyright 2015 the original author or authors.
33
* @https://github.com/scouter-project/scouter
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,10 +17,13 @@
1717
package scouter.util;
1818

1919
import java.lang.reflect.Field;
20+
import java.lang.reflect.Method;
2021
import java.lang.reflect.Modifier;
2122
import java.util.HashMap;
2223
import java.util.Map;
2324

25+
import scouter.lang.pack.XLogPack;
26+
2427
public class ClassUtil {
2528
public static <V> Map<String, V> getPublicFinalNameMap(Class<?> cls, Class v) {
2629

@@ -65,6 +68,7 @@ public static <V> Map<V, String> getPublicFinalValueMap(Class<?> cls, Class type
6568
}
6669
return map;
6770
}
71+
6872
public static <V> Map<V, String> getPublicFinalDeclaredValueMap(Class<?> cls, Class type) {
6973

7074
Map<V, String> map = new HashMap<V, String>();
@@ -86,4 +90,103 @@ public static <V> Map<V, String> getPublicFinalDeclaredValueMap(Class<?> cls, Cl
8690
}
8791
return map;
8892
}
93+
94+
public static String getClassDescription(Class c1) {
95+
int x = c1.getName().lastIndexOf(".");
96+
97+
StringBuffer sb = new StringBuffer();
98+
if (x > 0) {
99+
sb.append("package ").append(c1.getName().substring(0, x)).append(";\n\n");
100+
}
101+
int acc = c1.getModifiers();
102+
mod(sb, acc, c1.isInterface());
103+
if (c1.isInterface()) {
104+
sb.append("interface ");
105+
} else {
106+
sb.append("class ");
107+
}
108+
109+
if (x > 0) {
110+
sb.append(c1.getName().substring(x + 1));
111+
} else {
112+
sb.append(c1.getName());
113+
}
114+
if (c1.getSuperclass() != null && c1.getSuperclass() != Object.class) {
115+
sb.append(" extends ").append(c1.getSuperclass().getName());
116+
}
117+
Class[] inf = c1.getInterfaces();
118+
for (int i = 0; i < inf.length; i++) {
119+
if (i == 0) {
120+
sb.append(" implements ");
121+
}
122+
if (i > 0)
123+
sb.append(",");
124+
sb.append(inf[i].getName());
125+
}
126+
sb.append("{\n");
127+
Field[] f = c1.getDeclaredFields();
128+
for (int i = 0; i < f.length; i++) {
129+
sb.append("\t");
130+
mod(sb, f[i].getModifiers(), c1.isInterface());
131+
sb.append(toClassString(f[i].getType().getName())).append(" ");
132+
sb.append(f[i].getName()).append(";\n");
133+
}
134+
Method[] m = c1.getDeclaredMethods();
135+
if(f.length>0 && m.length >0){
136+
sb.append("\n");
137+
}
138+
for (int i = 0; i < m.length; i++) {
139+
sb.append("\t");
140+
mod(sb, m[i].getModifiers(), c1.isInterface());
141+
sb.append(toClassString(m[i].getReturnType().getName())).append(" ");
142+
sb.append(m[i].getName());
143+
sb.append("(");
144+
Class[] pc = m[i].getParameterTypes();
145+
for (int p = 0; p < pc.length; p++) {
146+
if (p > 0)
147+
sb.append(",");
148+
sb.append(toClassString(pc[p].getName())).append(" a" + p);
149+
}
150+
sb.append(")");
151+
if (Modifier.isAbstract(m[i].getModifiers()) == false) {
152+
sb.append("{...}\n");
153+
} else {
154+
sb.append(";\n");
155+
}
156+
}
157+
sb.append("}");
158+
return sb.toString();
159+
}
160+
161+
private static String toClassString(String name) {
162+
if (name.startsWith("java.lang")) {
163+
return name.substring("java.lang".length() + 1);
164+
}
165+
return name;
166+
}
167+
168+
private static void mod(StringBuffer sb, int acc, boolean isInterface) {
169+
if (Modifier.isAbstract(acc) && isInterface == false) {
170+
sb.append("abstract ");
171+
}
172+
if (Modifier.isProtected(acc)) {
173+
sb.append("protected ");
174+
}
175+
if (Modifier.isPrivate(acc)) {
176+
sb.append("private ");
177+
}
178+
if (Modifier.isPublic(acc)) {
179+
sb.append("public ");
180+
}
181+
if (Modifier.isFinal(acc)) {
182+
sb.append("final ");
183+
}
184+
if (Modifier.isSynchronized(acc)) {
185+
sb.append("synchronized ");
186+
}
187+
}
188+
189+
public static void main(String[] args) {
190+
System.out.println(getClassDescription(XLogPack.class));
191+
}
89192
}

scouter.server/src/scouter/server/netio/service/handle/AgentInfo.scala

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,20 @@ class AgentInfo {
109109
dout.writeByte(TcpFlag.HasNEXT);
110110
dout.writePack(p);
111111
}
112-
}
112+
}
113+
114+
@ServiceHandler(RequestCmd.OBJECT_CLASS_DESC)
115+
def getClassDesc(din: DataInputX, dout: DataOutputX, login: Boolean) {
116+
val param = din.readPack().asInstanceOf[MapPack];
117+
val objHash = param.getInt("objHash");
118+
val o = AgentManager.getAgent(objHash);
119+
120+
val p = AgentCall.call(o, RequestCmd.OBJECT_CLASS_DESC, param);
121+
if (p != null) {
122+
dout.writeByte(TcpFlag.HasNEXT);
123+
dout.writePack(p);
124+
}
125+
}
113126

114127
@ServiceHandler(RequestCmd.OBJECT_CLASS_LIST)
115128
def getLoadedClassList(din: DataInputX, dout: DataOutputX, login: Boolean) {

0 commit comments

Comments
 (0)