> data = TableDataProcessor.parseData(TableDataProcessor.getData(url,
+ conn));
if (data != null) {
tableDataProcess(data);
}
@@ -230,9 +178,13 @@ public abstract class DruidPanel extends JPanel {
}
protected void doInBackground(MBeanServerConnection conn) {
-
+ if (conn == null) {
+ LOG.warn("MBeanServerConnection is null");
+ return;
+ }
try {
- addOrRefreshTable(url, conn);
+ this.conn = conn;
+ addOrRefreshTable(url);
} catch (Exception e) {
LOG.warn("", e);
}
diff --git a/src/main/java/com/alibaba/druid/support/jconsole/DruidSQLPanel.java b/src/main/java/com/alibaba/druid/support/jconsole/DruidSQLPanel.java
index 7bb07181ba..6c65ed27c1 100644
--- a/src/main/java/com/alibaba/druid/support/jconsole/DruidSQLPanel.java
+++ b/src/main/java/com/alibaba/druid/support/jconsole/DruidSQLPanel.java
@@ -299,7 +299,7 @@ public class DruidSQLPanel extends DruidPanel {
if (e.getClickCount() == 2) {// 点击几次,这里是双击事件
int row = table.getSelectedRow();
String id = ids.get(row);
- System.out.println(id);
+ new DruidSqlDetailFrame(id,conn);
}
}
});
diff --git a/src/main/java/com/alibaba/druid/support/jconsole/DruidSqlDetailFrame.java b/src/main/java/com/alibaba/druid/support/jconsole/DruidSqlDetailFrame.java
new file mode 100644
index 0000000000..0b236749be
--- /dev/null
+++ b/src/main/java/com/alibaba/druid/support/jconsole/DruidSqlDetailFrame.java
@@ -0,0 +1,313 @@
+package com.alibaba.druid.support.jconsole;
+
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.GridLayout;
+import java.awt.Toolkit;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map.Entry;
+
+import javax.management.MBeanServerConnection;
+import javax.swing.BorderFactory;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.border.TitledBorder;
+import javax.swing.table.JTableHeader;
+import javax.swing.table.TableColumn;
+
+import com.alibaba.druid.support.jconsole.model.DruidTableCellRenderer;
+import com.alibaba.druid.support.jconsole.model.DruidTableModel;
+import com.alibaba.druid.support.jconsole.util.TableDataProcessor;
+import com.alibaba.druid.support.jconsole.util.TableDataProcessor.ColumnData;
+import com.alibaba.druid.support.logging.Log;
+import com.alibaba.druid.support.logging.LogFactory;
+
+/**
+ * sql语句的详细信息
+ *
+ * 调用服务地址:/sql-{id}.json
+ * 返回信息:
+ *
+ * {
+ "ResultCode": 1,
+ "Content": {
+ "ExecuteCount": 15,
+ "ReadStringLength": 0,
+ "LastSlowParameters": null,
+ "BlobOpenCount": 0,
+ "InputStreamOpenCount": 0,
+ "DbType": "mysql",
+ "DataSource": null,
+ "RunningCount": 0,
+ "parsedRelationships": "[]",
+ "ConcurrentMax": 1,
+ "LastErrorClass": null,
+ "MaxTimespan": 125,
+ "InTransactionCount": 0,
+ "ID": 3,
+ "parsedFields": "[]",
+ "EffectedRowCount": 0,
+ "BatchSizeTotal": 0,
+ "URL": null,
+ "ExecuteAndResultSetHoldTime": 0,
+ "LastErrorMessage": null,
+ "FetchRowCountHistogram": [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "FetchRowCountMax": 0,
+ "Histogram": [
+ 0,
+ 0,
+ 13,
+ 2,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "parsedOrderbycolumns": "[]",
+ "ErrorCount": 0,
+ "SQL": "DROP TABLE t_big",
+ "ClobOpenCount": 0,
+ "LastTime": "2012-09-14 21:35:10",
+ "File": null,
+ "LastErrorStackTrace": null,
+ "LastError": null,
+ "EffectedRowCountHistogram": [
+ 15,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "TotalTime": 742,
+ "formattedSql": "DROP TABLE t_big",
+ "Name": null,
+ "MaxTimespanOccurTime": "2012/09/14 09:35:00:758",
+ "parsedTable": "{t_big=Drop}",
+ "BatchSizeMax": 0,
+ "ReadBytesLength": 0,
+ "EffectedRowCountMax": 0,
+ "FetchRowCount": 0,
+ "parsedConditions": "[]",
+ "ResultSetHoldTime": 0,
+ "ReaderOpenCount": 0,
+ "ExecuteAndResultHoldTimeHistogram": [
+ 0,
+ 0,
+ 13,
+ 2,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "LastErrorTime": null
+ }
+ }
+ *
+ * */
+public class DruidSqlDetailFrame extends JFrame {
+
+ private static final long serialVersionUID = 1L;
+ private static final String BASE_URL = "/sql";
+ private String id;
+ private MBeanServerConnection conn;
+ private static final ArrayList PARESE_TITLE_LIST = new ArrayList(){
+
+ private static final long serialVersionUID = 1L;
+
+ {
+ add("parsedTable");
+ add("parsedFields");
+ add("parsedConditions");
+ add("parsedRelationships");
+ add("parsedOrderbycolumns");
+
+ }
+ };
+ private static final ArrayList LAST_SLOW_TITLE_LIST= new ArrayList(){
+
+ private static final long serialVersionUID = 1L;
+
+ {
+ add("MaxTimespan");
+ add("MaxTimespanOccurTime");
+ add("LastSlowParameters");
+ }
+ };
+ private static final ArrayList LAST_ERROR_TITLE_LIST= new ArrayList(){
+
+ private static final long serialVersionUID = 1L;
+
+ {
+ add("LastErrorMessage");
+ add("LastErrorClass");
+ add("LastErrorTime");
+ add("LastErrorStackTrace");
+ }
+ };
+ private static final ArrayList OTHER_ERROR_TITLE_LIST= new ArrayList(){
+
+ private static final long serialVersionUID = 1L;
+
+ {
+ add("BatchSizeMax");
+ add("BatchSizeTotal");
+ add("BlobOpenCount");
+ add("ClobOpenCount");
+ add("ReaderOpenCount");
+ add("InputStreamOpenCount");
+ add("ReadStringLength");
+ add("ReadBytesLength");
+ }
+ };
+ private ArrayList> parseData;
+ private ArrayList> lastSlowData;
+ private ArrayList> lastErrorData;
+ private ArrayList> otherData;
+ private int maxListLen;
+ private String formatSql;
+ private String sql;
+
+ private static final int WIDTH = 620;
+ private static final int HEIGHT = 520;
+ private final static Log LOG = LogFactory.getLog(DruidSqlDetailFrame.class);
+
+ public DruidSqlDetailFrame(String id, MBeanServerConnection conn) {
+ this.id = id;
+ this.conn = conn;
+ getMaxListLen();
+ init();
+ start();
+ }
+
+ private void getMaxListLen() {
+ maxListLen = PARESE_TITLE_LIST.size();
+ int slowLen = LAST_SLOW_TITLE_LIST.size();
+ int errLen = LAST_ERROR_TITLE_LIST.size();
+ int otherLen = OTHER_ERROR_TITLE_LIST.size();
+ if (maxListLen < slowLen) {
+ maxListLen = slowLen;
+ }
+ if (maxListLen < errLen) {
+ maxListLen = errLen;
+ }
+ if (maxListLen < otherLen) {
+ maxListLen = otherLen;
+ }
+ }
+
+ private void init() {
+ String url = BASE_URL + "-" + id + ".json";
+
+ try {
+ ArrayList> data = TableDataProcessor.parseData(TableDataProcessor.getData(url,conn));
+ if (data != null) {
+ LinkedHashMap contentEle = data.get(0);
+ formatSql = (String)contentEle.remove("formattedSql");
+ int parseLen = PARESE_TITLE_LIST.size();
+ int slowLen = LAST_SLOW_TITLE_LIST.size();
+ int errLen = LAST_ERROR_TITLE_LIST.size();
+ int otherLen = OTHER_ERROR_TITLE_LIST.size();
+ LinkedHashMap parseDataEle = new LinkedHashMap();
+ LinkedHashMap slowDataEle = new LinkedHashMap();
+ LinkedHashMap errDataEle = new LinkedHashMap();
+ LinkedHashMap otherDataEle = new LinkedHashMap();
+ parseData = new ArrayList>(1);
+ lastSlowData = new ArrayList>(1);
+ lastErrorData = new ArrayList>(1);
+ otherData = new ArrayList>(1);
+ for (Iterator> it = contentEle.entrySet().iterator(); it.hasNext();) {
+ Entry entry = it.next();
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ for(int i=0;i> data) {
+ final JPanel content1 = new JPanel();
+ content1.setLayout(new BorderLayout());
+ content1.setBorder((TitledBorder)BorderFactory.createTitledBorder(title));
+ contentPanel.add(content1);
+
+ ColumnData colData = TableDataProcessor.row2col(data);
+ JTable table = new JTable();
+ DruidTableModel tableModel = new DruidTableModel(colData.getDatas());
+ table.setModel(tableModel);
+
+ TableColumn col = table.getColumnModel().getColumn(0);
+ col.setCellRenderer(new DruidTableCellRenderer());
+
+ final JTableHeader header1 = table.getTableHeader();
+ content1.add(header1,BorderLayout.NORTH);
+ content1.add(table);
+ }
+
+ private void addComponentsToPane(Container pane) {
+ JScrollPane scrollPane = new JScrollPane();
+ JPanel contentPanel = new JPanel();
+ contentPanel.setLayout(new GridLayout(0,1));
+
+ final JTextArea sqlField = new JTextArea(formatSql,15,20);
+ final JScrollPane content1 = new JScrollPane (sqlField);
+
+ content1.setBorder((TitledBorder)BorderFactory.createTitledBorder("SQL语句"));
+ contentPanel.add(content1);
+
+ addTable(contentPanel,"解析信息",parseData);
+ addTable(contentPanel,"上次慢查询信息",lastSlowData);
+ addTable(contentPanel,"上次错误查询信息",lastErrorData);
+ addTable(contentPanel,"其他信息",otherData);
+
+ scrollPane.setViewportView(contentPanel);
+ pane.add(scrollPane,BorderLayout.CENTER);
+ }
+
+ private void start() {
+ addComponentsToPane(getContentPane());
+ pack();
+ setSize(WIDTH, HEIGHT);
+ double width = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
+ double height = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
+
+ setLocation( (int) (width - getWidth()) / 2,
+ (int) (height - getHeight()) / 2);
+ setVisible(true);
+ }
+
+}
diff --git a/src/main/java/com/alibaba/druid/support/jconsole/util/TableDataProcessor.java b/src/main/java/com/alibaba/druid/support/jconsole/util/TableDataProcessor.java
index 57e22c9c5c..0c1a2641de 100644
--- a/src/main/java/com/alibaba/druid/support/jconsole/util/TableDataProcessor.java
+++ b/src/main/java/com/alibaba/druid/support/jconsole/util/TableDataProcessor.java
@@ -17,8 +17,17 @@ package com.alibaba.druid.support.jconsole.util;
import java.util.ArrayList;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import com.alibaba.druid.stat.DruidStatService;
+import com.alibaba.druid.support.json.JSONUtils;
+import com.alibaba.druid.support.logging.Log;
+import com.alibaba.druid.support.logging.LogFactory;
+
/**
* 表格数据处理类
*
@@ -27,10 +36,18 @@ import java.util.Map;
public final class TableDataProcessor {
/** 名称列的列名. */
- private static final String COLUMN_KEY_NAME = "名称";
+ private static final String COLUMN_KEY_NAME = "名称";
/** 内容列的列名. */
- private static final String COLUMN_VALUE_NAME = "值";
+ private static final String COLUMN_VALUE_NAME = "值";
+
+ /** 返回码在json中的键名 */
+ private static final String RESP_JSON_RESULT_KEY = "ResultCode";
+ /** 内容在json中的键名 */
+ private static final String RESP_JSON_CONTENT_KEY = "Content";
+ /** 成功的返回码 */
+ protected static final int RESP_SUCCESS_RESULT = 1;
+ private final static Log LOG = LogFactory.getLog(TableDataProcessor.class);
/**
* TableDataProcessor的构造函数
@@ -124,6 +141,54 @@ public final class TableDataProcessor {
public static ColumnData row2col(ArrayList> rowDatas) {
return row2col(rowDatas, null);
}
+
+ /**
+ * 解析调用service后得到JSON数据
+ *
+ * @param respData 获取到的json对象
+ * @return 返回解析后的数据
+ */
+ @SuppressWarnings("unchecked")
+ public static ArrayList> parseData(Object respData) {
+ ArrayList> data = null;
+ if (respData instanceof Map) {
+ LinkedHashMap map = (LinkedHashMap) respData;
+ int rv = (Integer) map.get(RESP_JSON_RESULT_KEY);
+
+ if (rv == RESP_SUCCESS_RESULT) {
+ Object content = map.get(RESP_JSON_CONTENT_KEY);
+ if (content instanceof List) {
+ data = (ArrayList>) content;
+ } else if (content instanceof Map) {
+ LinkedHashMap contentEle = (LinkedHashMap) content;
+ data = new ArrayList>();
+ data.add(contentEle);
+ }
+ }
+ }
+ return data;
+ }
+
+ /**
+ * 调用service,返回数据
+ *
+ * @param url service的地址
+ * @param conn MBeanServerConnection对象
+ * @return 调用service后返回的数据
+ * @throws Exception
+ */
+ public static Object getData(String url, MBeanServerConnection conn) throws Exception {
+ Object o = null;
+ ObjectName name = new ObjectName(DruidStatService.MBEAN_NAME);
+
+ String result = (String) conn.invoke(name, "service", new String[] { url },
+ new String[] { String.class.getName() });
+ o = JSONUtils.parse(result);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(o.toString());
+ }
+ return o;
+ }
/**
* The Class ColumnData.