StarViewServlet:add sort support for sql.json and sqlview page

This commit is contained in:
sand
2012-07-25 11:29:38 +08:00
parent af0ca2ebab
commit d7d0a955cb
5 changed files with 151 additions and 25 deletions
@@ -25,6 +25,7 @@ import com.alibaba.druid.stat.DruidDataSourceStatManager;
import com.alibaba.druid.stat.JdbcSqlStat;
import com.alibaba.druid.stat.JdbcStatManager;
import com.alibaba.druid.util.IOUtils;
import com.alibaba.druid.util.SortUtils;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
@@ -41,9 +42,14 @@ public class StatViewServlet extends HttpServlet {
private final static int RESULT_CODE_SUCCESS = 1;
private final static int RESULT_CODE_ERROR = -1;
private final static int DEFAULT_PAGE = 1;
private final static int DEFAULT_PER_PAGE_COUNT = Integer.MAX_VALUE;
private final static String RESOURCE_PATH = "support/http/resources";
private final static String TEMPLATE_PAGE_RESOURCE_PATH = RESOURCE_PATH + "/template.html";
private static final String DEFAULT_ORDER_TYPE = "asc";
public String templatePage;
public void init() throws ServletException {
@@ -96,7 +102,7 @@ public class StatViewServlet extends HttpServlet {
}
if (path.equals("/sql.json")) {
returnJSONResult(request, response, RESULT_CODE_SUCCESS, getSqlStatDataList());
returnJSONResult(request, response, RESULT_CODE_SUCCESS, getSqlStatDataList(request));
return;
}
@@ -258,14 +264,33 @@ public class StatViewServlet extends HttpServlet {
return null;
}
private List<Object> getSqlStatDataList() {
List<Object> array = new ArrayList<Object>();
private List<Map<String, Object>> getSqlStatDataList(HttpServletRequest request) {
String orderBy = request.getParameter("orderBy");
String orderType = request.getParameter("orderType");
Integer page = StringUtils.stringToInteger(request.getParameter("page"));
Integer perPageCount = StringUtils.stringToInteger(request.getParameter("perPageCount"));
if (!"desc".equals(orderType)) orderType = DEFAULT_ORDER_TYPE;
if (page == null) page = DEFAULT_PAGE;
if (perPageCount == null) perPageCount = DEFAULT_PER_PAGE_COUNT;
List<Map<String, Object>> array = new ArrayList<Map<String, Object>>();
for (DruidDataSource datasource : DruidDataSourceStatManager.getDruidDataSourceInstances()) {
for (JdbcSqlStat sqlStat : datasource.getDataSourceStat().getSqlStatMap().values()) {
array.add(getSqlStatData(sqlStat));
}
}
return array;
// orderby
SortUtils.sortMapList(orderBy, array, DEFAULT_ORDER_TYPE.equals(orderType));
// page
int fromIndex = (page - 1) * perPageCount;
int toIndex = page * perPageCount;
if (toIndex > array.size()) toIndex = array.size();
return array.subList(fromIndex, toIndex);
}
private Map<String, Object> dataSourceToMapData(DruidDataSource dataSource) {
@@ -0,0 +1,59 @@
package com.alibaba.druid.util;
import java.text.Collator;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author sandzhang<sandzhangtoo@gmail.com>
*/
public class SortUtils {
public static void sortMapList(final String orderByKey, List<Map<String, Object>> targetList, final boolean isDesc) {
if (orderByKey == null || orderByKey.length() == 0) return;
Collections.sort(targetList, new Comparator<Map<String, Object>>() {
private int compare(Number o1, Number o2) {
return (int) (o1.doubleValue() - o2.doubleValue());
}
private int compare(String o1, String o2) {
return Collator.getInstance().compare(o1, o2);
}
private int compare(Date o1, Date o2) {
return (int) (o1.getTime() - o2.getTime());
}
@Override
public int compare(Map<String, Object> o1, Map<String, Object> o2) {
int result = compare_0(o1, o2);
if (isDesc) result = -result;
return result;
}
public int compare_0(Map<String, Object> o1, Map<String, Object> o2) {
Object v1 = o1.get(orderByKey);
Object v2 = o2.get(orderByKey);
if (v1 == null && v2 == null) return 0;
if (v1 == null) return -1;
if (v2 == null) return 1;
if (v1 instanceof Number) return compare((Number) v1, (Number) v2);
if (v1 instanceof String) return compare((String) v1, (String) v2);
if (v1 instanceof Date) return compare((Date) v1, (Date) v2);
return 0;
}
});
}
}
@@ -6,7 +6,7 @@
<script src="js.js" type="text/javascript" charset="utf8"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
</head>
<body onload="init()">
<body>
<br />
<div id="menu" >
<a href="index.html">Index</a> | <a href="datasource.html">DataSource</a> | <a href="sql.html">Sql</a> | <a href="#" onclick="ajaxRequestForReset()">Reset All</a> | <a href="api.html">JSON API</a>
@@ -49,7 +49,11 @@
<a href="sql.json" target="_blank">sql.json</a>
</td>
<td>
SqlStat info List.
<p>SqlStat info List.</p>
<p>orderBy=[ID|ExecuteCount|...|](every property without histogram in sqlstat object)</p>
<p>orderType=[asc|desc] default is desc</p>
<p>page=page count start with 1</p>
<p>perPageCount=item count in one page,default is IN</p>
</td>
</tr>
<tr>
@@ -3,6 +3,44 @@ var xmlHttpForDataSourceInfo;
var xmlHttpForDataSourceSqlStatInfo;
var xmlHttpForReset;
var sqlViewOrderBy = 'ID';
var sqlViewOrderType = 'asc';
// only one page for now
var sqlViewPage = 1;
var sqlViewPerPageCount = 1000000;
function setOrderBy(orderBy) {
if (sqlViewOrderBy != orderBy) {
sqlViewOrderBy = orderBy;
sqlViewOrderType = 'desc'
return;
}
if (sqlViewOrderType == 'asc')
sqlViewOrderType = 'desc'
else
sqlViewOrderType = 'asc'
}
function getSqlViewJsonUrl() {
var result = 'sql.json?';
if (sqlViewOrderBy != undefined)
result += 'orderBy=' + sqlViewOrderBy + '&';
if (sqlViewOrderType != undefined)
result += 'orderType=' + sqlViewOrderType + '&';
if (sqlViewPage != undefined)
result += 'page=' + sqlViewPage + '&';
if (sqlViewPerPageCount != undefined)
result += 'perPageCount=' + sqlViewPerPageCount + '&';
return result;
}
function ajaxRequestForReset() {
if (window.XMLHttpRequest)
xmlHttpForReset = new XMLHttpRequest();
@@ -28,7 +66,7 @@ function ajaxRequestForDataSourceSqlStatInfo() {
else if (window.ActiveXObject)
xmlHttpForDataSourceSqlStatInfo = new ActiveXObject("Microsoft.XMLHTTP");
xmlHttpForDataSourceSqlStatInfo.onreadystatechange = ajaxResponseForDataSourceSqlStatInfo;
xmlHttpForDataSourceSqlStatInfo.open("GET", 'sql.json', true);
xmlHttpForDataSourceSqlStatInfo.open("GET", getSqlViewJsonUrl(), true);
xmlHttpForDataSourceSqlStatInfo.send(null);
}
function ajaxRequestForDataSourceInfo() {
@@ -226,14 +264,14 @@ function ajaxResponseForDataSourceSqlStatInfo() {
var sqlStat = sqlStatList[i];
var newRow = sqlStatTable.insertRow(-1);
newRow.insertCell(-1).innerHTML = '<a target="_blank" href="sql-' + sqlStat.ID + '.html">' + subSqlString(sqlStat.SQL, 25) + '</a>';
// if (sqlStat.File)
// newRow.insertCell(-1).innerHTML = sqlStat.File;
// else
// newRow.insertCell(-1).innerHTML = '';
// if (sqlStat.Name)
// newRow.insertCell(-1).innerHTML = sqlStat.Name;
// else
// newRow.insertCell(-1).innerHTML = '';
// if (sqlStat.File)
// newRow.insertCell(-1).innerHTML = sqlStat.File;
// else
// newRow.insertCell(-1).innerHTML = '';
// if (sqlStat.Name)
// newRow.insertCell(-1).innerHTML = sqlStat.Name;
// else
// newRow.insertCell(-1).innerHTML = '';
newRow.insertCell(-1).innerHTML = sqlStat.ExecuteCount;
newRow.insertCell(-1).innerHTML = sqlStat.TotalTime;
newRow.insertCell(-1).innerHTML = sqlStat.MaxTimespan;
@@ -22,16 +22,16 @@
<h2>SqlStat List<a href="sql.json" target="_blank">[View JSON API]</a></h2>
<table cellspacing="1" cellpadding="5" id="SqlStatTable" width="99%">
<thead>
<th class="td_lable">SQL</th>
<th class="td_lable" width="50">Execute Count</th>
<th class="td_lable" width="50">Execute Millis Total</th>
<th class="td_lable" width="50">Execute Millis Max</th>
<th class="td_lable" width="50">InTxn Count</th>
<th class="td_lable" width="50">Error Count</th>
<th class="td_lable" width="50">Effected Row Count</th>
<th class="td_lable" width="50">Fetch Row Count</th>
<th class="td_lable" width="50">Running Count</th>
<th class="td_lable" width="80">Concurrent Max</th>
<th class="td_lable" ><a href="#" onclick="setOrderBy('SQL');return false;">SQL</a></th>
<th class="td_lable" width="50"><a href="return false;" onclick="setOrderBy('ExecuteCount');return false;">Execute Count</a></th>
<th class="td_lable" width="50"><a href="return false;" onclick="setOrderBy('TotalTime');return false;">Execute Millis Total</a></th>
<th class="td_lable" width="50"><a href="return false;" onclick="setOrderBy('MaxTimespan');return false;">Execute Millis Max</a></th>
<th class="td_lable" width="50"><a href="return false;" onclick="setOrderBy('InTransactionCount');return false;">InTxn Count</a></th>
<th class="td_lable" width="50"><a href="return false;" onclick="setOrderBy('ErrorCount');return false;">Error Count</a></th>
<th class="td_lable" width="50"><a href="return false;" onclick="setOrderBy('EffectedRowCount');return false;">Effected Row Count</a></th>
<th class="td_lable" width="50"><a href="return false;" onclick="setOrderBy('FetchRowCount');return false;">Fetch Row Count</a></th>
<th class="td_lable" width="50"><a href="return false;" onclick="setOrderBy('RunningCount');return false;">Running Count</a></th>
<th class="td_lable" width="80"><a href="return false;" onclick="setOrderBy('ConcurrentMax');return false;">Concurrent Max</a></th>
<th class="td_lable" width="100">ExecHistogram</th>
<th class="td_lable" width="100">FetchRow</th>
<th class="td_lable" width="100">UpdateCount</th>