Package com.alibaba.druid.stat

Source Code of com.alibaba.druid.stat.JdbcSqlStat

/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* 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 com.alibaba.druid.stat;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

import javax.management.JMException;
import javax.management.openmbean.ArrayType;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.SimpleType;

import com.alibaba.druid.proxy.jdbc.StatementExecuteType;
import com.alibaba.druid.util.Histogram;
import com.alibaba.druid.util.IOUtils;
import com.alibaba.druid.util.JMXUtils;

/**
* @author wenshao<szujobs@hotmail.com>
*/
public final class JdbcSqlStat implements JdbcSqlStatMBean {

    private final String     sql;
    private long             id;
    private String           dataSource;
    private long             executeLastStartTime;

    private final AtomicLong executeBatchSizeTotal = new AtomicLong();
    private final AtomicLong executeBatchSizeMax   = new AtomicLong();

    private final AtomicLong executeSuccessCount   = new AtomicLong();
    private final AtomicLong executeSpanNanoTotal  = new AtomicLong();
    private final AtomicLong executeSpanNanoMax    = new AtomicLong();
    private final AtomicLong runningCount          = new AtomicLong(0L);
    private final AtomicLong concurrentMax         = new AtomicLong();
    private final AtomicLong resultSetHoldTimeNano = new AtomicLong();
    private final  AtomicLong executeAndResultSetHoldTime = new AtomicLong();
   
    private String           name;
    private String           file;
    private String           dbType;

    private long             executeNanoSpanMaxOccurTime;

    private final AtomicLong executeErrorCount     = new AtomicLong();
    private Throwable        executeErrorLast;
    private long             executeErrorLastTime;

    private final AtomicLong updateCount           = new AtomicLong();
    private final AtomicLong fetchRowCount         = new AtomicLong();

    private final AtomicLong inTransactionCount    = new AtomicLong();

   
    private String           lastSlowParameters;

    private final Histogram  histogram             = new Histogram(new long[] { //
                                                                                //
            1, 10, 100, 1000, 10 * 1000, //
            100 * 1000, 1000 * 1000
                                                                   //
                                                                   });
   
    private final Histogram  executeAndResultHoldTimeHistogram             = new Histogram(new long[] { //
            //
        1, 10, 100, 1000, 10 * 1000, //
        100 * 1000, 1000 * 1000
//
    });

   
    private final Histogram  fetchRowCountHistogram             = new Histogram(new long[] { //
            1, 10, 100, 1000, 10 * 1000
    });

   
    private final Histogram  updateCountHistogram             = new Histogram(new long[] { //
            1, 10, 100, 1000, 10 * 1000
    });
   
   
   
    public JdbcSqlStat(String sql){
        this.sql = sql;
    }

    public String getLastSlowParameters() {
        return lastSlowParameters;
    }

    public void setLastSlowParameters(String lastSlowParameters) {
        this.lastSlowParameters = lastSlowParameters;
    }

    public String getDbType() {
        return dbType;
    }

    public void setDbType(String dbType) {
        this.dbType = dbType;
    }

    public String getDataSource() {
        return dataSource;
    }

    public void setDataSource(String dataSource) {
        this.dataSource = dataSource;
    }

    @Deprecated
    public final static String getContextSqlName() {
        JdbcStatContext context = JdbcStatManager.getInstance().getStatContext();
        if (context == null) {
            return null;
        }
        return context.getName();
    }

    @Deprecated
    public final static void setContextSqlName(String val) {
        JdbcStatContext context = JdbcStatManager.getInstance().getStatContext();
        if (context == null) {
            context = JdbcStatManager.getInstance().createStatContext();
            JdbcStatManager.getInstance().setStatContext(context);
        }

        context.setName(val);
    }

    @Deprecated
    public final static String getContextSqlFile() {
        JdbcStatContext context = JdbcStatManager.getInstance().getStatContext();
        if (context == null) {
            return null;
        }
        return context.getFile();
    }

    @Deprecated
    public final static void setContextSqlFile(String val) {
        JdbcStatContext context = JdbcStatManager.getInstance().getStatContext();
        if (context == null) {
            context = JdbcStatManager.getInstance().createStatContext();
            JdbcStatManager.getInstance().setStatContext(context);
        }

        context.setFile(val);
    }
   
    public final static void setContextSql(String val) {
        JdbcStatContext context = JdbcStatManager.getInstance().getStatContext();
        if (context == null) {
            context = JdbcStatManager.getInstance().createStatContext();
            JdbcStatManager.getInstance().setStatContext(context);
        }

        context.setSql(val);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getFile() {
        return file;
    }

    public void setFile(String file) {
        this.file = file;
    }

    public void reset() {
        executeLastStartTime = 0;

        executeBatchSizeTotal.set(0);
        executeBatchSizeMax.set(0);

        executeSuccessCount.set(0);
        executeSpanNanoTotal.set(0);
        executeSpanNanoMax.set(0);
        executeNanoSpanMaxOccurTime = 0;
        runningCount.set(0);
        concurrentMax.set(0);

        executeErrorCount.set(0);
        executeErrorLast = null;
        executeErrorLastTime = 0;

        updateCount.set(0);
        fetchRowCount.set(0);

        histogram.reset();
        this.lastSlowParameters = null;
        inTransactionCount.set(0);
        resultSetHoldTimeNano.set(0);
        executeAndResultSetHoldTime.set(0);
        fetchRowCountHistogram.reset();
        updateCountHistogram.reset();
        executeAndResultHoldTimeHistogram.reset();
    }

    public long getConcurrentMax() {
        return concurrentMax.get();
    }

    public long getRunningCount() {
        return runningCount.get();
    }

    public void addUpdateCount(int delta) {
        if (delta > 0) {
            this.updateCount.addAndGet(delta);
        }
       
        this.updateCountHistogram.recode(delta);
        this.fetchRowCountHistogram.recode(0);
       
    }

    public long getUpdateCount() {
        return updateCount.get();
    }

    public long getFetchRowCount() {
        return fetchRowCount.get();
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getSql() {
        return sql;
    }

    public Date getExecuteLastStartTime() {
        if (executeLastStartTime <= 0) {
            return null;
        }

        return new Date(executeLastStartTime);
    }

    public void setExecuteLastStartTime(long executeLastStartTime) {
        this.executeLastStartTime = executeLastStartTime;
    }

    public Date getExecuteNanoSpanMaxOccurTime() {
        if (executeNanoSpanMaxOccurTime <= 0) {
            return null;
        }
        return new Date(executeNanoSpanMaxOccurTime);
    }

    public Date getExecuteErrorLastTime() {
        if (executeErrorLastTime <= 0) {
            return null;
        }
        return new Date(executeErrorLastTime);
    }

    public void addFetchRowCount(long delta) {
        this.fetchRowCount.addAndGet(delta);
        this.fetchRowCountHistogram.recode(delta);
       
    }

    public void addExecuteBatchCount(long batchSize) {
        executeBatchSizeTotal.addAndGet(batchSize);

        // executeBatchSizeMax
        for (;;) {
            long current = executeBatchSizeMax.get();
            if (current < batchSize) {
                if (executeBatchSizeMax.compareAndSet(current, batchSize)) {
                    break;
                } else {
                    continue;
                }
            } else {
                break;
            }
        }
    }

    public long getExecuteBatchSizeTotal() {
        return executeBatchSizeTotal.get();
    }

    public void incrementExecuteSuccessCount() {
        executeSuccessCount.incrementAndGet();
    }

    public void incrementRunningCount() {
        long val = runningCount.incrementAndGet();

        for (;;) {
            long max = concurrentMax.get();
            if (val > max) {
                if (concurrentMax.compareAndSet(max, val)) {
                    break;
                } else {
                    continue;
                }
            } else {
                break;
            }
        }
    }
   
    public void decrementRunningCount() {
        runningCount.decrementAndGet();
    }

    public void decrementExecutingCount() {
        runningCount.decrementAndGet();
    }

    public long getExecuteSuccessCount() {
        return executeSuccessCount.get();
    }
   
    public void addExecuteTime(StatementExecuteType executeType, long nanoSpan) {
      if (StatementExecuteType.ExecuteQuery != executeType) {
        executeAndResultHoldTimeHistogram.recode((nanoSpan)/1000/1000);
      }
      addExecuteTime(nanoSpan);
    }

    public void addExecuteTime(long nanoSpan) {
        executeSpanNanoTotal.addAndGet(nanoSpan);

        for (;;) {
            long current = executeSpanNanoMax.get();
            if (current < nanoSpan) {
                if (executeSpanNanoMax.compareAndSet(current, nanoSpan)) {
                    // 可能不准确,但是绝大多数情况下都会正确,性能换取一致性
                    executeNanoSpanMaxOccurTime = System.currentTimeMillis();

                    break;
                } else {
                    continue;
                }
            } else {
                break;
            }
        }

        long millis = nanoSpan / (1000 * 1000);
        histogram.recode(millis);
    }

    public long getExecuteMillisTotal() {
        return executeSpanNanoTotal.get() / (1000 * 1000);
    }

    public long getExecuteMillisMax() {
        return executeSpanNanoMax.get() / (1000 * 1000);
    }

    public long getErrorCount() {
        return executeErrorCount.get();
    }

    @Override
    public long getExecuteBatchSizeMax() {
        return executeBatchSizeMax.get();
    }

    public long getInTransactionCount() {
        return inTransactionCount.get();
    }

    public void incrementInTransactionCount() {
        inTransactionCount.incrementAndGet();
    }

    private static CompositeType COMPOSITE_TYPE = null;

    public static CompositeType getCompositeType() throws JMException {

        if (COMPOSITE_TYPE != null) {
            return COMPOSITE_TYPE;
        }

        OpenType<?>[] indexTypes = new OpenType<?>[] {
                // 0 - 4
                SimpleType.LONG, //
                SimpleType.STRING, //
                SimpleType.STRING, //
                SimpleType.LONG, //
                SimpleType.LONG, //

                // 5 - 9
                SimpleType.LONG, //
                SimpleType.DATE, //
                SimpleType.LONG, //
                JMXUtils.getThrowableCompositeType(), //
                SimpleType.LONG, //
                //

                // 10 - 14
                SimpleType.LONG, //
                SimpleType.DATE, //
                SimpleType.LONG, //
                SimpleType.LONG, //
                SimpleType.LONG, //
                //

                // 15 - 19
                SimpleType.LONG, //
                SimpleType.STRING, //
                SimpleType.STRING, //
                SimpleType.STRING, //
                SimpleType.STRING, //
                //

                // 20 - 24
                SimpleType.STRING, //
                SimpleType.DATE, //
                SimpleType.STRING, //
                SimpleType.LONG, //
                SimpleType.STRING, //

                // 25 - 29
                new ArrayType<Long>(SimpleType.LONG, true), //
                SimpleType.STRING, //
                SimpleType.LONG, //
                SimpleType.LONG, //
                new ArrayType<Long>(SimpleType.LONG, true), //
               
                // 30 -
               
                new ArrayType<Long>(SimpleType.LONG, true), //
                new ArrayType<Long>(SimpleType.LONG, true), //
               
        };

        String[] indexNames = {
                // 0 - 4
                "ID", //
                "DataSource", //
                "SQL", //
                "ExecuteCount", //
                "ErrorCount", //

                // 5 - 9
                "TotalTime", //
                "LastTime", //
                "MaxTimespan", //
                "LastError", //
                "EffectedRowCount", //

                // 10 - 14
                "FetchRowCount", //
                "MaxTimespanOccurTime", //
                "BatchSizeMax", //
                "BatchSizeTotal", //
                "ConcurrentMax", //

                // 15 - 19
                "RunningCount", //
                "Name", //
                "File", //
                "LastErrorMessage", //
                "LastErrorClass", //

                // 20 - 24
                "LastErrorStackTrace", //
                "LastErrorTime", //
                "DbType", //
                "InTransactionCount", //
                "URL", //

                // 25 - 29
                "Histogram", //
                "LastSlowParameters",
                "ResultSetHoldTime",
                "ExecuteAndResultSetHoldTime",
                "FetchRowCountHistogram",
               
                // 30
                "EffectedRowCountHistogram",
                "ExecuteAndResultHoldTimeHistogram"
               
               
               
        //
        };
        String[] indexDescriptions = indexNames;
        COMPOSITE_TYPE = new CompositeType("SqlStatistic", "Sql Statistic", indexNames, indexDescriptions, indexTypes);

        return COMPOSITE_TYPE;
    }

    public long getExecuteCount() {
        return getErrorCount() + getExecuteSuccessCount();
    }

    public Map<String, Object> getData() throws JMException {
        Map<String, Object> map = new HashMap<String, Object>();

        // 0 - 4
        map.put("ID", id);
        map.put("DataSource", dataSource);
        map.put("SQL", sql);
        map.put("ExecuteCount", getExecuteCount());
        map.put("ErrorCount", getErrorCount());

        // 5 - 9
        map.put("TotalTime", getExecuteMillisTotal());
        map.put("LastTime", getExecuteLastStartTime());
        map.put("MaxTimespan", getExecuteMillisMax());
        map.put("LastError", JMXUtils.getErrorCompositeData(this.getExecuteErrorLast()));
        map.put("EffectedRowCount", getUpdateCount());

        // 10 - 14
        map.put("FetchRowCount", getFetchRowCount());
        map.put("MaxTimespanOccurTime", getExecuteNanoSpanMaxOccurTime());
        map.put("BatchSizeMax", getExecuteBatchSizeMax());
        map.put("BatchSizeTotal", getExecuteBatchSizeTotal());
        map.put("ConcurrentMax", getConcurrentMax());

        // 15 -
        map.put("RunningCount", getRunningCount()); // 15
        map.put("Name", getName()); // 16
        map.put("File", getFile()); // 17

        Throwable lastError = this.executeErrorLast;
        if (lastError != null) {
            map.put("LastErrorMessage", lastError.getMessage()); // 18
            map.put("LastErrorClass", lastError.getClass().getName()); // 19

            map.put("LastErrorStackTrace", IOUtils.getStackTrace(lastError)); // 20
            map.put("LastErrorTime", new Date(executeErrorLastTime)); // 21
        } else {
            map.put("LastErrorMessage", null);
            map.put("LastErrorClass", null);
            map.put("LastErrorStackTrace", null);
            map.put("LastErrorTime", null);
        }

        map.put("DbType", dbType); // 22
        map.put("URL", null); // 23
        map.put("InTransactionCount", getInTransactionCount()); // 24

        map.put("Histogram", this.histogram.toArray()); // 25
        map.put("LastSlowParameters", lastSlowParameters); // 26
        map.put("ResultSetHoldTime", getResultSetHoldTimeMilis()); // 27
        map.put("ExecuteAndResultSetHoldTime", this.getExecuteAndResultSetHoldTimeMilis()); // 28
        map.put("FetchRowCountHistogram", this.getFetchRowCountHistogram().toArray()); // 29
       
       
        map.put("EffectedRowCountHistogram", this.getUpdateCountHistogram().toArray()); // 30
        map.put("ExecuteAndResultHoldTimeHistogram", this.getExecuteAndResultHoldTimeHistogram().toArray()); // 30
      

        return map;
    }

    public CompositeDataSupport getCompositeData() throws JMException {
        return new CompositeDataSupport(getCompositeType(), getData());
    }

    public Throwable getExecuteErrorLast() {
        return executeErrorLast;
    }

    public void error(Throwable error) {
        executeErrorCount.incrementAndGet();
        executeErrorLastTime = System.currentTimeMillis();
        executeErrorLast = error;

    }

    public long getResultSetHoldTimeMilis() {
        return getResultSetHoldTimeNano() / (1000 * 1000);
    }
   
    public long getExecuteAndResultSetHoldTimeMilis() {
        return getExecuteAndResultSetHoldTimeNano() / (1000 * 1000);
    }
   
   
    public Histogram getFetchRowCountHistogram() {
        return this.fetchRowCountHistogram;
    }
   
    public Histogram getUpdateCountHistogram() {
        return this.updateCountHistogram;
    }
   
    public Histogram getExecuteAndResultHoldTimeHistogram() {
        return this.executeAndResultHoldTimeHistogram;
    }
   
   
    public long getResultSetHoldTimeNano() {
        return resultSetHoldTimeNano.get();
    }

    public long getExecuteAndResultSetHoldTimeNano() {
        return executeAndResultSetHoldTime.get();
    }
   
    public void addResultSetHoldTimeNano(long nano) {
        resultSetHoldTimeNano.addAndGet(nano);
    }

    public void addResultSetHoldTimeNano(long statementExecuteNano, long resultHoldTimeNano) {
      resultSetHoldTimeNano.addAndGet(resultHoldTimeNano);     
      executeAndResultSetHoldTime.addAndGet(statementExecuteNano+resultHoldTimeNano);
      executeAndResultHoldTimeHistogram.recode((statementExecuteNano+resultHoldTimeNano)/1000/1000);
      updateCountHistogram.recode(0);
    }
}
TOP

Related Classes of com.alibaba.druid.stat.JdbcSqlStat

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.