Skip to content

Commit 7e241ba

Browse files
authored
Merge pull request #314 from scouter-project/dev
Dev
2 parents c1b4d13 + 8b45344 commit 7e241ba

File tree

12 files changed

+573
-18
lines changed

12 files changed

+573
-18
lines changed

scouter.agent.host/src/scouter/agent/counter/task/HostPerf.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,11 @@ public void disk(CounterBasket pw) {
278278
if (conf.disk_ignore_names.hasKey(dir))
279279
continue;
280280

281-
usage = sigar.getFileSystemUsage(dir);
281+
try {
282+
usage = sigar.getFileSystemUsage(dir);
283+
} catch (SigarException e) {
284+
continue;
285+
}
282286

283287
float pct = (float) (usage.getUsePercent() * 100);
284288
if (pct >= conf.disk_fatal_pct && fatal.length() < 32756) {

scouter.agent.java/src/scouter/agent/AgentTransformer.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,14 @@ public static void reload() {
8888
temp.add(new CallRunnableASM());
8989

9090
temp.add(new SpringReqMapASM());
91-
9291
temp.add(new SocketASM());
93-
9492
temp.add(new JspServletASM());
93+
temp.add(new MapImplASM());
94+
temp.add(new UserExceptionASM());
95+
temp.add(new UserExceptionHandlerASM());
9596

9697
temp.add(new AddFieldASM());
9798

98-
temp.add(new MapImplASM());
99-
10099
asms = temp;
101100
}
102101

scouter.agent.java/src/scouter/agent/Configure.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ public final static synchronized Configure getInstance() {
109109
public boolean profile_http_parameter_enabled;
110110
@ConfigDesc("Service URL prefix for Http parameter profile")
111111
public String profile_http_parameter_url_prefix = "/";
112+
@ConfigDesc("spring controller method parameter profile")
113+
public boolean profile_spring_controller_method_parameter_enabled = false;
112114
@ConfigDesc("Activating profile summary function")
113115
public boolean profile_summary_mode_enabled = false;
114116
@ConfigDesc("Calculating CPU time by profile")
@@ -137,6 +139,8 @@ public final static synchronized Configure getInstance() {
137139
public boolean profile_fullstack_sql_error_enabled = false;
138140
@ConfigDesc("Stack profile in occurrence of commit error")
139141
public boolean profile_fullstack_sql_commit_enabled = false;
142+
@ConfigDesc("Stack profile in occurrence of sql error")
143+
public boolean profile_fullstack_hooked_exception_enabled = false;
140144
@ConfigDesc("Number of stack profile lines in occurrence of error")
141145
public int profile_fullstack_max_lines = 0;
142146
@ConfigDesc("Activating SQL literal task")
@@ -352,6 +356,12 @@ public final static synchronized Configure getInstance() {
352356
public String hook_jdbc_rs_classes = "";
353357
@ConfigDesc("Method set for dbconnection wrapping")
354358
public String hook_jdbc_wrapping_driver_patterns = "";
359+
@ConfigDesc("Exception class patterns - These will seem as error on xlog view. (ex) my.app.BizException,my.app.exception.*Exception")
360+
public String hook_exception_class_patterns = "";
361+
@ConfigDesc("Exception class exlude patterns")
362+
public String hook_exception_exlude_class_patterns = "";
363+
@ConfigDesc("Exception handler patterns - exceptions passed to these methods are treated as error on xlog view. (ex) my.app.myHandler.handleException")
364+
public String hook_exception_handler_method_patterns = "";
355365

356366
@ConfigDesc("Hook for supporting async servlet")
357367
public boolean hook_async_servlet_enabled = true;
@@ -556,6 +566,7 @@ private void apply() {
556566
this.profile_http_querystring_enabled = getBoolean("profile_http_querystring_enabled", false);
557567
this.profile_http_header_enabled = getBoolean("profile_http_header_enabled", false);
558568
this.profile_http_parameter_enabled = getBoolean("profile_http_parameter_enabled", false);
569+
this.profile_spring_controller_method_parameter_enabled = getBoolean("profile_spring_controller_method_parameter_enabled", false);
559570
this.profile_summary_mode_enabled = getBoolean("profile_summary_mode_enabled", false);
560571
this.xlog_lower_bound_time_ms = getInt("xlog_lower_bound_time_ms", 0);
561572
this.trace_service_name_header_key = getValue("trace_service_name_header_key", null);
@@ -651,6 +662,10 @@ private void apply() {
651662
this.hook_jdbc_stmt_classes = getValue("hook_jdbc_stmt_classes", "");
652663
this.hook_jdbc_rs_classes = getValue("hook_jdbc_rs_classes", "");
653664
this.hook_jdbc_wrapping_driver_patterns = getValue("hook_jdbc_wrapping_driver_patterns", "");
665+
this.hook_exception_class_patterns = getValue("hook_exception_class_patterns", "");
666+
this.hook_exception_exlude_class_patterns = getValue("hook_exception_exlude_class_patterns", "");
667+
this.hook_exception_handler_method_patterns = getValue("hook_exception_handler_method_patterns", "");
668+
654669
this.hook_async_servlet_enabled = getBoolean("_hook_async_servlet_enabled", true);
655670

656671
this.hook_async_context_dispatch_patterns = getValue("hook_async_context_dispatch_patterns", "");
@@ -691,6 +706,8 @@ private void apply() {
691706
this.profile_fullstack_apicall_error_enabled = getBoolean("profile_fullstack_apicall_error_enabled", false);
692707
this.profile_fullstack_sql_error_enabled = getBoolean("profile_fullstack_sql_error_enabled", false);
693708
this.profile_fullstack_sql_commit_enabled = getBoolean("profile_fullstack_sql_commit_enabled", false);
709+
this.profile_fullstack_hooked_exception_enabled = getBoolean("profile_fullstack_hooked_exception_enabled", false);
710+
694711
this.profile_fullstack_max_lines = getInt("profile_fullstack_max_lines", 0);
695712
this.profile_fullstack_rs_leak_enabled = getBoolean("profile_fullstack_rs_leak_enabled", false);
696713
this.profile_fullstack_stmt_leak_enabled = getBoolean("profile_fullstack_stmt_leak_enabled", false);

scouter.agent.java/src/scouter/agent/asm/JDBCPreparedStatementASM.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ public class JDBCPreparedStatementASM implements IASM, Opcodes {
3939
public final HashSet<String> noField = new HashSet<String>();
4040

4141
public JDBCPreparedStatementASM() {
42+
//mariadb 1.5.9
43+
target.add("org/mariadb/jdbc/AbstractPrepareStatement");
44+
4245
target.add("org/mariadb/jdbc/AbstractMariaDbPrepareStatement");
4346
target.add("org/mariadb/jdbc/MariaDbClientPreparedStatement");
4447
target.add("org/mariadb/jdbc/MariaDbServerPreparedStatement");

scouter.agent.java/src/scouter/agent/asm/SpringReqMapASM.java

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import scouter.org.objectweb.asm.ClassVisitor;
2626
import scouter.org.objectweb.asm.MethodVisitor;
2727
import scouter.org.objectweb.asm.Opcodes;
28+
import scouter.org.objectweb.asm.Type;
2829
import scouter.org.objectweb.asm.commons.LocalVariablesSorter;
2930
import scouter.util.StringUtil;
3031

@@ -132,12 +133,25 @@ class SpringReqMapMV extends LocalVariablesSorter implements Opcodes {
132133
private static final String TRACEMAIN = "scouter/agent/trace/TraceMain";
133134
private final static String SET_METHOD = "setServiceName";
134135
private static final String SET_METHOD_SIGNATURE = "(Ljava/lang/String;)V";
136+
137+
private final static String CONTROLLER_START_METHOD = "startSpringControllerMethod";
138+
private static final String CONTROLLER_START_METHOD_SIGNATURE = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/Object;)V";
139+
135140
private String methodRequestMappingUrl;
136141
private String methodType;
137142
private boolean isRequestHandler = false;
138143

144+
private String className;
145+
private int access;
146+
private String methodName;
147+
private String desc;
148+
139149
public SpringReqMapMV(String className, int access, String methodName, String desc, MethodVisitor mv) {
140150
super(ASM4, access, desc, mv);
151+
this.className = className;
152+
this.access = access;
153+
this.methodName = methodName;
154+
this.desc = desc;
141155
}
142156

143157
@Override
@@ -166,6 +180,77 @@ public void visitCode() {
166180
Logger.println("[Apply Spring F/W REST URL] " + serviceUrl);
167181
AsmUtil.PUSH(mv, serviceUrl);
168182
mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACEMAIN, SET_METHOD, SET_METHOD_SIGNATURE, false);
183+
184+
//=========== call for spring request mapping method capture plugin ============
185+
Type[] types = Type.getArgumentTypes(desc);
186+
boolean isStatic = (access & ACC_STATIC) != 0;
187+
188+
int sidx = isStatic ? 0 : 1;
189+
190+
int arrVarIdx = newLocal(Type.getType("[Ljava/lang/Object;"));
191+
AsmUtil.PUSH(mv, types.length);
192+
mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
193+
mv.visitVarInsn(Opcodes.ASTORE, arrVarIdx);
194+
195+
for (int i = 0; i < types.length; i++) {
196+
Type type = types[i];
197+
mv.visitVarInsn(Opcodes.ALOAD, arrVarIdx);
198+
AsmUtil.PUSH(mv, i);
199+
200+
switch (type.getSort()) {
201+
case Type.BOOLEAN:
202+
mv.visitVarInsn(Opcodes.ILOAD, sidx);
203+
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;",
204+
false);
205+
break;
206+
case Type.BYTE:
207+
mv.visitVarInsn(Opcodes.ILOAD, sidx);
208+
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
209+
break;
210+
case Type.CHAR:
211+
mv.visitVarInsn(Opcodes.ILOAD, sidx);
212+
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;",
213+
false);
214+
break;
215+
case Type.SHORT:
216+
mv.visitVarInsn(Opcodes.ILOAD, sidx);
217+
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
218+
break;
219+
case Type.INT:
220+
mv.visitVarInsn(Opcodes.ILOAD, sidx);
221+
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;",
222+
false);
223+
break;
224+
case Type.LONG:
225+
mv.visitVarInsn(Opcodes.LLOAD, sidx);
226+
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
227+
break;
228+
case Type.FLOAT:
229+
mv.visitVarInsn(Opcodes.FLOAD, sidx);
230+
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
231+
break;
232+
case Type.DOUBLE:
233+
mv.visitVarInsn(Opcodes.DLOAD, sidx);
234+
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
235+
break;
236+
default:
237+
mv.visitVarInsn(Opcodes.ALOAD, sidx);
238+
}
239+
mv.visitInsn(Opcodes.AASTORE);
240+
sidx += type.getSize();
241+
}
242+
AsmUtil.PUSH(mv, className);
243+
AsmUtil.PUSH(mv, methodName);
244+
AsmUtil.PUSH(mv, desc);
245+
if (isStatic) {
246+
AsmUtil.PUSHNULL(mv);
247+
} else {
248+
mv.visitVarInsn(Opcodes.ALOAD, 0);
249+
}
250+
mv.visitVarInsn(Opcodes.ALOAD, arrVarIdx);
251+
252+
mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACEMAIN, CONTROLLER_START_METHOD, CONTROLLER_START_METHOD_SIGNATURE, false);
253+
169254
}
170255
mv.visitCode();
171256
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
* @https://github.com/scouter-project/scouter
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package scouter.agent.asm;
19+
20+
import scouter.agent.ClassDesc;
21+
import scouter.agent.Configure;
22+
import scouter.agent.asm.util.AsmUtil;
23+
import scouter.agent.asm.util.HookingSet;
24+
import scouter.agent.trace.TraceMain;
25+
import scouter.org.objectweb.asm.ClassVisitor;
26+
import scouter.org.objectweb.asm.MethodVisitor;
27+
import scouter.org.objectweb.asm.Opcodes;
28+
29+
import java.util.List;
30+
31+
public class UserExceptionASM implements IASM, Opcodes {
32+
String exceptionPatterns = HookingSet.classPattrensToMethodPatterns(Configure.getInstance().hook_exception_class_patterns, "<init>");
33+
String exceptionExcludePatterns = HookingSet.classPattrensToMethodPatterns(Configure.getInstance().hook_exception_exlude_class_patterns, "<init>");
34+
35+
private List<HookingSet> target = HookingSet.getHookingMethodSet(exceptionPatterns);
36+
private List<HookingSet> excludeTarget = HookingSet.getHookingMethodSet(exceptionExcludePatterns);
37+
38+
public ClassVisitor transform(ClassVisitor cv, String className, ClassDesc classDesc) {
39+
for (int i = 0; i < target.size(); i++) {
40+
HookingSet mset = target.get(i);
41+
if (mset.classMatch.include(className)) {
42+
for (int j = 0; j < excludeTarget.size(); j++) {
43+
HookingSet excludeHookinSet = excludeTarget.get(j);
44+
if (excludeHookinSet.classMatch.include(className)) {
45+
return cv;
46+
}
47+
}
48+
return new UserExceptionCV(cv, mset, className);
49+
}
50+
}
51+
return cv;
52+
}
53+
}
54+
55+
class UserExceptionCV extends ClassVisitor implements Opcodes {
56+
57+
private HookingSet mset;
58+
private String className;
59+
60+
public UserExceptionCV(ClassVisitor cv, HookingSet mset, String className) {
61+
super(ASM4, cv);
62+
this.mset = mset;
63+
this.className = className;
64+
}
65+
66+
@Override
67+
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
68+
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
69+
if (mv == null || mset.isA(name, desc) == false) {
70+
return mv;
71+
}
72+
return new UserExceptionConsturtorMV(className, desc, mv);
73+
}
74+
}
75+
76+
// ///////////////////////////////////////////////////////////////////////////
77+
class UserExceptionConsturtorMV extends MethodVisitor implements Opcodes {
78+
private static final String CLASS = TraceMain.class.getName().replace('.', '/');
79+
private static final String METHOD = "endExceptionConstructor";
80+
private static final String SIGNATURE = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V";
81+
82+
private String className;
83+
private String methodDesc;
84+
85+
public UserExceptionConsturtorMV(String classname, String methoddesc, MethodVisitor mv) {
86+
super(ASM4, mv);
87+
this.className = classname;
88+
this.methodDesc = methoddesc;
89+
}
90+
91+
@Override
92+
public void visitInsn(int opcode) {
93+
if ((opcode >= IRETURN && opcode <= RETURN) || opcode == ATHROW) {
94+
AsmUtil.PUSH(mv, className);
95+
AsmUtil.PUSH(mv, methodDesc);
96+
mv.visitVarInsn(Opcodes.ALOAD, 0);
97+
mv.visitMethodInsn(Opcodes.INVOKESTATIC, CLASS, METHOD, SIGNATURE,false);
98+
}
99+
mv.visitInsn(opcode);
100+
}
101+
}
102+

0 commit comments

Comments
 (0)