Skip to content

Commit

Permalink
Merge pull request #32 from scouter-project/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
bill23-kim committed Sep 19, 2015
2 parents fdf3d03 + 0c443e4 commit ac4c223
Show file tree
Hide file tree
Showing 38 changed files with 835 additions and 1,363 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ scouter.agent.host/bin/*
scouter.agent.host.boot/bin/*
scouter.server.boot/bin/*
*.log
scouter.enduser.script/.project
6 changes: 3 additions & 3 deletions scouter.agent.java/src/scouter/agent/AgentTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ public class AgentTransformer implements ClassFileTransformer {
static {
final Configure conf = Configure.getInstance();
reload();
hook_signature=conf.hook_signature;
hook_signature=conf.getHookSignature();
ConfObserver.add("AgentTransformer", new Runnable(){
public void run() {
if(conf.hook_signature !=hook_signature){
if(conf.getHookSignature() !=hook_signature){
reload();
}
hook_signature=conf.hook_signature;
hook_signature=conf.getHookSignature();
}
});

Expand Down
47 changes: 20 additions & 27 deletions scouter.agent.java/src/scouter/agent/Configure.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ public final static synchronized Configure getInstance() {
public boolean enable_plus_objtype = false;

public boolean enable_asm_jdbc = true;
public boolean enable_asm_httpsession = true;
public boolean enable_asm_socket = true;

public boolean http_debug_querystring;
Expand Down Expand Up @@ -145,7 +144,8 @@ public final static synchronized Configure getInstance() {

public String plugin_classpath = "";

public StringSet log_ignore = new StringSet();
public String log_ignore = "";
public StringSet log_ignore_set = new StringSet();

public String hook_args = "";
public String hook_return = "";
Expand Down Expand Up @@ -174,6 +174,10 @@ public final static synchronized Configure getInstance() {
public String hook_apicall_info = "";
public String hook_jsp = "";

public String hook_jdbc_pstmt = "";
public String hook_jdbc_stmt = "";
public String hook_jdbc_rs = "";

// /LOAD CONTROL/////
public boolean enable_reject_service = false;
public int max_active_service = 10000;
Expand All @@ -187,7 +191,6 @@ public final static synchronized Configure getInstance() {

public String plugin_http_trace = "";
public String plugin_apicall_name = "";
public String plugin_http_trace_param = "";
public boolean profile_fullstack_service_error = false;
public boolean profile_fullstack_apicall_error = false;
public int profile_fullstack_lines = 0;
Expand All @@ -201,16 +204,13 @@ public final static synchronized Configure getInstance() {
public String this_txid = "scouter_this_txid";
public String caller_txid = "scouter_caller_txid";

public int hook_signature;
private int hook_signature;

public int max_concurrent_server_request = 10;
public String userid_jsessionid = "JSESSIONID";

public boolean enable_auto_service_trace = false;
public boolean enable_auto_service_backstack = true;

public boolean debug_apicall = false;

public String hook_future_task = "";
public String hook_future_task_prefix = "";

Expand All @@ -224,11 +224,6 @@ public final static synchronized Configure getInstance() {
public boolean enable_hook_step7 = true;
public boolean enable_hook_step8 = true;

public int stat_sql_max = 10000;
public int stat_api_max = 5000;
public int stat_app_sql_max = 10000;
public int stat_app_api_max = 5000;

public String direct_patch_class = "";

public long max_think_time = DateUtil.MILLIS_PER_FIVE_MINUTE;
Expand Down Expand Up @@ -368,15 +363,15 @@ private void apply() {
this.profile_sql_escape = getBoolean("profile_sql_escape", true);

this.enable_asm_jdbc = getBoolean("enable_asm_jdbc", getBoolean("enable.asm.jdbc", true));
this.enable_asm_httpsession = getBoolean("enable_asm_httpsession", getBoolean("enable.asm.httpsession", true));
this.enable_asm_socket = getBoolean("enable_asm_socket", getBoolean("enable.asm.socket", true));

this.udp_packet_max = getInt("udp_packet_max", getInt("udp.packet.max", 60000));

this.yellow_line_time = getLong("yellow_line_time", getLong("yellow.line.time", 3000));
this.red_line_time = getLong("red_line_time", getLong("red.line.time", 8000));

this.log_ignore = getStringSet("log_ignore", ",");
this.log_ignore = getValue("log_ignore", "");
this.log_ignore_set = getStringSet("log_ignore", ",");

this.debug_udp_xlog = getBoolean("debug_udp_xlog", getBoolean("debug.udp.xlog", false));
this.debug_udp_object = getBoolean("debug_udp_object", getBoolean("debug.udp.object", false));
Expand Down Expand Up @@ -414,10 +409,14 @@ private void apply() {
this._hook_method_ignore_classes = new StringSet(StringUtil.tokenizer(
this.hook_method_ignore_classes.replace('.', '/'), ","));

this.hook_service = getValue("hook_service", getValue("hook.service", ""));
this.hook_apicall = getValue("hook_apicall", getValue("hook.subcall", ""));
this.hook_service = getValue("hook_service", "");
this.hook_apicall = getValue("hook_apicall", "");
this.hook_apicall_info = getValue("hook_apicall_info", "");
this.hook_jsp = getValue("hook_jsp", getValue("hook.jsp", ""));
this.hook_jsp = getValue("hook_jsp", "");

this.hook_jdbc_pstmt = getValue("hook_jdbc_pstmt", "");
this.hook_jdbc_stmt = getValue("hook_jdbc_stmt", "");
this.hook_jdbc_rs = getValue("hook_jdbc_rs", "");

this.hook_signature ^= this.hook_args.hashCode();
this.hook_signature ^= this.hook_return.hashCode();
Expand Down Expand Up @@ -461,7 +460,6 @@ private void apply() {
this.this_txid = getValue("this_txid", "scouter_this_txid");
this.caller_txid = getValue("caller_txid", "scouter_caller_txid");

this.max_concurrent_server_request = getInt("max_concurrent_server_request", 10);
this.debug_dbopen_fullstack = getBoolean("debug_dbopen_fullstack", false);
this.debug_dbopen_autocommit = getBoolean("debug_dbopen_autocommit", false);

Expand All @@ -473,8 +471,6 @@ private void apply() {
this.enable_auto_service_trace = getBoolean("enable_auto_service_trace", false);
this.enable_auto_service_backstack = getBoolean("enable_auto_service_backstack", true);

this.debug_apicall = getBoolean("debug_apicall", false);

this.hook_future_task = getValue("hook_future_task", "");
this.hook_future_task_prefix = getValue("hook_future_task_prefix", "");

Expand All @@ -488,13 +484,6 @@ private void apply() {
this.enable_hook_step7 = getBoolean("enable_hook_step7", true);
this.enable_hook_step8 = getBoolean("enable_hook_step8", true);

this.stat_sql_max = getInt("stat_sql_max", 10000);
this.stat_api_max = getInt("stat_api_max", 5000);
this.stat_app_sql_max = getInt("stat_app_sql_max", 10000);
this.stat_app_api_max = getInt("stat_app_api_max", 5000);

this.plugin_http_trace_param = getValue("plugin_http_trace_param", "");

this.direct_patch_class = getValue("direct_patch_class", "");
this.max_think_time = getLong("max_think_time", DateUtil.MILLIS_PER_FIVE_MINUTE);

Expand Down Expand Up @@ -728,6 +717,10 @@ public MapValue getKeyValueInfo() {

return m;
}

public int getHookSignature() {
return this.hook_signature;
}

public static void main(String[] args) {
System.out.println(Configure.getInstance().getKeyValueInfo().toString().replace(',', '\n'));
Expand Down
2 changes: 1 addition & 1 deletion scouter.agent.java/src/scouter/agent/Logger.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static void println(String id, String message) {
}

private static boolean checkOk(String id) {
if (Configure.getInstance().log_ignore.hasKey(id))
if (Configure.getInstance().log_ignore_set.hasKey(id))
return false;
long last = lastLog.get(id);
long now = System.currentTimeMillis();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,78 +14,90 @@
* limitations under the License.
*/
package scouter.agent.asm;

import java.util.HashSet;

import scouter.agent.ClassDesc;
import scouter.agent.Configure;
import scouter.agent.Logger;
import scouter.agent.asm.jdbc.P0ClearParametersMV;
import scouter.agent.asm.jdbc.P0ExecuteMV;
import scouter.agent.asm.jdbc.P0InitMV;
import scouter.agent.asm.jdbc.P0SetMV;
import scouter.agent.asm.jdbc.PsClearParametersMV;
import scouter.agent.asm.jdbc.PsExecuteMV;
import scouter.agent.asm.jdbc.PsInitMV;
import scouter.agent.asm.jdbc.PsSetMV;
import scouter.agent.asm.jdbc.StExecuteMV;
import scouter.agent.asm.util.MethodSet;
import scouter.agent.trace.SqlParameter;
import scouter.agent.trace.TraceSQL;
import scouter.org.objectweb.asm.ClassVisitor;
import scouter.org.objectweb.asm.MethodVisitor;
import scouter.org.objectweb.asm.Opcodes;
import scouter.org.objectweb.asm.Type;

public class JDBCPreparedStatementASM implements IASM, Opcodes {
public final HashSet<String> target = new HashSet<String>();
public final HashSet<String> target = MethodSet.getHookingClassSet(Configure.getInstance().hook_jdbc_pstmt);
public final HashSet<String> noField = new HashSet<String>();

public JDBCPreparedStatementASM() {
target.add("org/mariadb/jdbc/MySQLPreparedStatement");
target.add("oracle/jdbc/driver/OraclePreparedStatement");
target.add("com/mysql/jdbc/PreparedStatement");

target.add("org/postgresql/jdbc2/AbstractJdbc2Statement");
target.add("org/apache/derby/client/am/PreparedStatement");
target.add("jdbc/FakePreparedStatement");
target.add("net/sourceforge/jtds/jdbc/JtdsPreparedStatement");


target.add("jdbc/FakePreparedStatement");
target.add("jdbc/FakePreparedStatement2");
target.add("com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement");
target.add("com/tmax/tibero/jdbc/TbPreparedStatement");
target.add("org/hsqldb/jdbc/JDBCPreparedStatement");

target.add("com/mysql/jdbc/ServerPreparedStatement");
target.add("com/mysql/jdbc/PreparedStatement");

// @skyworker - MySQL ServerPreparedStatement는 특별히 필드를 추가하지 않음
noField.add("com/mysql/jdbc/ServerPreparedStatement");
noField.add("jdbc/FakePreparedStatement2");
}

public boolean isTarget(String className) {
return target.contains(className) ;
return target.contains(className);
}

public ClassVisitor transform(ClassVisitor cv, String className, ClassDesc classDesc) {
if (target.contains(className) == false) {
return cv;
}
if(Configure.getInstance().enable_asm_jdbc==false)
if (Configure.getInstance().enable_asm_jdbc == false)
return cv;
Logger.println("A106", "jdbc pstmt found: " + className + " redefinable="+Configure.JDBC_REDEFINED);
return new PreparedStatementCV(cv);
Logger.println("A106", "jdbc pstmt found: " + className);
return new PreparedStatementCV(cv, noField);
}
}

class PreparedStatementCV extends ClassVisitor implements Opcodes {
public PreparedStatementCV(ClassVisitor cv) {
HashSet<String> noField;

public PreparedStatementCV(ClassVisitor cv, HashSet<String> noField) {
super(ASM4, cv);
this.noField = noField;
}

private String owner;

@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
//add dummy field

if(Configure.JDBC_REDEFINED==false){
super.visitField(ACC_PUBLIC, TraceSQL.PSTMT_PARAM_FIELD, Type.getDescriptor(SqlParameter.class), null, null).visitEnd();
}
this.owner = name;
if (noField.contains(name) == false) {
// add trace field
super.visitField(ACC_PUBLIC, TraceSQL.PSTMT_PARAM_FIELD, Type.getDescriptor(SqlParameter.class), null, null)
.visitEnd();
}
}

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
if(Configure.JDBC_REDEFINED){
return ifRedefined(access, name, desc, mv);
}else{
return ifNotRedefined(access, name, desc, mv);
}
}
private MethodVisitor ifRedefined(int access, String name, String desc, MethodVisitor mv) {
if ("<init>".equals(name)) {
return new PsInitMV(access, desc, mv, owner);
} else {
Expand All @@ -106,25 +118,5 @@ private MethodVisitor ifRedefined(int access, String name, String desc, MethodVi
}
return mv;
}
private MethodVisitor ifNotRedefined(int access, String name, String desc, MethodVisitor mv) {
if ("<init>".equals(name)) {
return new P0InitMV(access, desc, mv, owner);
} else {
String targetDesc = P0SetMV.getSetSignature(name);
if (targetDesc != null) {
if (targetDesc.equals(desc)) {
return new P0SetMV(access, name, desc, mv, owner);
}
} else if (P0ExecuteMV.isTarget(name)) {
if (desc.startsWith("()")) {
return new P0ExecuteMV(access, desc, mv, owner);
} else if (desc.startsWith("(Ljava/lang/String;)")) {
return new StExecuteMV(access, desc, mv, owner);
}
} else if ("clearParameters".equals(name) && "()V".equals(desc)) {
return new P0ClearParametersMV(access, desc, mv, owner);
}
}
return mv;
}

}
22 changes: 15 additions & 7 deletions scouter.agent.java/src/scouter/agent/asm/JDBCResultSetASM.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,60 @@
* limitations under the License.
*/
package scouter.agent.asm;

import java.util.HashSet;
import scouter.agent.ClassDesc;
import scouter.agent.Configure;
import scouter.agent.Logger;
import scouter.agent.asm.jdbc.RsCloseMV;
import scouter.agent.asm.jdbc.RsNextMV;
import scouter.agent.asm.util.MethodSet;
import scouter.org.objectweb.asm.ClassVisitor;
import scouter.org.objectweb.asm.MethodVisitor;
import scouter.org.objectweb.asm.Opcodes;

public class JDBCResultSetASM implements IASM, Opcodes {
public final HashSet<String> target = new HashSet<String>();
public final HashSet<String> target = MethodSet.getHookingClassSet(Configure.getInstance().hook_jdbc_rs);

public JDBCResultSetASM() {
target.add("org/mariadb/jdbc/MySQLResultSet");

target.add("oracle/jdbc/driver/OracleResultSetImpl");
target.add("com/mysql/jdbc/ResultSetImpl");
target.add("org/postgresql/jdbc2/AbstractJdbc2ResultSet");
target.add("org/apache/derby/client/am/ResultSet");
target.add("jdbc/FakeResultSet");
target.add("net/sourceforge/jtds/jdbc/JtdsResultSet");

target.add("com/microsoft/sqlserver/jdbc/SQLServerResultSet");
target.add("com/tmax/tibero/jdbc/TbResultSet");

target.add("oracle/jdbc/driver/InsensitiveScrollableResultSet");
target.add("oracle/jdbc/driver/SensitiveScrollableResultSet");

target.add("org/hsqldb/jdbc/JDBCResultSet");
}

public boolean isTarget(String className) {
return target.contains(className) ;
return target.contains(className);
}

public ClassVisitor transform(ClassVisitor cv, String className, ClassDesc classDesc) {
if (target.contains(className) == false) {
return cv;
}
if(Configure.getInstance().enable_asm_jdbc==false)
if (Configure.getInstance().enable_asm_jdbc == false)
return cv;
Logger.println("A107", "jdbc rs found: " + className);
return new ResultSetCV(cv);
}
}

class ResultSetCV extends ClassVisitor implements Opcodes {
public ResultSetCV(ClassVisitor cv) {
super(ASM4, cv);
}

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
Expand Down
Loading

0 comments on commit ac4c223

Please sign in to comment.