001 /*
002 * $Id: SqlStatistic.java,v 1.7 2014/05/17 17:31:34 oboehm Exp $
003 *
004 * Copyright (c) 2014 by Oliver Boehm
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 *
018 * (c)reated 16.04.2014 by oliver (ob@oasd.de)
019 */
020
021 package patterntesting.runtime.monitor.db;
022
023 import java.util.regex.Pattern;
024
025 import org.slf4j.*;
026
027 import patterntesting.runtime.monitor.*;
028 import patterntesting.runtime.monitor.db.internal.*;
029 import patterntesting.runtime.util.*;
030
031 /**
032 * This class monitors and measures SQL statements. To be able to distinguish
033 * them from methods profiling it is a separate class derived from
034 * {@link ProfileStatistic}.
035 *
036 * @author oliver
037 * @since 1.4.2 (16.04.2014)
038 */
039 public class SqlStatistic extends ProfileStatistic implements SqlStatisticMBean {
040
041 private static final Logger log = LoggerFactory.getLogger(SqlStatistic.class);
042 private static final SqlStatistic sqlInstance;
043
044 /**
045 * rootMonitor *must* be initialized before isJamonAvailable() is called.
046 * Otherwise you'll get a NullPointerException because in
047 * JamonAvailable() rootMonitor will be accessed (so rootMonitor must
048 * be initialized before!)
049 */
050 static {
051 sqlInstance = new SqlStatistic();
052 }
053
054 /**
055 * Gets the single instance of SqlStatistic.
056 *
057 * @return single instance of SqlStatistic
058 */
059 public static SqlStatistic getInstance() {
060 return sqlInstance;
061 }
062
063 private SqlStatistic() {
064 super("SQL");
065 }
066
067 /**
068 * To start a new statistic call this method. In contradiction to
069 * {@link ProfileStatistic#reset()} old {@link ProfileMonitor}s will be not
070 * kept.
071 */
072 public void reset() {
073 synchronized(SqlStatistic.class) {
074 this.resetRootMonitor();
075 }
076 }
077
078 /**
079 * Start.
080 *
081 * @param sql the sql
082 * @return the started profile monitor
083 */
084 public static ProfileMonitor start(final String sql) {
085 return sqlInstance.startProfileMonitorFor(sql);
086 }
087
088 /**
089 * Stops the given 'mon' and logs the given command with the needed time if
090 * debug is enabled.
091 *
092 * @param mon the mon
093 * @param command the command
094 */
095 public static void stop(final ProfileMonitor mon, final String command) {
096 stop(mon, command, Void.TYPE);
097 }
098
099 /**
100 * Stops the given 'mon' and logs the given command with the needed time if
101 * debug is enabled.
102 *
103 * @param mon the mon
104 * @param command the command
105 * @param returnValue the return value
106 */
107 public static void stop(final ProfileMonitor mon, final String command, final Object returnValue) {
108 mon.stop();
109 if (log.isDebugEnabled()) {
110 String msg = '"' + command + "\" returned with " + Converter.toShortString(returnValue)
111 + " after " + mon.getLastTime();
112 if (log.isTraceEnabled()) {
113 StackTraceElement[] stacktrace = StackTraceScanner.getCallerStackTrace(
114 new Pattern[0], SqlStatistic.class, StasiStatement.class,
115 StasiPreparedStatement.class);
116 log.trace("{}\n\t{}", msg, Converter.toLongString(stacktrace).trim());
117 } else {
118 log.debug("{}.", msg);
119 }
120 }
121 }
122
123 /**
124 * You can register the instance as shutdown hook. If the VM is
125 * terminated the profile values are logged and dumped to a CSV file in the
126 * tmp directory.
127 *
128 * @see #logStatistic()
129 * @see #dumpStatistic()
130 */
131 public static void addAsShutdownHook() {
132 addAsShutdownHook(sqlInstance);
133 }
134
135 }