All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scouter.xtra.jdbc.TraceSQL0 Maven / Gradle / Ivy

There is a newer version: 2.20.0
Show newest version
/*
 *  Copyright 2015 the original author or authors. 
 *  @https://github.com/scouter-project/scouter
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package scouter.xtra.jdbc;

import scouter.agent.Configure;
import scouter.agent.Logger;
import scouter.agent.netio.data.DataProxy;
import scouter.agent.proxy.ITraceSQL;
import scouter.agent.trace.LoadedContext;
import scouter.agent.trace.LocalContext;
import scouter.agent.trace.SqlParameter;
import scouter.agent.trace.TraceContext;
import scouter.agent.trace.TraceContextManager;
import scouter.lang.step.HashedMessageStep;
import scouter.lang.step.MessageStep;
import scouter.lang.step.MethodStep;
import scouter.lang.step.SqlStep3;
import scouter.lang.step.SqlXType;
import scouter.util.SysJMX;
import scouter.util.ThreadUtil;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import static scouter.agent.trace.TraceSQL.escapeLiteral;

/**
 * Trace SQL
 * @author @author Paul S.J. Kim([email protected])
 * @author Gun Lee ([email protected])
 * @author Eunsu Kim
 */
public class TraceSQL0 implements ITraceSQL {
    private static Configure conf = Configure.getInstance();
    private static SQLException slowSqlException = new SLOW_SQL("Slow SQL", "SLOW_SQL");
    private static SQLException tooManyRecordException = new TOO_MANY_RECORDS("TOO_MANY_RECORDS", "TOO_MANY_RECORDS");
    private static SQLException connectionOpenFailException = new CONNECTION_OPEN_FAIL("CONNECTION_OPEN_FAIL", "CONNECTION_OPEN_FAIL");

	@Override
	public Exception getSlowSqlException() {
		return slowSqlException;
	}

	@Override
	public Exception getTooManyRecordException() {
		return tooManyRecordException;
	}

	@Override
	public Exception getConnectionOpenFailException() {
		return connectionOpenFailException;
	}

	@Override
	public Object start(Object o, String sql, byte methodType) {
		TraceContext ctx = TraceContextManager.getContext();
		if (ctx == null) {
			if (conf._log_background_sql) {
				Logger.println("background: " + sql);
			}
			return null;
		}
		// to debug
		if (conf._profile_fullstack_sql_connection_enabled && ctx.debug_sql_call == false) {
			ctx.debug_sql_call = true;
			StringBuffer sb = new StringBuffer();
			if (o instanceof Statement) {
				try {
					Connection c = ((Statement) o).getConnection();
					sb.append("Connection = ").append(c.getClass().getName()).append("\n");
					sb.append("          ").append(c).append("\n");
					sb.append("          AutoCommit =").append(c.getAutoCommit()).append("\n");
				} catch (Exception e) {
					sb.append(e).append("\n");
				}
			}
			sb.append(ThreadUtil.getThreadStack());
			ctx.profile.add(new MessageStep((int) (System.currentTimeMillis() - ctx.startTime), sb.toString()));
		}
		// Looking for the position of calling SQL COMMIT
		if (conf.profile_fullstack_sql_commit_enabled) {
			if ("commit".equalsIgnoreCase(sql)) {
				ctx.profile.add(new MessageStep((int) (System.currentTimeMillis() - ctx.startTime),
						ThreadUtil.getThreadStack()));
			}
		}
		SqlStep3 step = new SqlStep3();
		step.start_time = (int) (System.currentTimeMillis() - ctx.startTime);
		if (ctx.profile_thread_cputime) {
			step.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu);
		}
		if (sql == null) {
			sql = "unknown";
		} else {
			sql = escapeLiteral(sql, step);
		}
		step.hash = DataProxy.sendSqlText(sql);
		step.xtype =(byte)(SqlXType.STMT | methodType);
		ctx.profile.push(step);
		ctx.sqltext = sql;
		return new LocalContext(ctx, step);
	}

	@Override
	public Object start(Object o, SqlParameter args, byte methodType) {
		TraceContext ctx = TraceContextManager.getContext();
		if (ctx == null) {
			if (conf._log_background_sql && args != null) {
				Logger.println("background: " + args.getSql());
			}
			return null;
		}

		//debug sql call
		if (conf._profile_fullstack_sql_execute_debug_enabled) {
			StringBuffer sb = new StringBuffer();
			if (o instanceof Statement) {
				try {
					Connection c = ((Statement) o).getConnection();
					sb.append(c).append("\n");
					sb.append("Connection = ").append(c.getClass().getName()).append("\n");
					sb.append("AutoCommit = ").append(c.getAutoCommit()).append("\n");
				} catch (Exception e) {
					sb.append(e).append("\n");
				}
			}
			sb.append(ThreadUtil.getStackTrace(Thread.currentThread().getStackTrace(), 2));
			ctx.profile.add(new MessageStep((int) (System.currentTimeMillis() - ctx.startTime), sb.toString()));

		} else if (conf._profile_fullstack_sql_connection_enabled && ctx.debug_sql_call == false) {
			ctx.debug_sql_call = true;
			StringBuffer sb = new StringBuffer();
			if (o instanceof Statement) {
				try {
					Connection c = ((Statement) o).getConnection();
					sb.append(c).append("\n");
					sb.append("Connection = ").append(c.getClass().getName()).append("\n");
					sb.append("AutoCommit = ").append(c.getAutoCommit()).append("\n");
				} catch (Exception e) {
					sb.append(e).append("\n");
				}
			}
			sb.append(ThreadUtil.getStackTrace(Thread.currentThread().getStackTrace(), 2));
			ctx.profile.add(new MessageStep((int) (System.currentTimeMillis() - ctx.startTime), sb.toString()));
		}

		// Looking for the position of calling SQL COMMIT
		if (conf.profile_fullstack_sql_commit_enabled) {
			if ("commit".equalsIgnoreCase(args.getSql())) {
				ctx.profile.add(new MessageStep((int) (System.currentTimeMillis() - ctx.startTime),
						ThreadUtil.getThreadStack()));
			}
		}
		SqlStep3 step = new SqlStep3();
		step.start_time = (int) (System.currentTimeMillis() - ctx.startTime);
		if (ctx.profile_thread_cputime) {
			step.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu);
		}
		ctx.sqlActiveArgs = args;
		String sql = "unknown";
		if (args != null) {
			sql = args.getSql();
			sql = escapeLiteral(sql, step);
			step.param = args.toString(step.param);
		}
		if (sql != null) {
			step.hash = DataProxy.sendSqlText(sql);
		}
		step.xtype =(byte)(SqlXType.PREPARED | methodType);
		ctx.profile.push(step);
		ctx.sqltext = sql;
		return new LocalContext(ctx, step);
	}

	@Override
	public Object driverConnect(Object conn, String url) {
		if (conn == null)
			return conn;
		if (conf.trace_db2_enabled == false)
			return conn;
		if (conn instanceof WrConnection)
			return conn;
		return new WrConnection((Connection) conn);
	}

	@Override
	public Object getConnection(Object conn) {
		if (conn == null)
			return conn;
		if (conn instanceof WrConnection) 
			return conn;
		return new WrConnection((Connection) conn);
	}

	@Override
	public Object dbcOpenEnd(Object conn, Object stat) {
		if (stat == null)
			return conn;
		LocalContext lctx = (LocalContext) stat;
		MethodStep step = (MethodStep) lctx.stepSingle;
		if (step == null)
			return conn;
		TraceContext tctx = lctx.context;
		if (tctx == null)
			return conn;

		Connection conn0 = (Connection) conn;
		step.elapsed = (int) (System.currentTimeMillis() - tctx.startTime) - step.start_time;
		if (tctx.profile_thread_cputime) {
			step.cputime = (int) (SysJMX.getCurrentThreadCPU() - tctx.startCpu) - step.start_cpu;
		}
		tctx.profile.pop(step);
		if (conf.profile_connection_autocommit_status_enabled) {
			HashedMessageStep ms = new HashedMessageStep();
			try {
				ms.hash = DataProxy.sendHashedMessage("AutoCommit : " + conn0.getAutoCommit());
			} catch (Exception e) {
				ms.hash = DataProxy.sendHashedMessage("AutoCommit : " + e);
			}
			ms.start_time = (int) (System.currentTimeMillis() - tctx.startTime);
			if (tctx.profile_thread_cputime) {
				ms.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - tctx.startCpu);
	        }
			tctx.profile.add(ms);
		}
		if (conn instanceof DetectConnection)
			return conn;
		else
			return new DetectConnection(conn0);
	}

	@Override
	public void ctxLookup(Object this1, Object ctx) {
		if (TraceContextManager.isForceDiscarded()) {
			return;
		}

		if (ctx instanceof DataSource) {
			LoadedContext.put(ctx);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy