/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.support.console;
import com.alibaba.druid.sql.SQLUtils;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class TabledDataPrinter {
private static final int SQL_MAX_LEN = 32;
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", "ExecRsHisto" };
private static final String[] sqlRowField = new String[] { "ID", "SQL", "ExecuteCount", "TotalTime", "MaxTimespan",
"InTransactionCount", "ErrorCount", "EffectedRowCount", "FetchRowCount", "RunningCount", "ConcurrentMax",
"ExecuteAndResultHoldTimeHistogram" };
private static final String[] sqlColField = new String[] { "ID", "DataSource", "SQL", "ExecuteCount", "ErrorCount",
"TotalTime", "LastTime", "MaxTimespan", "LastError", "EffectedRowCount", "FetchRowCount",
"MaxTimespanOccurTime", "BatchSizeMax", "BatchSizeTotal", "ConcurrentMax", "RunningCount", "Name", "File",
"LastErrorMessage", "LastErrorClass", "LastErrorStackTrace", "LastErrorTime", "DbType", "URL",
"InTransactionCount", "Histogram", "LastSlowParameters", "ResultSetHoldTime",
"ExecuteAndResultSetHoldTime", "FetchRowCountHistogram", "EffectedRowCountHistogram",
"ExecuteAndResultHoldTimeHistogram", "EffectedRowCountMax", "FetchRowCountMax", "ClobOpenCount" };
private static final String[] dsRowTitle = new String[] { "Identity", "DbType", "PoolingCount", "PoolingPeak",
"PoolingPeakTime", "ActiveCount", "ActivePeak", "ActivePeakTime", "ExecuteCount", "ErrorCount" };
private static final String[] dsRowField = new String[] { "Identity", "DbType", "PoolingCount", "PoolingPeak",
"PoolingPeakTime", "ActiveCount", "ActivePeak", "ActivePeakTime", "ExecuteCount", "ErrorCount" };
private static final String[] dsColField = new String[] { "Identity", "Name", "DbType", "DriverClassName", "URL",
"UserName", "FilterClassNames", "WaitThreadCount", "NotEmptyWaitCount", "NotEmptyWaitMillis",
"PoolingCount", "PoolingPeak", "PoolingPeakTime", "ActiveCount", "ActivePeak", "ActivePeakTime",
"InitialSize", "MinIdle", "MaxActive", "QueryTimeout", "TransactionQueryTimeout", "LoginTimeout",
"ValidConnectionCheckerClassName", "ExceptionSorterClassName", "TestOnBorrow", "TestOnReturn",
"TestWhileIdle", "DefaultAutoCommit", "DefaultReadOnly", "DefaultTransactionIsolation",
"LogicConnectCount", "LogicCloseCount", "LogicConnectErrorCount", "PhysicalConnectCount",
"PhysicalCloseCount", "PhysicalConnectErrorCount", "ExecuteCount", "ErrorCount", "CommitCount",
"RollbackCount", "PSCacheAccessCount", "PSCacheHitCount", "PSCacheMissCount", "StartTransactionCount",
"TransactionHistogram", "ConnectionHoldTimeHistogram", "RemoveAbandoned", "ClobOpenCount" };
public static void printActiveConnStack(List<List<String>> content, Option opt) {
PrintStream out = opt.getPrintStream();
for (List<String> stack : content) {
for (String line : stack) {
out.println(line);
}
out.println("===============================\n");
}
}
public static void printDataSourceData(List<Map<String, Object>> content, Option opt) {
while (true) {
_printDataSourceData(content, opt);
if (opt.getInterval() == -1) {
break;
}
try {
Thread.sleep(opt.getInterval() * 1000);
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
public static void _printDataSourceData(List<Map<String, Object>> content, Option opt) {
PrintStream out = opt.getPrintStream();
if (opt.getId() != -1) {
List<Map<String, Object>> matchedContent = new ArrayList<Map<String, Object>>();
for (Map<String, Object> dsStat : content) {
Integer idStr = (Integer) dsStat.get("Identity");
if (idStr == opt.getId()) {
matchedContent.add(dsStat);
break;
}
}
content = matchedContent;
}
if (opt.isDetailPrint()) {
out.println(getVerticalFormattedOutput(content, dsColField));
} else {
out.println(getFormattedOutput(content, dsRowTitle, dsRowField));
}
}
public static void printSqlData(List<Map<String, Object>> content, Option opt) {
while (true) {
_printSqlData(content, opt);
if (opt.getInterval() == -1) {
break;
}
try {
Thread.sleep(opt.getInterval() * 1000);
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
public static void _printSqlData(List<Map<String, Object>> content, Option opt) {
PrintStream out = opt.getPrintStream();
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 == opt.getId()) {
matchedContent.add(sqlStat);
if (opt.isDetailPrint()) {
String dbType = (String) sqlStat.get("DbType");
String sql = (String) sqlStat.get("SQL");
out.println("Formatted SQL:");
out.println(SQLUtils.format(sql, dbType));
out.println();
}
break;
}
}
content = matchedContent;
}
if (opt.isDetailPrint()) {
out.println(getVerticalFormattedOutput(content, sqlColField));
} else {
out.println(getFormattedOutput(content, sqlRowTitle, sqlRowField));
}
}
public static String getFormattedOutput(List<Map<String, Object>> content, String[] title, String[] rowField) {
List<String[]> printContents = new ArrayList<String[]>();
printContents.add(title);
for (Map<String, Object> sqlStat : content) {
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);
}
return TableFormatter.format(printContents);
}
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 (String titleField : titleFields) {
String[] row = new String[maxCol + 1];
row[0] = titleField;
for (int j = 0; j < maxCol; j++) {
Map<String, Object> sqlStat = content.get(j);
Object value = sqlStat.get(titleField);
row[j + 1] = handleAndConvert(value, titleField);
}
printContents.add(row);
}
return TableFormatter.format(printContents);
}
public static String handleAndConvert(Object value, String fieldName) {
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) + "...";
}
value = sql;
}
return value.toString();
}
}