Merge remote-tracking branch 'upstream/master'

This commit is contained in:
xiaoyu830411
2012-08-27 16:49:37 +08:00
13 changed files with 232 additions and 77 deletions
@@ -113,13 +113,13 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
private final CountDownLatch initedLatch = new CountDownLatch(2);
private boolean enable = true;
private volatile boolean enable = true;
private boolean resetStatEnable = true;
private String initStackTrace;
private boolean closed = false;
private volatile boolean closed = false;
private long closeTimeMillis = -1L;
private JdbcDataSourceStat dataSourceStat;
@@ -320,11 +320,14 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
throw new SQLException("interrupt", e);
}
boolean init = false;
try {
if (inited) {
return;
}
init = true;
initStackTrace = IOUtils.toString(Thread.currentThread().getStackTrace());
this.id = DruidDriver.createDataSourceId();
@@ -343,10 +346,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
throw new IllegalArgumentException("illegal maxActive " + maxActive);
}
if (maxIdle <= 0 || maxIdle < minIdle) {
throw new IllegalArgumentException("illegal maxPoolSize");
}
if (getInitialSize() > maxActive) {
throw new IllegalArgumentException("illegal initialSize " + this.initialSize + ", maxActieve "
+ maxActive);
@@ -437,7 +436,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
inited = true;
lock.unlock();
if (LOG.isInfoEnabled()) {
if (init && LOG.isInfoEnabled()) {
LOG.info("{dataSource-" + this.getID() + "} inited");
}
}
@@ -669,8 +668,20 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
private DruidPooledConnection getConnectionInternal(long maxWait) throws SQLException {
DruidPooledConnection poolalbeConnection;
if (closed) {
connectErrorCount.incrementAndGet();
throw new DataSourceClosedException("dataSource already closed at " + new Date(closeTimeMillis));
}
if (!enable) {
connectErrorCount.incrementAndGet();
throw new DataSourceDisableException();
}
final long nanos = TimeUnit.MILLISECONDS.toNanos(maxWait);
final int maxWaitThreadCount = getMaxWaitThreadCount();
DruidConnectionHolder holder;
try {
lock.lockInterruptibly();
} catch (InterruptedException e) {
@@ -679,17 +690,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
try {
if (closed) {
connectErrorCount.incrementAndGet();
throw new DataSourceClosedException("dataSource already closed at " + new Date(closeTimeMillis));
}
if (!enable) {
connectErrorCount.incrementAndGet();
throw new DataSourceDisableException();
}
final int maxWaitThreadCount = getMaxWaitThreadCount();
if (maxWaitThreadCount > 0) {
if (notEmptyWaitThreadCount >= maxWaitThreadCount) {
connectErrorCount.incrementAndGet();
@@ -700,26 +700,18 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
connectCount++;
DruidConnectionHolder holder;
if (maxWait > 0) {
holder = pollLast(maxWait, TimeUnit.MILLISECONDS);
holder = pollLast(nanos);
} else {
holder = takeLast();
}
if (holder == null) {
throw new SQLException("can not get connection");
}
holder.incrementUseCount();
activeCount++;
if (activeCount > activePeak) {
activePeak = activeCount;
activePeakTime = System.currentTimeMillis();
}
poolalbeConnection = new DruidPooledConnection(holder);
} catch (InterruptedException e) {
connectErrorCount.incrementAndGet();
throw new SQLException(e.getMessage(), e);
@@ -729,6 +721,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} finally {
lock.unlock();
}
holder.incrementUseCount();
DruidPooledConnection poolalbeConnection = new DruidPooledConnection(holder);
return poolalbeConnection;
}
@@ -815,12 +811,18 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
}
if (!enable) {
discardConnection(holder.getConnection());
return;
}
final long lastActiveTimeMillis = System.currentTimeMillis();
lock.lockInterruptibly();
try {
activeCount--;
closeCount++;
putLast(holder);
putLast(holder, lastActiveTimeMillis);
recycleCount++;
} finally {
lock.unlock();
@@ -918,18 +920,13 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
}
void putLast(DruidConnectionHolder e) throws SQLException {
if (!enable) {
discardConnection(e.getConnection());
return;
}
e.setLastActiveTimeMillis(System.currentTimeMillis());
void putLast(DruidConnectionHolder e, long lastActiveTimeMillis) throws SQLException {
e.setLastActiveTimeMillis(lastActiveTimeMillis);
connections[poolingCount++] = e;
if (poolingCount > poolingPeak) {
poolingPeak = poolingCount;
poolingPeakTime = System.currentTimeMillis();
poolingPeakTime = lastActiveTimeMillis;
}
notEmpty.signal();
@@ -950,7 +947,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
notEmptyWaitThreadCount--;
}
notEmptyWaitCount++;
if (!enable) {
connectErrorCount.incrementAndGet();
throw new DataSourceDisableException();
@@ -969,8 +966,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
return last;
}
DruidConnectionHolder pollLast(long timeout, TimeUnit unit) throws InterruptedException, SQLException {
final long nanos = unit.toNanos(timeout);
DruidConnectionHolder pollLast(long nanos) throws InterruptedException, SQLException {
long estimate = nanos;
for (int i = 0;; ++i) {
@@ -993,7 +989,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
// creator
notEmptyWaitCount++;
notEmptyWaitNanos += (startEstimate - estimate);
if (!enable) {
connectErrorCount.incrementAndGet();
throw new DataSourceDisableException();
@@ -1540,7 +1536,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
buf.append(entry.getKey().getSql());
buf.append("\"");
buf.append("\t}");
entryIndex++;
}
} catch (ConcurrentModificationException e) {
@@ -15,10 +15,11 @@
*/
package com.alibaba.druid.stat;
import com.alibaba.druid.pool.DruidDataSource;
import java.lang.management.ManagementFactory;
import java.sql.Driver;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
@@ -27,6 +28,7 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import com.alibaba.druid.VERSION;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.stat.WebAppStatManager;
import com.alibaba.druid.support.spring.stat.SpringStatManager;
import com.alibaba.druid.util.DruidDataSourceUtils;
@@ -188,6 +190,10 @@ public class DruidStatManagerFacade {
dataMap.put("Drivers", getDriversData());
dataMap.put("ResetEnable", isResetEnable());
dataMap.put("ResetCount", getResetCount());
dataMap.put("JavaVMName", System.getProperty("java.vm.name"));
dataMap.put("JavaVersion", System.getProperty("java.version"));
dataMap.put("JavaClassPath", System.getProperty("java.class.path"));
dataMap.put("StartTime", new Date(ManagementFactory.getRuntimeMXBean().getStartTime()));
return dataMap;
}
@@ -25,6 +25,7 @@ public class Option {
private PrintStyle style = PrintStyle.HORIZONTAL;
private int printDataType = 0;
private int vmid = -1;
private int id = -1;
public void addPrintDataType(int newValue) {
this.printDataType= this.printDataType | newValue;
@@ -33,7 +34,7 @@ public class Option {
public static boolean isPrintHelp(String[] args) {
if (args == null ) return true;
for (String arg: args) {
if (arg.equals("-h") || arg.equals("--help")) {
if (arg.equals("-help") ) {
return true;
}
}
@@ -112,6 +113,13 @@ public class Option {
option.setStyle(PrintStyle.HORIZONTAL);
} else if (args[i].equals("-s2")) {
option.setStyle(PrintStyle.VERTICAL);
} else if (args[i].equals("-id")) {
try {
int id = Integer.parseInt(args[i+1]);
option.setId(id);
} catch (NumberFormatException e) {
throw new OptionParseException("vmid argument is not a integer!");
}
}
i++;
}
@@ -122,7 +130,7 @@ public class Option {
}
public static void printHelp() {
System.out.println("Usage: druidStat -help | -sql -ds -act -s1 -s2 vmid");
System.out.println("Usage: druidStat -help | -sql -ds -act -s1 -s2 -id vmid");
System.out.println();
System.out.println("arguments: ");
System.out.println(" vmid the process id of jvm that running druid");
@@ -131,8 +139,17 @@ public class Option {
System.out.println(" -act print active connection stacktrace data");
System.out.println(" -s1 print field name in first row");
System.out.println(" -s2 print field name in first column");
System.out.println(" -id only print the sql data matched with id, use this with -sql argument" );
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
@@ -19,11 +19,26 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.alibaba.druid.sql.SQLUtils;
public class TabledDataPrinter {
private static final int SQL_MAX_LEN = 32;
private static final String[] sqlFields = new String[] {
private static final int MAX_COL = 4;
private static final String[] sqlRowTitle = new String[] {
"ID", "SQL", "ExecCount", "ExecTime",
"ExecMax","Txn", "Error","Update","FetchRow","Running","Concurrent",
"ExecHisto", "ExecRsHisto","FetchRowHisto","UpdateHisto" };
private static final String[] sqlRowField = new String[] {
"ID", "SQL", "ExecuteCount", "TotalTime", "MaxTimespan",
"InTransactionCount", "ErrorCount", "EffectedRowCount", "FetchRowCount",
"RunningCount","ConcurrentMax","Histogram","ExecuteAndResultHoldTimeHistogram",
"FetchRowCountHistogram","EffectedRowCountHistogram" };
private static final String[] sqlColField = new String[] {
"ID", "DataSource", "SQL", "ExecuteCount", "ErrorCount",
"TotalTime", "LastTime", "MaxTimespan", "LastError", "EffectedRowCount",
"FetchRowCount", "MaxTimespanOccurTime", "BatchSizeMax", "BatchSizeTotal", "ConcurrentMax",
@@ -33,7 +48,21 @@ public class TabledDataPrinter {
"Histogram", "LastSlowParameters", "ResultSetHoldTime", "ExecuteAndResultSetHoldTime", "FetchRowCountHistogram",
"EffectedRowCountHistogram", "ExecuteAndResultHoldTimeHistogram", "EffectedRowCountMax", "FetchRowCountMax", "ClobOpenCount" };
private static final String[] dsFields = new String[] {
private static final String[] dsRowTitle = new String[] {
"Name", "DbType",
"PoolingCount", "PoolingPeak", "PoolingPeakTime",
"ActiveCount", "ActivePeak", "ActivePeakTime",
"ExecuteCount", "ErrorCount", "CommitCount", "RollbackCount" };
private static final String[] dsRowField = new String[] {
"Name", "DbType",
"PoolingCount", "PoolingPeak", "PoolingPeakTime",
"ActiveCount", "ActivePeak", "ActivePeakTime",
"ExecuteCount", "ErrorCount", "CommitCount", "RollbackCount" };
private static final String[] dsColField = new String[] {
"Identity", "Name", "DbType", "DriverClassName", "URL", "UserName", "FilterClassNames",
"WaitThreadCount", "NotEmptyWaitCount", "NotEmptyWaitMillis",
"PoolingCount", "PoolingPeak", "PoolingPeakTime",
@@ -60,29 +89,48 @@ public class TabledDataPrinter {
public static void printDataSourceData(List<Map<String, Object>> content,Option opt) {
if (opt.getStyle() == Option.PrintStyle.HORIZONTAL) {
System.out.println(getFormattedOutput(content, dsFields));
System.out.println(getFormattedOutput(content, dsRowTitle, dsRowField));
} else {
System.out.println(getVerticalFormattedOutput(content, dsFields));
System.out.println(getVerticalFormattedOutput(content, dsColField));
}
}
public static void printSqlData(List<Map<String, Object>> content, Option opt) {
if (opt.getId() != -1) {
List<Map<String,Object>> matchedContent = new ArrayList<Map<String,Object>>();
for (Map<String, Object> sqlStat : content) {
Integer idStr = (Integer)sqlStat.get("ID");
if (idStr.intValue() == opt.getId()) {
matchedContent.add(sqlStat);
String dbType = (String) sqlStat.get("DbType");
String sql = (String) sqlStat.get("SQL");
System.out.println(SQLUtils.format(sql, dbType));
System.out.println("===============================\n");
break;
}
}
content = matchedContent;
}
if (opt.getStyle() == Option.PrintStyle.HORIZONTAL) {
System.out.println(getFormattedOutput(content, sqlFields));
System.out.println(getFormattedOutput(content, sqlRowTitle, sqlRowField));
} else {
System.out.println(getVerticalFormattedOutput(content, sqlFields));
System.out.println(getVerticalFormattedOutput(content, sqlColField));
}
}
public static String getFormattedOutput(List<Map<String, Object>> content, String[] titleFields) {
public static String getFormattedOutput(List<Map<String, Object>> content,
String[] title , String[] rowField) {
List<String[]> printContents = new ArrayList<String[]>();
printContents.add(titleFields);
printContents.add(title);
for (Map<String, Object> sqlStat : content) {
String[] row = new String[titleFields.length];
for (int i = 0; i < titleFields.length; ++i) {
Object value = sqlStat.get(titleFields[i]);
row[i] = handleAndConvert(value,titleFields[i]);
String[] row = new String[rowField.length];
for (int i = 0; i < rowField.length; ++i) {
Object value = sqlStat.get(rowField[i]);
row[i] = handleAndConvert(value,rowField[i]);
}
printContents.add(row);
}
@@ -94,10 +142,12 @@ public class TabledDataPrinter {
public static String getVerticalFormattedOutput(List<Map<String, Object>> content, String[] titleFields) {
List<String[]> printContents = new ArrayList<String[]>();
int maxCol = content.size() > MAX_COL ? MAX_COL: content.size();
for (int i = 0; i < titleFields.length; ++i) {
String[] row = new String[content.size()+1];
String[] row = new String[maxCol+1];
row[0] = titleFields[i];
for (int j=0; j<content.size(); j++) {
for (int j=0; j< maxCol ; j++) {
Map<String,Object> sqlStat = content.get(j);
Object value = sqlStat.get(titleFields[i]);
row[j+1] = handleAndConvert(value, titleFields[i]);
@@ -112,6 +162,8 @@ public class TabledDataPrinter {
if (value == null) value = "";
if (fieldName.equals("SQL")) {
String sql = (String)value;
sql = sql.replace("\n", " ");
sql = sql.replace("\t", " ");
if (sql.length() > SQL_MAX_LEN) {
sql = sql.substring(0,SQL_MAX_LEN-3) + "...";
}
@@ -212,7 +212,8 @@ public class StatViewServlet extends HttpServlet {
return;
}
if (isRequireAuth() && session.getAttribute(SESSION_USER_KEY) == null
if (isRequireAuth()
&& session.getAttribute(SESSION_USER_KEY) == null
&& !("/login.html".equals(path) || path.startsWith("/css") || path.startsWith("/js") || path.startsWith("/img"))) {
if (contextPath == null || contextPath.equals("") || contextPath.equals("/")) {
response.sendRedirect("/login.html");
@@ -251,6 +252,15 @@ public class StatViewServlet extends HttpServlet {
private void returnResourceFile(String fileName, String uri, HttpServletResponse response) throws ServletException,
IOException {
if (fileName.endsWith(".jpg")) {
byte[] bytes = IOUtils.readByteArrayFromResource(RESOURCE_PATH + fileName);
if (bytes != null) {
response.getOutputStream().write(bytes);
}
return;
}
String text = IOUtils.readFromResource(RESOURCE_PATH + fileName);
if (text == null) {
response.sendRedirect(uri + "/index.html");
@@ -15,9 +15,11 @@
*/
package com.alibaba.druid.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
@@ -52,6 +54,37 @@ public class IOUtils {
JdbcUtils.close(in);
}
}
public static byte[] readByteArrayFromResource(String resource) throws IOException {
InputStream in = null;
try {
in = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
if (in == null) {
return null;
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
copy(in, output);
return output.toByteArray();
} finally {
JdbcUtils.close(in);
}
}
public static long copy(InputStream input, OutputStream output)
throws IOException {
final int EOF = -1;
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
long count = 0;
int n = 0;
while (EOF != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
public static String read(Reader reader) {
try {
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

@@ -23,7 +23,7 @@
</td>
</tr>
<tr >
<td valign="top" class="td_lable"> drivers </td>
<td valign="top" class="td_lable"> Drivers </td>
<td id="DruidDrivers"> </td>
</tr>
<tr >
@@ -34,6 +34,22 @@
<td valign="top" class="td_lable"> ResetCount </td>
<td id="ResetCount"></td>
</tr>
<tr >
<td valign="top" class="td_lable"> JavaVersion </td>
<td id="JavaVersion"></td>
</tr>
<tr >
<td valign="top" class="td_lable"> JavaVMName </td>
<td id="JavaVMName"></td>
</tr>
<tr>
<td valign="top" class="td_lable"> JavaClassPath </td>
<td id="JavaClassPath"></td>
</tr>
<tr >
<td valign="top" class="td_lable"> StartTime </td>
<td id="StartTime"></td>
</tr>
</table>
</div>
<script type="text/javascript">
@@ -62,6 +78,10 @@
}
$("#ResetEnable").text(data.Content.ResetEnable)
$("#ResetCount").text(data.Content.ResetCount)
$("#JavaVersion").text(data.Content.JavaVersion)
$("#JavaVMName").text(data.Content.JavaVMName)
$("#JavaClassPath").text(data.Content.JavaClassPath)
$("#StartTime").text(data.Content.StartTime)
},
dataType: "json"
});
@@ -17,7 +17,7 @@ druid.common = function () {
var html = '<div class="navbar navbar-fixed-top">'+
' <div class="navbar-inner">'+
' <div class="container">'+
' <a href="#" class="brand">Druid Monitor</a>'+
' <a href="https://github.com/AlibabaTech/druid/wiki" target="_blank" class="brand">Druid Monitor</a>'+
' <div class="nav-collapse">'+
' <ul class="nav">'+
' <li><a href="index.html">Index</a></li>'+
@@ -41,9 +41,10 @@ druid.common = function () {
buildFooter : function() {
var html = '<footer class="footer">'+
' <div class="container">'+
' powered by <a href="https://github.com/AlibabaTech/">AlibabaTech</a> & <a href="http://www.sandzhang.com/">sandzhang</a> & <a href="mailto:libinsong1204@gmail.com">melin</a>'+
' </div>'+
'</footer>';
' powered by <a href="https://github.com/AlibabaTech/" target="_blank">AlibabaTech</a> & <a href="http://www.sandzhang.com/" target="_blank">sandzhang</a> & <a href="http://melin.iteye.com/" target="_blank">melin</a> & <a href="https://github.com/shrekwang" target="_blank">shrek.wang</a><br/>'+
' <img src="img/logo.jpg" />'
' </div>'+
'</footer>';
$(document.body).append(html);
},
@@ -169,4 +170,4 @@ druid.common = function () {
$(document).ready(function() {
druid.common.init();
});
});
+18
View File
@@ -0,0 +1,18 @@
@echo off
rem Copyright 1999-2011 Alibaba Group Holding Ltd.
rem
rem Licensed under the Apache License, Version 2.0 (the "License");
rem you may not use this file except in compliance with the License.
rem You may obtain a copy of the License at
rem
rem http://www.apache.org/licenses/LICENSE-2.0
rem
rem Unless required by applicable law or agreed to in writing, software
rem distributed under the License is distributed on an "AS IS" BASIS,
rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rem See the License for the specific language governing permissions and
rem limitations under the License.
java -classpath "../druid.jar" com.alibaba.druid.support.console.DruidStat
@@ -45,9 +45,9 @@ public class Case1 extends TestCase {
private int maxPoolSize = 50;
private int maxActive = 50;
private String validationQuery = "SELECT 1";
private int threadCount = 2;
private int threadCount = 10;
private int loopCount = 4;
final int LOOP_COUNT = 1000 * 1000;
final int LOOP_COUNT = 1000 * 100;
protected void setUp() throws Exception {
jdbcUrl = "jdbc:fake:dragoon_v25masterdb";
@@ -56,7 +56,7 @@ public class Case1 extends TestCase {
driverClass = "com.alibaba.druid.mock.MockDriver";
}
public void test_0() throws Exception {
public void f_test_0() throws Exception {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setInitialSize(initialSize);
@@ -110,6 +110,7 @@ public class Case1 extends TestCase {
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setStatementsCacheSize(100);
dataSource.setServiceOrder("LIFO");
// dataSource.setMaxOpenPreparedStatements(100);
dataSource.setUsername(user);
dataSource.setPassword(password);
@@ -35,6 +35,13 @@ public class OptionTest extends TestCase {
Assert.assertFalse(opt.printActiveConn());
Assert.assertEquals(opt.getStyle(), Option.PrintStyle.VERTICAL);
Assert.assertEquals(opt.getVmid(), 1319);
cmdArray = new String[] {"-sql","-id","5","200"};
opt = Option.parseOptions(cmdArray);
Assert.assertNotNull(opt);
Assert.assertEquals(opt.getId(), 5);
Assert.assertEquals(opt.getVmid(), 200);
//not enough arguments
@@ -103,13 +103,7 @@ public class ParamTest extends TestCase {
Assert.assertEquals(1, dataSource.getProxyFilters().size());
error = null;
try {
dataSource.getConnection();
} catch (Exception ex) {
error = ex;
}
Assert.assertNotNull(error);
dataSource.getConnection();
dataSource.close();
}