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

scouter.jdbc.DetectConnection 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.jdbc;

import scouter.agent.Configure;
import scouter.agent.Logger;
import scouter.agent.error.CONNECTION_NOT_CLOSE;
import scouter.agent.netio.data.DataProxy;
import scouter.agent.trace.TraceContext;
import scouter.agent.trace.TraceContextManager;
import scouter.agent.util.ICloseManager;
import scouter.agent.util.ILeakableObject;
import scouter.agent.util.LeakableObject;
import scouter.agent.util.LeakableObject2;
import scouter.lang.step.MethodStep;
import scouter.util.SysJMX;

import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.Executor;

public class DetectConnection implements java.sql.Connection {

    private static CONNECTION_NOT_CLOSE error = new CONNECTION_NOT_CLOSE("connection leak detected");
    private final ILeakableObject object;
    java.sql.Connection inner;
    private static Configure conf = Configure.getInstance();

    public DetectConnection(java.sql.Connection inner) {
        this.inner = inner;
        int serviceHash = 0;
        long txid = 0;

        //if(conf._log_trace_enabled) Logger.trace("[DetectConn-InnerObject]" + System.identityHashCode(inner));

        TraceContext ctx = TraceContextManager.getContext();
        if (ctx != null) {
            serviceHash = ctx.serviceHash;
            txid = ctx.txid;
        }

        if (conf._summary_connection_leak_fullstack_enabled) {
            if(conf.__control_connection_leak_autoclose_enabled && conf.__experimental) {
                this.object = new LeakableObject2(new CONNECTION_NOT_CLOSE(), inner, ConnectionCloseManager.getInstance(), serviceHash, txid, true, 2);
            } else {
                this.object = new LeakableObject(new CONNECTION_NOT_CLOSE(), inner.getClass().getName(), serviceHash, txid, true, 2);
            }
        } else {
            if(conf.__control_connection_leak_autoclose_enabled && conf.__experimental) {
                this.object = new LeakableObject2(error, inner, ConnectionCloseManager.getInstance(), serviceHash, txid, false, 0);
            } else {
                this.object = new LeakableObject(error, inner.getClass().getName(), serviceHash, txid, false, 0);
            }
        }
    }

    private static class ConnectionCloseManager implements ICloseManager {
        private static ConnectionCloseManager connectionCloseManager = new ConnectionCloseManager();

        public static ConnectionCloseManager getInstance() {
            return connectionCloseManager;
        }

        @Override
        public boolean close(Object o) {
            try {
                if(o instanceof java.sql.Connection) {
                    ((java.sql.Connection) o).close();
                    return true;
                } else {
                    Logger.println("G001", "Connection auto close - not a connection instance");
                    return false;
                }
            } catch (SQLException e) {
                Logger.println("G002", "Connection auto close exception", e);
                return false;
            }
        }
    }

    final public void setReadOnly(boolean a0) throws java.sql.SQLException {
        this.inner.setReadOnly(a0);
    }

    private static String MSG_CLOSE = "CLOSE";
    private static int HASH_CLOSE;
    private static String MSG_COMMIT = "COMMIT";
    private static int HASH_COMMIT;
    private static String MSG_AUTO_COMMIT_TRUE = "setAutoCommit(true)";
    private static int HASH_AUTO_COMMIT_TRUE;
    private static String MSG_AUTO_COMMIT_FALSE = "setAutoCommit(false)";
    private static int HASH_AUTO_COMMIT_FALSE;

    static {
        try {
            HASH_CLOSE = DataProxy.sendMethodName(MSG_CLOSE);
            HASH_COMMIT = DataProxy.sendMethodName(MSG_COMMIT);
            HASH_AUTO_COMMIT_TRUE = DataProxy.sendMethodName(MSG_AUTO_COMMIT_TRUE);
            HASH_AUTO_COMMIT_FALSE = DataProxy.sendMethodName(MSG_AUTO_COMMIT_FALSE);
        } catch (Exception e) {
        }
    }

    final public void close() throws java.sql.SQLException {

        long stime = System.currentTimeMillis();
        object.close();
        this.inner.close();
        long etime = System.currentTimeMillis();

        TraceContext ctx = TraceContextManager.getContext();
        if (ctx == null)
            return;

        MethodStep p = new MethodStep();
        p.hash = HASH_CLOSE;
        p.start_time = (int) (stime - ctx.startTime);
        if (ctx.profile_thread_cputime) {
            p.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu);
        }
        p.elapsed = (int) (etime - stime);
        ctx.profile.add(p);
    }

    final public boolean isReadOnly() throws java.sql.SQLException {
        return this.inner.isReadOnly();
    }

    final public java.sql.Statement createStatement() throws java.sql.SQLException {
        return this.inner.createStatement();
    }

    final public java.sql.Statement createStatement(int a0, int a1) throws java.sql.SQLException {
        return this.inner.createStatement(a0, a1);
    }

    final public java.sql.Statement createStatement(int a0, int a1, int a2) throws java.sql.SQLException {
        return this.inner.createStatement(a0, a1, a2);
    }

    final public java.sql.PreparedStatement prepareStatement(java.lang.String a0, int a1) throws java.sql.SQLException {
        return this.inner.prepareStatement(a0, a1);
    }

    final public java.sql.PreparedStatement prepareStatement(java.lang.String a0, int a1, int a2)
            throws java.sql.SQLException {
        return this.inner.prepareStatement(a0, a1, a2);
    }

    final public java.sql.PreparedStatement prepareStatement(java.lang.String a0, int a1, int a2, int a3)
            throws java.sql.SQLException {
        return this.inner.prepareStatement(a0, a1, a2, a3);
    }

    final public java.sql.PreparedStatement prepareStatement(java.lang.String a0, int[] a1)
            throws java.sql.SQLException {
        return this.inner.prepareStatement(a0, a1);
    }

    final public java.sql.PreparedStatement prepareStatement(java.lang.String a0, java.lang.String[] a1)
            throws java.sql.SQLException {
        return this.inner.prepareStatement(a0, a1);
    }

    final public java.sql.PreparedStatement prepareStatement(java.lang.String a0) throws java.sql.SQLException {
        return inner.prepareStatement(a0);
    }

    final public java.sql.CallableStatement prepareCall(java.lang.String a0) throws java.sql.SQLException {
        return this.inner.prepareCall(a0);
    }

    final public java.sql.CallableStatement prepareCall(java.lang.String a0, int a1, int a2)
            throws java.sql.SQLException {
        return this.inner.prepareCall(a0, a1, a2);
    }

    final public java.sql.CallableStatement prepareCall(java.lang.String a0, int a1, int a2, int a3)
            throws java.sql.SQLException {
        return this.inner.prepareCall(a0, a1, a2, a3);
    }

    final public java.lang.String nativeSQL(java.lang.String a0) throws java.sql.SQLException {
        return this.inner.nativeSQL(a0);
    }

    final public void setAutoCommit(boolean a0) throws java.sql.SQLException {
        this.inner.setAutoCommit(a0);

        TraceContext ctx = TraceContextManager.getContext();
        if (ctx == null)
            return;

        MethodStep p = new MethodStep();
        p.hash = a0 ? HASH_AUTO_COMMIT_TRUE : HASH_AUTO_COMMIT_FALSE;
        p.start_time = (int) (System.currentTimeMillis() - ctx.startTime);
        if (ctx.profile_thread_cputime) {
            p.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu);
        }

        ctx.profile.add(p);
    }

    final public boolean getAutoCommit() throws java.sql.SQLException {
        return this.inner.getAutoCommit();
    }

    final public void commit() throws java.sql.SQLException {
        long stime = System.currentTimeMillis();
        this.inner.commit();
        long etime = System.currentTimeMillis();

        TraceContext ctx = TraceContextManager.getContext();
        if (ctx == null)
            return;

        MethodStep p = new MethodStep();
        p.hash = HASH_COMMIT;
        p.start_time = (int) (stime - ctx.startTime);
        if (ctx.profile_thread_cputime) {
            p.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu);
        }
        p.elapsed = (int) (etime - stime);
        ctx.profile.add(p);
    }

    final public void rollback(java.sql.Savepoint a0) throws java.sql.SQLException {
        this.inner.rollback(a0);
    }

    final public void rollback() throws java.sql.SQLException {
        this.inner.rollback();
    }

    final public boolean isClosed() throws java.sql.SQLException {
        return this.inner.isClosed();
    }

    final public java.sql.DatabaseMetaData getMetaData() throws java.sql.SQLException {
        return this.inner.getMetaData();
    }

    final public void setCatalog(java.lang.String a0) throws java.sql.SQLException {
        this.inner.setCatalog(a0);
    }

    final public java.lang.String getCatalog() throws java.sql.SQLException {
        return this.inner.getCatalog();
    }

    final public void setTransactionIsolation(int a0) throws java.sql.SQLException {
        this.inner.setTransactionIsolation(a0);
    }

    final public int getTransactionIsolation() throws java.sql.SQLException {
        return this.inner.getTransactionIsolation();
    }

    final public java.sql.SQLWarning getWarnings() throws java.sql.SQLException {
        return this.inner.getWarnings();
    }

    final public void clearWarnings() throws java.sql.SQLException {
        this.inner.clearWarnings();
    }

    final public java.util.Map getTypeMap() throws java.sql.SQLException {
        return this.inner.getTypeMap();
    }

    public  T unwrap(Class a0) throws SQLException {
        return this.inner.unwrap(a0);
    }

    public boolean isWrapperFor(Class a0) throws SQLException {
        return this.inner.isWrapperFor(a0);
    }

    public void setTypeMap(Map> a0) throws SQLException {
        this.inner.setTypeMap(a0);
    }

    final public void setHoldability(int a0) throws java.sql.SQLException {
        this.inner.setHoldability(a0);
    }

    final public int getHoldability() throws java.sql.SQLException {
        return this.inner.getHoldability();
    }

    final public java.sql.Savepoint setSavepoint() throws java.sql.SQLException {
        return this.inner.setSavepoint();
    }

    final public java.sql.Savepoint setSavepoint(java.lang.String a0) throws java.sql.SQLException {
        return this.inner.setSavepoint(a0);
    }

    final public void releaseSavepoint(java.sql.Savepoint a0) throws java.sql.SQLException {
        this.inner.releaseSavepoint(a0);
    }

    final public java.sql.Clob createClob() throws java.sql.SQLException {
        return this.inner.createClob();
    }

    final public java.sql.Blob createBlob() throws java.sql.SQLException {
        return this.inner.createBlob();
    }

    final public java.sql.NClob createNClob() throws java.sql.SQLException {
        return this.inner.createNClob();
    }

    final public java.sql.SQLXML createSQLXML() throws java.sql.SQLException {
        return this.inner.createSQLXML();
    }

    final public boolean isValid(int a0) throws java.sql.SQLException {
        return this.inner.isValid(a0);
    }

    final public void setClientInfo(java.util.Properties a0) throws java.sql.SQLClientInfoException {
        this.inner.setClientInfo(a0);
    }

    final public void setClientInfo(java.lang.String a0, java.lang.String a1) throws java.sql.SQLClientInfoException {
        this.inner.setClientInfo(a0, a1);
    }

    final public java.util.Properties getClientInfo() throws java.sql.SQLException {
        return this.inner.getClientInfo();
    }

    final public java.lang.String getClientInfo(java.lang.String a0) throws java.sql.SQLException {
        return this.inner.getClientInfo(a0);
    }

    final public java.sql.Array createArrayOf(java.lang.String a0, java.lang.Object[] a1) throws java.sql.SQLException {
        return this.inner.createArrayOf(a0, a1);
    }

    final public java.sql.Struct createStruct(java.lang.String a0, java.lang.Object[] a1) throws java.sql.SQLException {
        return this.inner.createStruct(a0, a1);
    }

    public void setSchema(String schema) throws SQLException {
        // TODO Auto-generated method stub

    }

    public String getSchema() throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }

    public void abort(Executor executor) throws SQLException {
        // TODO Auto-generated method stub

    }

    public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
        // TODO Auto-generated method stub

    }

    public int getNetworkTimeout() throws SQLException {
        // TODO Auto-generated method stub
        return 0;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy