mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
StarViewServlet:add sort support for sql.json and sqlview page
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user