diff --git a/screenshots/pash-viewer-screenshot-01.png b/screenshots/pash-viewer-screenshot-01.png index 9afc49f..b509cc9 100644 Binary files a/screenshots/pash-viewer-screenshot-01.png and b/screenshots/pash-viewer-screenshot-01.png differ diff --git a/src/org/ash/database/ASHDatabase.java b/src/org/ash/database/ASHDatabase.java index ea252cc..3d10e57 100644 --- a/src/org/ash/database/ASHDatabase.java +++ b/src/org/ash/database/ASHDatabase.java @@ -671,7 +671,8 @@ public DefaultTableModel getASHRawData(double begin, double end, String detail) "Wait Class", "Wait Class id", "UserID", - "Hostname" + "Hostname", + "Backend Type" }, 0); try { @@ -721,7 +722,8 @@ public DefaultTableModel getASHRawData(double begin, double end, String detail) ASH.getWaitClass(), (long) ASH.getWaitClassId(), ASH.getUserId(), - ASH.getHostname() + ASH.getHostname(), + ASH.getBackendType() }); } ActiveSessionHistoryCursor.close(); diff --git a/src/org/ash/database/ASHDatabasePG10.java b/src/org/ash/database/ASHDatabasePG10.java index 462ffce..367a384 100644 --- a/src/org/ash/database/ASHDatabasePG10.java +++ b/src/org/ash/database/ASHDatabasePG10.java @@ -49,12 +49,6 @@ // dcvetkov import import org.ash.util.Options; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; /** * The Class ASHDatabasePG10. @@ -90,15 +84,15 @@ public class ASHDatabasePG10 extends ASHDatabase { * The query ash. */ private String queryASH = "SELECT current_timestamp, " - + "datname, pid, usesysid, " - + "coalesce(usename, backend_type, 'unknown') as usename, " - + "application_name, " + + "datname, pid, usesysid, usename, " + + "application_name, backend_type, " + "coalesce(client_hostname, client_addr::text, 'localhost') as client_hostname, " - + "wait_event_type, wait_event, backend_type, query " + + "wait_event_type, wait_event, query " + "from pg_stat_activity " + "where state='active' and pid != pg_backend_pid() and query not like '%pash_snapshot()%'"; - private String FILESEPARATOR = System.getProperty("file.separator"); + private String fileSeparator = System.getProperty("file.separator"); + private String planDir = Options.getInstance().getPlanDir(); /** * The k for sample_id after reconnect @@ -183,12 +177,16 @@ private void loadAshDataToLocal() { if (model.getConnectionPool() != null) { + String connDBName = getParameter("ASH.db"); + conn = this.model.getConnectionPool().getConnection(); statement = conn.prepareStatement(this.queryASH); // set ArraySize for current statement to improve performance statement.setFetchSize(5000); + // set Timeout to 1 second + statement.setQueryTimeout(1); resultSetAsh = statement.executeQuery(); @@ -206,9 +204,8 @@ private void loadAshDataToLocal() { Long valueSampleIdTimeLongWait = (new Long(PGDateSampleTime.getTime())); Long sessionId = resultSetAsh.getLong("pid"); - String sessionType = resultSetAsh.getString("backend_type"); + String backendType = resultSetAsh.getString("backend_type"); - String ConnDBName = getParameter("ASH.db"); String databaseName = resultSetAsh.getString("datname"); Long userId = resultSetAsh.getLong("usesysid"); @@ -222,7 +219,7 @@ private void loadAshDataToLocal() { query_text = "backup"; } else if (program.equals("walreceiver") || program.equals("walsender")) { query_text = "wal"; - } else if (sessionType.equals("walreceiver") || sessionType.equals("walsender")) { + } else if (backendType.equals("walreceiver") || backendType.equals("walsender")) { query_text = "wal"; } else { query_text = "empty"; @@ -241,7 +238,7 @@ private void loadAshDataToLocal() { String event = resultSetAsh.getString("wait_event"); String waitClass = resultSetAsh.getString("wait_event_type"); - if (waitClass == null) { + if ((waitClass == null) || (waitClass.equals(""))) { waitClass = "CPU"; event = "CPU"; } @@ -287,7 +284,7 @@ private void loadAshDataToLocal() { .putNoReturn(new ActiveSessionHistory( activeSessionHistoryIdWait, valueSampleIdTimeLongWait, - sessionId, sessionType, userId, userName, sqlId, command_type, + sessionId, backendType, userId, userName, sqlId, command_type, event, waitClass, waitClassId, program, hostname)); } catch (Exception e) { e.printStackTrace(); @@ -302,68 +299,11 @@ private void loadAshDataToLocal() { // dcvetkov: explain plan if (command_type.equals("SELECT") || command_type.equals("UPDATE") || command_type.equals("DELETE") || command_type.equals("INSERT")) { - - String planFileName = Options.getInstance().getPlanDir() + FILESEPARATOR + sqlId + ".plan"; - String textFileName = Options.getInstance().getPlanDir() + FILESEPARATOR + sqlId + ".sql"; - File planFile = new File(planFileName); - // если mtime файла старше часа - запрашиваем план заново - if (System.currentTimeMillis() - planFile.lastModified() > 3600000) { - - String plan = "EXPLAIN PLAN FOR SQLID " + sqlId + " (" + command_type + "):\n" - + "------------------------------------------------------------\n\n"; - - if (ConnDBName.equals(databaseName)) { - - ResultSet rs1 = null; - PreparedStatement st1 = null; - try { - st1 = conn.prepareStatement("EXPLAIN " + query_text); - rs1 = st1.executeQuery(); - } catch (Exception e) { - plan = plan + e.toString(); - } - - if (rs1 != null) { - while (rs1.next()) { - plan = plan + rs1.getString(1) + "\n"; - } - rs1.close(); - } - - if (st1 != null) { - st1.close(); - } - } else { - plan = plan + "You are connected to database " + ConnDBName + " while query " + sqlId + " executed in database " + databaseName; - plan = plan + ".\nSo sorry."; - } - - if (ConnDBName.length() > 0) { - Writer writer = null; - try { - writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(planFileName), "utf-8")); - writer.write(plan); - } catch (IOException ex) { - } finally { - try { - writer.close(); - } catch (Exception ex) {/*ignore*/ } - } - - writer = null; - try { - writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(textFileName), "utf-8")); - writer.write(query_text); - } catch (IOException ex) { - } finally { - try { - writer.close(); - } catch (Exception ex) {/*ignore*/ - } - } - } - } + if (connDBName.length() > 0) { + DBUtils.explainPlan(sqlId, query_text, command_type, planDir, fileSeparator, connDBName, databaseName, conn); + } } + } if (conn != null) { model.getConnectionPool().free(conn); @@ -432,12 +372,8 @@ public void calculateSqlsSessionsData(double beginTime, double endTime, // get rows from ActiveSessionHistory for samplId EntityCursor ActiveSessionHistoryCursor; - ActiveSessionHistoryCursor = dao.doRangeQuery( - dao.activeSessionHistoryByAshId, ashSumMain - .getsampleId(), true, ashSumMain.getsampleId(), - true); - Iterator ActiveSessionHistoryIter = ActiveSessionHistoryCursor - .iterator(); + ActiveSessionHistoryCursor = dao.doRangeQuery(dao.activeSessionHistoryByAshId, ashSumMain.getsampleId(), true, ashSumMain.getsampleId(), true); + Iterator ActiveSessionHistoryIter = ActiveSessionHistoryCursor.iterator(); while (ActiveSessionHistoryIter.hasNext()) { ActiveSessionHistory ASH = ActiveSessionHistoryIter.next(); @@ -452,6 +388,7 @@ public void calculateSqlsSessionsData(double beginTime, double endTime, String usernameSess = ASH.getUserName(); String programSess = ASH.getProgram(); programSess = programSess + "@" + ASH.getHostname(); + String backendSess = ASH.getBackendType(); String waitClass = ASH.getWaitClass(); String eventName = ASH.getEvent(); @@ -460,14 +397,14 @@ public void calculateSqlsSessionsData(double beginTime, double endTime, if (waitClass != null && waitClass.equalsIgnoreCase(eventFlag)) { this.loadDataToTempSqlSession(tmpSqlsTemp, tmpSessionsTemp, sqlId, waitClassId, - sessionId, sessionidS, 0.0, "", + sessionId, sessionidS, 0.0, backendSess, useridL, usernameSess, programSess, true, eventName, 0); } } else { this.loadDataToTempSqlSession(tmpSqlsTemp, tmpSessionsTemp, sqlId, waitClassId, - sessionId, sessionidS, 0.0, "", + sessionId, sessionidS, 0.0, backendSess, useridL, usernameSess, programSess, false, eventFlag, 0); } } @@ -584,7 +521,7 @@ public String getSqlText(String sqlId) { */ private void loadDataToTempSqlSession(SqlsTemp tmpSqlsTemp, SessionsTemp tmpSessionsTemp, String sqlId, double waitClassId, Long sessionId, - String sessionidS, Double sessionSerial, String sessioniSerialS, + String sessionidS, Double sessionSerial, String backendType, Long useridL, String usernameSess, String programSess, boolean isDetail, String eventDetail, double sqlPlanHashValue) { @@ -605,8 +542,8 @@ private void loadDataToTempSqlSession(SqlsTemp tmpSqlsTemp, /** * Save data for session row */ - tmpSessionsTemp.setSessionId(sessionidS, sessioniSerialS, programSess, "", usernameSess); - tmpSessionsTemp.setTimeOfGroupEvent(sessionidS + "_" + sessioniSerialS, waitClassId, count); + tmpSessionsTemp.setSessionId(sessionidS, backendType, programSess, "", usernameSess); + tmpSessionsTemp.setTimeOfGroupEvent(sessionidS, waitClassId, count); /** * Save event detail data for sql and sessions row @@ -615,7 +552,7 @@ private void loadDataToTempSqlSession(SqlsTemp tmpSqlsTemp, if (sqlId != null) { tmpSqlsTemp.setTimeOfEventName(sqlId, waitClassId, eventDetail, count); } - tmpSessionsTemp.setTimeOfEventName(sessionidS + "_" + sessioniSerialS, waitClassId, eventDetail, count); + tmpSessionsTemp.setTimeOfEventName(sessionidS, waitClassId, eventDetail, count); } } @@ -697,9 +634,8 @@ private void loadHistAshDataToLocal() { Long valueSampleIdTimeLongWait = (new Long(PGDateSampleTime.getTime())); Long sessionId = resultSetAsh.getLong("pid"); - String sessionType = resultSetAsh.getString("backend_type"); + String backendType = resultSetAsh.getString("backend_type"); - String ConnDBName = getParameter("ASH.db"); String databaseName = resultSetAsh.getString("datname"); Long userId = resultSetAsh.getLong("usesysid"); @@ -713,7 +649,7 @@ private void loadHistAshDataToLocal() { query_text = "backup"; } else if (program.equals("walreceiver") || program.equals("walsender")) { query_text = "wal"; - } else if (sessionType.equals("walreceiver") || sessionType.equals("walsender")) { + } else if (backendType.equals("walreceiver") || backendType.equals("walsender")) { query_text = "wal"; } else { query_text = "empty"; @@ -778,7 +714,7 @@ private void loadHistAshDataToLocal() { .putNoReturn(new ActiveSessionHistory( activeSessionHistoryIdWait, valueSampleIdTimeLongWait, - sessionId, sessionType, userId, userName, sqlId, command_type, + sessionId, backendType, userId, userName, sqlId, command_type, event, waitClass, waitClassId, program, hostname)); } catch (Exception e) { e.printStackTrace(); diff --git a/src/org/ash/database/ASHDatabasePG95.java b/src/org/ash/database/ASHDatabasePG95.java index 0dc72e2..fc417d3 100644 --- a/src/org/ash/database/ASHDatabasePG95.java +++ b/src/org/ash/database/ASHDatabasePG95.java @@ -49,12 +49,6 @@ // dcvetkov import import org.ash.util.Options; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; /** * The Class ASHDatabasePG9. @@ -99,7 +93,8 @@ public class ASHDatabasePG95 extends ASHDatabase { + "from pg_stat_activity " + "where state='active' and pid != pg_backend_pid()"; - private String FILESEPARATOR = System.getProperty("file.separator"); + private String fileSeparator = System.getProperty("file.separator"); + private String planDir = Options.getInstance().getPlanDir(); /** * The k for sample_id after reconnect @@ -184,12 +179,16 @@ private void loadAshDataToLocal() { if (model.getConnectionPool() != null) { + String connDBName = getParameter("ASH.db"); + conn = this.model.getConnectionPool().getConnection(); statement = conn.prepareStatement(this.queryASH); // set ArraySize for current statement to improve performance statement.setFetchSize(5000); + // set Timeout to 1 second + statement.setQueryTimeout(1); resultSetAsh = statement.executeQuery(); @@ -207,10 +206,8 @@ private void loadAshDataToLocal() { Long valueSampleIdTimeLongWait = (new Long(PGDateSampleTime.getTime())); Long sessionId = resultSetAsh.getLong("pid"); - // String sessionType = resultSetAsh.getString("backend_type"); - String sessionType = ""; + String backendType = ""; - String ConnDBName = getParameter("ASH.db"); String databaseName = resultSetAsh.getString("datname"); Long userId = resultSetAsh.getLong("usesysid"); @@ -224,6 +221,8 @@ private void loadAshDataToLocal() { query_text = "backup"; } else if (program.equals("walreceiver") || program.equals("walsender")) { query_text = "wal"; + } else if (backendType.equals("walreceiver") || backendType.equals("walsender")) { + query_text = "wal"; } else { query_text = "empty"; } @@ -267,7 +266,7 @@ private void loadAshDataToLocal() { .putNoReturn(new ActiveSessionHistory( activeSessionHistoryIdWait, valueSampleIdTimeLongWait, - sessionId, sessionType, userId, userName, sqlId, command_type, + sessionId, backendType, userId, userName, sqlId, command_type, event, waitClass, waitClassId, program, hostname)); } catch (Exception e) { e.printStackTrace(); @@ -282,68 +281,11 @@ private void loadAshDataToLocal() { // dcvetkov: explain plan if (command_type.equals("SELECT") || command_type.equals("UPDATE") || command_type.equals("DELETE") || command_type.equals("INSERT")) { - - String planFileName = Options.getInstance().getPlanDir() + FILESEPARATOR + sqlId + ".plan"; - String textFileName = Options.getInstance().getPlanDir() + FILESEPARATOR + sqlId + ".sql"; - File planFile = new File(planFileName); - // если mtime файла старше часа - запрашиваем план заново - if (System.currentTimeMillis() - planFile.lastModified() > 3600000) { - - String plan = "EXPLAIN PLAN FOR SQLID " + sqlId + " (" + command_type + "):\n" - + "------------------------------------------------------------\n\n"; - - if (ConnDBName.equals(databaseName)) { - - ResultSet rs1 = null; - PreparedStatement st1 = null; - try { - st1 = conn.prepareStatement("EXPLAIN " + query_text); - rs1 = st1.executeQuery(); - } catch (Exception e) { - plan = plan + e.toString(); - } - - if (rs1 != null) { - while (rs1.next()) { - plan = plan + rs1.getString(1) + "\n"; - } - rs1.close(); - } - - if (st1 != null) { - st1.close(); - } - } else { - plan = plan + "You are connected to database " + ConnDBName + " while query " + sqlId + " executed in database " + databaseName; - plan = plan + ".\nSo sorry."; - } - - if (ConnDBName.length() > 0) { - Writer writer = null; - try { - writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(planFileName), "utf-8")); - writer.write(plan); - } catch (IOException ex) { - } finally { - try { - writer.close(); - } catch (Exception ex) {/*ignore*/ } - } - - writer = null; - try { - writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(textFileName), "utf-8")); - writer.write(query_text); - } catch (IOException ex) { - } finally { - try { - writer.close(); - } catch (Exception ex) {/*ignore*/ - } - } - } - } + if (connDBName.length() > 0) { + DBUtils.explainPlan(sqlId, query_text, command_type, planDir, fileSeparator, connDBName, databaseName, conn); + } } + } if (conn != null) { model.getConnectionPool().free(conn); @@ -564,7 +506,7 @@ public String getSqlText(String sqlId) { */ private void loadDataToTempSqlSession(SqlsTemp tmpSqlsTemp, SessionsTemp tmpSessionsTemp, String sqlId, double waitClassId, Long sessionId, - String sessionidS, Double sessionSerial, String sessioniSerialS, + String sessionidS, Double sessionSerial, String backendType, Long useridL, String usernameSess, String programSess, boolean isDetail, String eventDetail, double sqlPlanHashValue) { @@ -585,8 +527,8 @@ private void loadDataToTempSqlSession(SqlsTemp tmpSqlsTemp, /** * Save data for session row */ - tmpSessionsTemp.setSessionId(sessionidS, sessioniSerialS, programSess, "", usernameSess); - tmpSessionsTemp.setTimeOfGroupEvent(sessionidS + "_" + sessioniSerialS, waitClassId, count); + tmpSessionsTemp.setSessionId(sessionidS, backendType, programSess, "", usernameSess); + tmpSessionsTemp.setTimeOfGroupEvent(sessionidS, waitClassId, count); /** * Save event detail data for sql and sessions row @@ -595,7 +537,7 @@ private void loadDataToTempSqlSession(SqlsTemp tmpSqlsTemp, if (sqlId != null) { tmpSqlsTemp.setTimeOfEventName(sqlId, waitClassId, eventDetail, count); } - tmpSessionsTemp.setTimeOfEventName(sessionidS + "_" + sessioniSerialS, waitClassId, eventDetail, count); + tmpSessionsTemp.setTimeOfEventName(sessionidS, waitClassId, eventDetail, count); } } diff --git a/src/org/ash/database/ASHDatabasePG96.java b/src/org/ash/database/ASHDatabasePG96.java index 8c0c2e2..fdb1187 100644 --- a/src/org/ash/database/ASHDatabasePG96.java +++ b/src/org/ash/database/ASHDatabasePG96.java @@ -49,12 +49,6 @@ // dcvetkov import import org.ash.util.Options; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; /** * The Class ASHDatabasePG9. @@ -99,7 +93,8 @@ public class ASHDatabasePG96 extends ASHDatabase { + "from pg_stat_activity " + "where state='active' and pid != pg_backend_pid()"; - private String FILESEPARATOR = System.getProperty("file.separator"); + private String fileSeparator = System.getProperty("file.separator"); + private String planDir = Options.getInstance().getPlanDir(); /** * The k for sample_id after reconnect @@ -184,12 +179,16 @@ private void loadAshDataToLocal() { if (model.getConnectionPool() != null) { + String connDBName = getParameter("ASH.db"); + conn = this.model.getConnectionPool().getConnection(); statement = conn.prepareStatement(this.queryASH); // set ArraySize for current statement to improve performance statement.setFetchSize(5000); + // set Timeout to 1 second + statement.setQueryTimeout(1); resultSetAsh = statement.executeQuery(); @@ -207,10 +206,8 @@ private void loadAshDataToLocal() { Long valueSampleIdTimeLongWait = (new Long(PGDateSampleTime.getTime())); Long sessionId = resultSetAsh.getLong("pid"); - // String sessionType = resultSetAsh.getString("backend_type"); - String sessionType = ""; + String backendType = ""; - String ConnDBName = getParameter("ASH.db"); String databaseName = resultSetAsh.getString("datname"); Long userId = resultSetAsh.getLong("usesysid"); @@ -224,6 +221,8 @@ private void loadAshDataToLocal() { query_text = "backup"; } else if (program.equals("walreceiver") || program.equals("walsender")) { query_text = "wal"; + } else if (backendType.equals("walreceiver") || backendType.equals("walsender")) { + query_text = "wal"; } else { query_text = "empty"; } @@ -291,7 +290,7 @@ private void loadAshDataToLocal() { .putNoReturn(new ActiveSessionHistory( activeSessionHistoryIdWait, valueSampleIdTimeLongWait, - sessionId, sessionType, userId, userName, sqlId, command_type, + sessionId, backendType, userId, userName, sqlId, command_type, event, waitClass, waitClassId, program, hostname)); } catch (Exception e) { e.printStackTrace(); @@ -306,68 +305,11 @@ private void loadAshDataToLocal() { // dcvetkov: explain plan if (command_type.equals("SELECT") || command_type.equals("UPDATE") || command_type.equals("DELETE") || command_type.equals("INSERT")) { - - String planFileName = Options.getInstance().getPlanDir() + FILESEPARATOR + sqlId + ".plan"; - String textFileName = Options.getInstance().getPlanDir() + FILESEPARATOR + sqlId + ".sql"; - File planFile = new File(planFileName); - // если mtime файла старше часа - запрашиваем план заново - if (System.currentTimeMillis() - planFile.lastModified() > 3600000) { - - String plan = "EXPLAIN PLAN FOR SQLID " + sqlId + " (" + command_type + "):\n" - + "------------------------------------------------------------\n\n"; - - if (ConnDBName.equals(databaseName)) { - - ResultSet rs1 = null; - PreparedStatement st1 = null; - try { - st1 = conn.prepareStatement("EXPLAIN " + query_text); - rs1 = st1.executeQuery(); - } catch (Exception e) { - plan = plan + e.toString(); - } - - if (rs1 != null) { - while (rs1.next()) { - plan = plan + rs1.getString(1) + "\n"; - } - rs1.close(); - } - - if (st1 != null) { - st1.close(); - } - } else { - plan = plan + "You are connected to database " + ConnDBName + " while query " + sqlId + " executed in database " + databaseName; - plan = plan + ".\nSo sorry."; - } - - if (ConnDBName.length() > 0) { - Writer writer = null; - try { - writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(planFileName), "utf-8")); - writer.write(plan); - } catch (IOException ex) { - } finally { - try { - writer.close(); - } catch (Exception ex) {/*ignore*/ } - } - - writer = null; - try { - writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(textFileName), "utf-8")); - writer.write(query_text); - } catch (IOException ex) { - } finally { - try { - writer.close(); - } catch (Exception ex) {/*ignore*/ - } - } - } - } + if (connDBName.length() > 0) { + DBUtils.explainPlan(sqlId, query_text, command_type, planDir, fileSeparator, connDBName, databaseName, conn); + } } + } if (conn != null) { model.getConnectionPool().free(conn); @@ -588,7 +530,7 @@ public String getSqlText(String sqlId) { */ private void loadDataToTempSqlSession(SqlsTemp tmpSqlsTemp, SessionsTemp tmpSessionsTemp, String sqlId, double waitClassId, Long sessionId, - String sessionidS, Double sessionSerial, String sessioniSerialS, + String sessionidS, Double sessionSerial, String backendType, Long useridL, String usernameSess, String programSess, boolean isDetail, String eventDetail, double sqlPlanHashValue) { @@ -609,8 +551,8 @@ private void loadDataToTempSqlSession(SqlsTemp tmpSqlsTemp, /** * Save data for session row */ - tmpSessionsTemp.setSessionId(sessionidS, sessioniSerialS, programSess, "", usernameSess); - tmpSessionsTemp.setTimeOfGroupEvent(sessionidS + "_" + sessioniSerialS, waitClassId, count); + tmpSessionsTemp.setSessionId(sessionidS, backendType, programSess, "", usernameSess); + tmpSessionsTemp.setTimeOfGroupEvent(sessionidS, waitClassId, count); /** * Save event detail data for sql and sessions row @@ -619,7 +561,7 @@ private void loadDataToTempSqlSession(SqlsTemp tmpSqlsTemp, if (sqlId != null) { tmpSqlsTemp.setTimeOfEventName(sqlId, waitClassId, eventDetail, count); } - tmpSessionsTemp.setTimeOfEventName(sessionidS + "_" + sessioniSerialS, waitClassId, eventDetail, count); + tmpSessionsTemp.setTimeOfEventName(sessionidS, waitClassId, eventDetail, count); } } diff --git a/src/org/ash/database/DBUtils.java b/src/org/ash/database/DBUtils.java index 7245f99..e29f14e 100644 --- a/src/org/ash/database/DBUtils.java +++ b/src/org/ash/database/DBUtils.java @@ -27,6 +27,17 @@ import java.util.Iterator; import java.security.MessageDigest; import java.math.BigInteger; +import org.ash.util.Options; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Connection; +import java.sql.SQLException; public class DBUtils { @@ -229,5 +240,89 @@ public static String md5Custom(String st) { return md5Hex; } + + + + public static void explainPlan(String sqlId, String query_text, String command_type, String planDir, String fileSeparator, String connDBName, String databaseName, Connection conn) { + + String planFileName = planDir + fileSeparator + sqlId + ".plan"; + String textFileName = planDir + fileSeparator + sqlId + ".sql"; + File planFile = new File(planFileName); + String plan = ""; + String planHashValue = ""; + + // если mtime файла старше часа - запрашиваем план заново + if (System.currentTimeMillis() - planFile.lastModified() > 3600000) { + + if (connDBName.equals(databaseName)) { + + ResultSet rs1 = null; + PreparedStatement st1 = null; + try { + st1 = conn.prepareStatement("EXPLAIN " + query_text); + st1.setQueryTimeout(1); + rs1 = st1.executeQuery(); + } catch (Exception e) { + plan = plan + e.toString(); + } + + if (rs1 != null) { + try { + while (rs1.next()) { + plan = plan + rs1.getString(1) + "\n"; + } + } catch (SQLException e) { e.printStackTrace(); } + + try { + rs1.close(); + } catch (SQLException e) { e.printStackTrace(); } + + planHashValue = PlanHashValue(plan); + + plan = "PLAN " + planHashValue + " FOR SQLID " + sqlId + " (" + command_type + "):\n" + + "------------------------------------------------------------\n\n" + plan; + } + + if (st1 != null) { + try { + st1.close(); + } catch (SQLException e) { e.printStackTrace(); } + } + } else { + plan = plan + "You are connected to database " + connDBName + " while query " + sqlId + " executed in database " + databaseName; + plan = plan + ".\nSo sorry."; + } + + Writer writer = null; + try { + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(planFileName), "utf-8")); + writer.write(plan); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + writer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + writer = null; + try { + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(textFileName), "utf-8")); + writer.write(query_text); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + writer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + } + } diff --git a/src/org/ash/datamodel/ActiveSessionHistory.java b/src/org/ash/datamodel/ActiveSessionHistory.java index 884e337..003fab4 100644 --- a/src/org/ash/datamodel/ActiveSessionHistory.java +++ b/src/org/ash/datamodel/ActiveSessionHistory.java @@ -48,7 +48,7 @@ class ActiveSessionHistory { long sessionId; /** The session type. */ - String backend_type; + String backendType; /** The user id. */ long userId; @@ -72,14 +72,14 @@ class ActiveSessionHistory { String program; String hostname; - public ActiveSessionHistory(long activeSessionHistoryId, long sampleId, long sessionId, String sessionType, long userId, String userName, String sqlId, String command_type, String event, String waitClass, double waitClassId, String program, String hostname) { + public ActiveSessionHistory(long activeSessionHistoryId, long sampleId, long sessionId, String backendType, long userId, String userName, String sqlId, String command_type, String event, String waitClass, double waitClassId, String program, String hostname) { this.activeSessionHistoryId = activeSessionHistoryId; this.sampleId = sampleId; this.sessionId = sessionId; - this.backend_type = sessionType; + this.backendType = backendType; this.userId = userId; this.userName = userName; this.sqlId = sqlId; @@ -128,8 +128,8 @@ public long getSessionId() { * * @return the session type */ - public String getBackend_type() { - return backend_type; + public String getBackendType() { + return backendType; } /** @@ -228,7 +228,7 @@ public String toString() { + "activeSessionHistoryId = " + this.activeSessionHistoryId + TAB + "sampleId = " + this.sampleId + TAB + "sessionId = " + this.sessionId + TAB - + "backend_type = " + this.backend_type + TAB + + "backendType = " + this.backendType + TAB + "userId = " + this.userId + TAB + "userName = " + this.userName + TAB + "sqlId = " + this.sqlId + TAB diff --git a/src/org/ash/datatemp/SessionsTemp.java b/src/org/ash/datatemp/SessionsTemp.java index 583afcc..5633985 100644 --- a/src/org/ash/datatemp/SessionsTemp.java +++ b/src/org/ash/datatemp/SessionsTemp.java @@ -83,7 +83,7 @@ public class SessionsTemp { /** * The session serial#. */ - private String SESSIONSERIAL = "SESSIONSERIAL"; + private String BACKENDTYPE = "BACKENDTYPE"; /** * The lwlock. @@ -134,9 +134,9 @@ public SessionsTemp(EntityStore store0, AshDataAccessor dao0) { * @param user_id the user_id * @param username the username */ - public void setSessionId(String _sessionId, String _sessionSerial, String program, + public void setSessionId(String _sessionId, String _backendType, String program, String user_id, String username) { - String sessionId = _sessionId + "_" + _sessionSerial; + String sessionId = _sessionId; if (!mainSessions.containsKey(sessionId)) { // Add SQL_ID, init storage for rows mainSessions.put(sessionId, new HashMap()); @@ -154,7 +154,7 @@ public void setSessionId(String _sessionId, String _sessionSerial, String progra // Set SESSIONID mainSessions.get(sessionId).put(SESSIONID, _sessionId); // Set SESSIONSERIAL - mainSessions.get(sessionId).put(SESSIONSERIAL, _sessionSerial); + mainSessions.get(sessionId).put(BACKENDTYPE, _backendType); // Set USERNAME mainSessions.get(sessionId).put(USERNAME, username); // Set PROGRAM diff --git a/src/org/ash/detail/GanttDetails.java b/src/org/ash/detail/GanttDetails.java index 58e5dbb..e457b41 100644 --- a/src/org/ash/detail/GanttDetails.java +++ b/src/org/ash/detail/GanttDetails.java @@ -195,7 +195,7 @@ private void loadDataToJPanelsPrivate(double beginTime, double endTime){ String sqlIdHash = "SQL ID"; String[][] columnNamesSqls = {{"Activity %", sqlIdHash, "SQL Type"}}; - String[][] columnNamesSessions = {{"Activity %", "PID", "User Name", "Program"}}; + String[][] columnNamesSessions = {{"Activity %", "PID", "User Name", "Program", "Backend Type"}}; /** Array SqlIdText for SQL Text tab*/ Map arraySqlIdText50SQLTextTab = new HashMap(); diff --git a/src/org/ash/detail/GanttSessions.java b/src/org/ash/detail/GanttSessions.java index 7cf5568..add2241 100644 --- a/src/org/ash/detail/GanttSessions.java +++ b/src/org/ash/detail/GanttSessions.java @@ -92,11 +92,12 @@ private Object[][] loadDataToSessionsGanttPr(){ String USERNAME = "USERNAME"; String PROGRAM = "PROGRAM"; String SESSIONID = "SESSIONID"; + String BACKENDTYPE = "BACKENDTYPE"; int i = 0; int sizeGanttTable = 100; int sizeMainSqls = database.getSessionsTempDetail().getMainSessions().size(); - Object[][] data = new Object[Math.min(sizeGanttTable, sizeMainSqls)][4]; + Object[][] data = new Object[Math.min(sizeGanttTable, sizeMainSqls)][5]; final GanttDrawingPartHelper partHelper = new GanttDrawingPartHelper(); @@ -114,6 +115,7 @@ private Object[][] loadDataToSessionsGanttPr(){ data[i][1] = me.getValue().get(SESSIONID); data[i][2] = me.getValue().get(USERNAME); data[i][3] = me.getValue().get(PROGRAM); + data[i][4] = me.getValue().get(BACKENDTYPE); /** Exit when rows > 100 */ if (i+1==Math.min(sizeGanttTable, sizeMainSqls)){ diff --git a/src/org/ash/gui/Gantt.java b/src/org/ash/gui/Gantt.java index 5bc6b1e..f83f883 100644 --- a/src/org/ash/gui/Gantt.java +++ b/src/org/ash/gui/Gantt.java @@ -243,7 +243,7 @@ private void loadDataToJPanelsPrivate(double beginTime, double endTime) { String sqlIdHash = "SQL ID"; String[][] columnNamesSqls = { { "Activity %", sqlIdHash, "SQL Type" } }; - String[][] columnNamesSessions = { { "Activity %", "PID", "User Name", "Program" } }; + String[][] columnNamesSessions = { { "Activity %", "PID", "User Name", "Program", "Backend Type" } }; /** Array NofRow-sqlId for SQL Text tab*/ Map arraySqlIdTSQLTextTab = new HashMap(); @@ -574,11 +574,12 @@ private Object[][] loadDataToSessionsGantt() { String USERNAME = "USERNAME"; String PROGRAM = "PROGRAM"; String SESSIONID = "SESSIONID"; + String BACKENDTYPE = "BACKENDTYPE"; int i = 0; int sizeGanttTable = 100; int sizeMainSqls = database.getSessionsTemp().getMainSessions().size(); - Object[][] data = new Object[Math.min(sizeGanttTable, sizeMainSqls)][4]; + Object[][] data = new Object[Math.min(sizeGanttTable, sizeMainSqls)][5]; final GanttDrawingPartHelper partHelper = new GanttDrawingPartHelper(); @@ -586,16 +587,15 @@ private Object[][] loadDataToSessionsGantt() { double sumOfRange = database.getSessionsTemp().get_sum(); // Desc sorting - HashMap> sortedSessionMap = sortHashMapByValuesCOUNT(database - .getSessionsTemp().getMainSessions()); + HashMap> sortedSessionMap = sortHashMapByValuesCOUNT(database.getSessionsTemp().getMainSessions()); - for (Entry> me : sortedSessionMap - .entrySet()) { + for (Entry> me : sortedSessionMap.entrySet()) { data[i][0] = createDrawingState(partHelper, me, countOfSqls, sumOfRange); data[i][1] = me.getValue().get(SESSIONID); data[i][2] = me.getValue().get(USERNAME); data[i][3] = me.getValue().get(PROGRAM); + data[i][4] = me.getValue().get(BACKENDTYPE); /** Exit when rows > 500 */ if (i + 1 == Math.min(sizeGanttTable, sizeMainSqls)) { diff --git a/src/org/ash/gui/MainFrame.java b/src/org/ash/gui/MainFrame.java index 14b3dbc..63e1bf2 100644 --- a/src/org/ash/gui/MainFrame.java +++ b/src/org/ash/gui/MainFrame.java @@ -396,7 +396,7 @@ protected void processWindowEvent(WindowEvent e) { private void setThresholdMaxCpu(){ Double valueSampleTime = 0.0; // double maxCpu = Double.parseDouble(this.database.getParameter("cpu_count")); - double maxCpu = 4.0; + double maxCpu = 10.0; this.stackedChartMainObject.setThresholdMaxCpu(maxCpu); this.detailJPanel.setThresholdMaxCpu(maxCpu); } diff --git a/src/org/ash/gui/Settings.java b/src/org/ash/gui/Settings.java index cd16e8b..1a7ff77 100644 --- a/src/org/ash/gui/Settings.java +++ b/src/org/ash/gui/Settings.java @@ -102,10 +102,6 @@ public class Settings extends JDialog { private JRadioButton _30RadioButtonTopA = new JRadioButton(); private JRadioButton _50RadioButtonTopA = new JRadioButton(); - /** The checkbox for sql plans */ - private JCheckBox sqlPlanCheckBoxTA = new JCheckBox(); - private JCheckBox sqlPlanCheckBoxDetail = new JCheckBox(); - /** Button group for top sqls and sql plans */ private ButtonGroup buttonGrTopSqlsTopA = new ButtonGroup(); private ButtonGroup buttonGrTopSqlsPlanTopA = new ButtonGroup(); @@ -157,7 +153,7 @@ public Settings(MainFrame root0){ super.setResizable(false); this.InitializesJDialog(); super.pack(); - this.setSize(250,420); + this.setSize(250,350); this.mainFrame = root0; Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); @@ -195,6 +191,7 @@ public void setSpinerRangeWindowEnabled(boolean flag){ * */ private void InitializesJDialog(){ + /** The radio buttons for count of top sqls */ this._0RadioButtonTopA.setMnemonic(Options.getInstance().getResource("_0RadioButton.mnemonic").charAt(0)); this._0RadioButtonTopA.setText(Options.getInstance().getResource("_0RadioButton.text")); @@ -213,14 +210,6 @@ private void InitializesJDialog(){ this._50RadioButtonTopA.setText(Options.getInstance().getResource("_50RadioButton.text")); this._50RadioButtonTopA.addItemListener(new SelectItemListenerTopSqlRadioButtonTopA()); - this.sqlPlanCheckBoxTA.setText(Options.getInstance().getResource("_sqlPlanTA.text")); - this.sqlPlanCheckBoxTA.setSelected(false); - this.sqlPlanCheckBoxTA.addItemListener(new SelectItemListenerSqlPlanTA()); - - this.sqlPlanCheckBoxDetail.setText(Options.getInstance().getResource("_sqlPlanDetail.text")); - this.sqlPlanCheckBoxDetail.setSelected(false); - this.sqlPlanCheckBoxDetail.addItemListener(new SelectItemListenerSqlPlanDetail()); - this.buttonGrTopSqlsTopA.add(_0RadioButtonTopA); this.buttonGrTopSqlsTopA.add(_10RadioButtonTopA); this.buttonGrTopSqlsTopA.add(_30RadioButtonTopA); @@ -230,9 +219,9 @@ private void InitializesJDialog(){ this.sqlTextToClipboardCheckbox.setText(Options.getInstance().getResource("texttoclip.text")); this.sqlTextToClipboardCheckbox.addItemListener(new SelectItemListenerTextToClipboard()); - this.sqlMinimalistcCheckbox.setMnemonic(Options.getInstance().getResource("texttoclip.mnemonic").charAt(0)); - this.sqlMinimalistcCheckbox.setText(Options.getInstance().getResource("minimalistic.text")); - this.sqlMinimalistcCheckbox.addItemListener(new SelectItemListenerMinimalistic()); + this.sqlMinimalistcCheckbox.setMnemonic(Options.getInstance().getResource("texttoclip.mnemonic").charAt(0)); + this.sqlMinimalistcCheckbox.setText(Options.getInstance().getResource("minimalistic.text")); + this.sqlMinimalistcCheckbox.addItemListener(new SelectItemListenerMinimalistic()); this.autoRadioButton.setMnemonic(Options.getInstance().getResource("autoRadio.mnemonic").charAt(0)); this.autoRadioButton.setText(Options.getInstance().getResource("autoRadio.text")); @@ -268,7 +257,6 @@ private void InitializesJDialog(){ this.buttonGrScaleTopA.add(scaleX15ButtonTopA); this.buttonGrScaleTopA.add(scaleX2ButtonTopA); - /** The radio buttons for top sqls (detail) */ this._0RadioButtonDetail.setMnemonic(Options.getInstance().getResource("_0RadioButton.mnemonic").charAt(0)); this._0RadioButtonDetail.setText(Options.getInstance().getResource("_0RadioButton.text")); @@ -291,8 +279,7 @@ private void InitializesJDialog(){ this.buttonGrTopSqlsDetail.add(_10RadioButtonDetail); this.buttonGrTopSqlsDetail.add(_30RadioButtonDetail); this.buttonGrTopSqlsDetail.add(_50RadioButtonDetail); - - + this.scaleAutoRadioButtonDetail.setMnemonic(Options.getInstance().getResource("scaleAutoRadioButton.mnemonic").charAt(0)); this.scaleAutoRadioButtonDetail.setText(Options.getInstance().getResource("scaleAutoRadioButton.text")); this.scaleAutoRadioButtonDetail.setSelected(true); @@ -325,11 +312,11 @@ private void InitializesJDialog(){ mainPanelCommon.setLayout(gridBagLayoutCommon1); mainPanelTopA.setLayout(gridBagLayoutTopA1); - okButtonTopA.setMnemonic(Options.getInstance().getResource("okbutton.mnemonic").charAt(0)); - okButtonTopA.setText(Options.getInstance().getResource("okbutton.text")); - okButtonTopA.addActionListener(new OptionsDialog_okButton_actionAdapter(this)); - buttonsPanelTopA.setBorder(BorderFactory.createEtchedBorder()); - buttonsPanelTopA.add(okButtonTopA, null); + okButtonTopA.setMnemonic(Options.getInstance().getResource("okbutton.mnemonic").charAt(0)); + okButtonTopA.setText(Options.getInstance().getResource("okbutton.text")); + okButtonTopA.addActionListener(new OptionsDialog_okButton_actionAdapter(this)); + buttonsPanelTopA.setBorder(BorderFactory.createEtchedBorder()); + buttonsPanelTopA.add(okButtonTopA, null); mainPanelDetail.setLayout(gridBagLayoutDetail1); okButtonDetail.setMnemonic(Options.getInstance().getResource("okbutton.mnemonic").charAt(0)); @@ -365,12 +352,14 @@ private void InitializesJDialog(){ TitledBorder.DEFAULT_POSITION, topSqlSessSettPanelTopA); - topSqlPlanSettPanelTopA.setLayout(gridBagLayoutTopA2); +// topSqlPlanSettPanelTopA.setLayout(gridBagLayoutTopA2); +/* titledSelectionModeTopA = BorderFactory.createTitledBorder(loweredetched, "SQL plan"); addCompForTitledBorder(titledSelectionModeTopA, TitledBorder.LEFT, TitledBorder.DEFAULT_POSITION, topSqlPlanSettPanelTopA); +*/ stackedSettPanelTopA.setLayout(gridBagLayoutTopA2); titledSelectionModeTopA = BorderFactory.createTitledBorder(loweredetched, "Top activity scale"); @@ -386,12 +375,14 @@ private void InitializesJDialog(){ TitledBorder.DEFAULT_POSITION, topSqlSessSettPanelDetail); - topSqlPlanSettPanelDetail.setLayout(gridBagLayoutDetail2); +// topSqlPlanSettPanelDetail.setLayout(gridBagLayoutDetail2); +/* titledSelectionModeDetail = BorderFactory.createTitledBorder(loweredetched, "SQL plan"); addCompForTitledBorder(titledSelectionModeDetail, TitledBorder.LEFT, TitledBorder.DEFAULT_POSITION, topSqlPlanSettPanelDetail); +*/ stackedSettPanelDetail.setLayout(gridBagLayoutDetail2); titledSelectionModeDetail = BorderFactory.createTitledBorder(loweredetched, "Top activity scale"); @@ -406,85 +397,41 @@ private void InitializesJDialog(){ getContentPane().add(tabsSettings); - mainPanelCommon.add(sqlTextToClipboardPanelCommon, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 260, 5), 0, 0)); - sqlTextToClipboardPanelCommon.add(sqlTextToClipboardCheckbox, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); + mainPanelCommon.add(sqlTextToClipboardPanelCommon, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); + sqlTextToClipboardPanelCommon.add(sqlTextToClipboardCheckbox, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); + sqlTextToClipboardPanelCommon.add(sqlMinimalistcCheckbox, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); + sqlTextToClipboardPanelCommon.add(new JPanel(), new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); - sqlTextToClipboardPanelCommon.add(sqlMinimalistcCheckbox, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); + mainPanelTopA.add(autoManualPanelTopA, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); + mainPanelTopA.add(topSqlSessSettPanelTopA, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); + mainPanelTopA.add(stackedSettPanelTopA, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); - sqlTextToClipboardPanelCommon.add(new JPanel(), new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); + mainPanelDetail.add(topSqlSessSettPanelDetail, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); + mainPanelDetail.add(stackedSettPanelDetail, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); - mainPanelTopA.add(autoManualPanelTopA, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); - mainPanelTopA.add(topSqlSessSettPanelTopA, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); - mainPanelTopA.add(topSqlPlanSettPanelTopA, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); - mainPanelTopA.add(stackedSettPanelTopA, new GridBagConstraints(0, 3, 1, 1, 1.0, 1.0 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); - - mainPanelDetail.add(topSqlSessSettPanelDetail, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); - mainPanelDetail.add(topSqlPlanSettPanelDetail, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); - mainPanelDetail.add(stackedSettPanelDetail, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); - - autoManualPanelTopA.add(manualRadioButton, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - autoManualPanelTopA.add(autoRadioButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - autoManualPanelTopA.add(spinerRangeWindow, new GridBagConstraints(2, 0, 1, 1, 1.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + autoManualPanelTopA.add(manualRadioButton, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + autoManualPanelTopA.add(autoRadioButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + autoManualPanelTopA.add(spinerRangeWindow, new GridBagConstraints(2, 0, 1, 1, 1.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - topSqlSessSettPanelTopA.add(_0RadioButtonTopA, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - topSqlSessSettPanelTopA.add(_10RadioButtonTopA, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - topSqlSessSettPanelTopA.add(_30RadioButtonTopA, new GridBagConstraints(2, 0, 1, 1, 1.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - topSqlSessSettPanelTopA.add(_50RadioButtonTopA, new GridBagConstraints(3, 0, 1, 1, 1.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + topSqlSessSettPanelTopA.add(_0RadioButtonTopA, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + topSqlSessSettPanelTopA.add(_10RadioButtonTopA, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + topSqlSessSettPanelTopA.add(_30RadioButtonTopA, new GridBagConstraints(2, 0, 1, 1, 1.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + topSqlSessSettPanelTopA.add(_50RadioButtonTopA, new GridBagConstraints(3, 0, 1, 1, 1.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - topSqlPlanSettPanelTopA.add(sqlPlanCheckBoxTA, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - topSqlPlanSettPanelTopA.add(Box.createRigidArea(new Dimension(80, 10)), new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - - stackedSettPanelTopA.add(scaleAutoRadioButtonTopA, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); - stackedSettPanelTopA.add(scaleX1ButtonTopA, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); - stackedSettPanelTopA.add(scaleX15ButtonTopA, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); - stackedSettPanelTopA.add(scaleX2ButtonTopA, new GridBagConstraints(0, 3, 1, 1, 1.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); + stackedSettPanelTopA.add(scaleAutoRadioButtonTopA, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); + stackedSettPanelTopA.add(scaleX1ButtonTopA, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); + stackedSettPanelTopA.add(scaleX15ButtonTopA, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); + stackedSettPanelTopA.add(scaleX2ButtonTopA, new GridBagConstraints(0, 3, 1, 1, 1.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); - topSqlSessSettPanelDetail.add(_0RadioButtonDetail, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - topSqlSessSettPanelDetail.add(_10RadioButtonDetail, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - topSqlSessSettPanelDetail.add(_30RadioButtonDetail, new GridBagConstraints(2, 0, 1, 1, 1.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - topSqlSessSettPanelDetail.add(_50RadioButtonDetail, new GridBagConstraints(3, 0, 1, 1, 1.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + topSqlSessSettPanelDetail.add(_0RadioButtonDetail, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + topSqlSessSettPanelDetail.add(_10RadioButtonDetail, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + topSqlSessSettPanelDetail.add(_30RadioButtonDetail, new GridBagConstraints(2, 0, 1, 1, 1.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + topSqlSessSettPanelDetail.add(_50RadioButtonDetail, new GridBagConstraints(3, 0, 1, 1, 1.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - topSqlPlanSettPanelDetail.add(sqlPlanCheckBoxDetail, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - topSqlPlanSettPanelDetail.add(Box.createRigidArea(new Dimension(80, 10)), new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - - stackedSettPanelDetail.add(scaleAutoRadioButtonDetail, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); - stackedSettPanelDetail.add(scaleX1ButtonDetail, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); - stackedSettPanelDetail.add(scaleX15ButtonDetail, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); - stackedSettPanelDetail.add(scaleX2ButtonDetail, new GridBagConstraints(0, 3, 1, 1, 1.0, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); + stackedSettPanelDetail.add(scaleAutoRadioButtonDetail, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); + stackedSettPanelDetail.add(scaleX1ButtonDetail, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0 ,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); + stackedSettPanelDetail.add(scaleX15ButtonDetail, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0 ,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); + stackedSettPanelDetail.add(scaleX2ButtonDetail, new GridBagConstraints(0, 3, 1, 1, 1.0, 0.0 ,GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0)); } @@ -618,20 +565,15 @@ public void itemStateChanged(ItemEvent e){ if(e.getStateChange() == ItemEvent.SELECTED){ if (sel.getText().equals(Options.getInstance().getResource("_0RadioButton.text"))){ mainFrame.setTopSqlsSqlTextTopA(0); - sqlPlanCheckBoxTA.setSelected(false); - sqlPlanCheckBoxTA.setEnabled(false); } else if (sel.getText().equals(Options.getInstance().getResource("_10RadioButton.text"))){ mainFrame.setTopSqlsSqlTextTopA(10); - sqlPlanCheckBoxTA.setEnabled(true); } else if (sel.getText().equals(Options.getInstance().getResource("_30RadioButton.text"))){ mainFrame.setTopSqlsSqlTextTopA(30); - sqlPlanCheckBoxTA.setEnabled(true); } else if (sel.getText().equals(Options.getInstance().getResource("_50RadioButton.text"))){ mainFrame.setTopSqlsSqlTextTopA(50); - sqlPlanCheckBoxTA.setEnabled(true); } } } @@ -649,20 +591,15 @@ public void itemStateChanged(ItemEvent e){ if(e.getStateChange() == ItemEvent.SELECTED){ if (sel.getText().equals(Options.getInstance().getResource("_0RadioButton.text"))){ mainFrame.setTopSqlsSqlTextDetail(0); - sqlPlanCheckBoxDetail.setSelected(false); - sqlPlanCheckBoxDetail.setEnabled(false); } else if (sel.getText().equals(Options.getInstance().getResource("_10RadioButton.text"))){ mainFrame.setTopSqlsSqlTextDetail(10); - sqlPlanCheckBoxDetail.setEnabled(true); } else if (sel.getText().equals(Options.getInstance().getResource("_30RadioButton.text"))){ mainFrame.setTopSqlsSqlTextDetail(30); - sqlPlanCheckBoxDetail.setEnabled(true); } else if (sel.getText().equals(Options.getInstance().getResource("_50RadioButton.text"))){ mainFrame.setTopSqlsSqlTextDetail(50); - sqlPlanCheckBoxDetail.setEnabled(true); } } } @@ -682,13 +619,13 @@ public void itemStateChanged(ItemEvent e){ mainFrame.setUpperBoundOfRangeAxisTopA(0.0); } else if (sel.getText().equals(Options.getInstance().getResource("scaleX1Button.text"))){ - mainFrame.setUpperBoundOfRangeAxisTopA(1.1); + mainFrame.setUpperBoundOfRangeAxisTopA(1.0); } else if (sel.getText().equals(Options.getInstance().getResource("scaleX15Button.text"))){ - mainFrame.setUpperBoundOfRangeAxisTopA(1.5); + mainFrame.setUpperBoundOfRangeAxisTopA(2.0); } else if (sel.getText().equals(Options.getInstance().getResource("scaleX2Button.text"))){ - mainFrame.setUpperBoundOfRangeAxisTopA(2.0); + mainFrame.setUpperBoundOfRangeAxisTopA(5.0); } } } diff --git a/src/org/ash/gui/StackedChart.java b/src/org/ash/gui/StackedChart.java index 60fce09..0a21f1f 100644 --- a/src/org/ash/gui/StackedChart.java +++ b/src/org/ash/gui/StackedChart.java @@ -324,6 +324,7 @@ private JFreeChart createChart() { legend.setPosition(RectangleEdge.RIGHT); legend.setHorizontalAlignment(HorizontalAlignment.LEFT); + legend.setVerticalAlignment(VerticalAlignment.CENTER); chart.addSubtitle(legend); diff --git a/src/org/ash/history/ASHDatabaseH.java b/src/org/ash/history/ASHDatabaseH.java index 77fcae7..47d8697 100644 --- a/src/org/ash/history/ASHDatabaseH.java +++ b/src/org/ash/history/ASHDatabaseH.java @@ -430,7 +430,8 @@ public DefaultTableModel getASHRawData(double begin, double end) throws Database "Wait Class", "Wait Class id", "UserID", - "Hostname" + "Hostname", + "Backend Type" }, 0); try { @@ -476,7 +477,8 @@ public DefaultTableModel getASHRawData(double begin, double end) throws Database ASH.getWaitClass(), (long) ASH.getWaitClassId(), ASH.getUserId(), - ASH.getHostname() + ASH.getHostname(), + ASH.getBackendType() }); } ActiveSessionHistoryCursor.close(); @@ -580,6 +582,7 @@ public void calculateSqlsSessionsData(double beginTime, double endTime, String usernameSess = ASH.getUserName(); String programSess = ASH.getProgram(); programSess = programSess + "@" + ASH.getHostname(); + String backendSess = ASH.getBackendType(); String waitClass = ASH.getWaitClass(); String eventName = ASH.getEvent(); @@ -588,13 +591,13 @@ public void calculateSqlsSessionsData(double beginTime, double endTime, if (waitClass != null && waitClass.equalsIgnoreCase(eventFlag)) { this.loadDataToTempSqlSession(tmpSqlsTemp, tmpSessionsTemp, sqlId, waitClassId, sessionId, sessionidS, - 0.0, "", useridL, usernameSess, programSess, + 0.0, backendSess, useridL, usernameSess, programSess, true, eventName, 0, ASH.getCommand_type()); } } else { this.loadDataToTempSqlSession(tmpSqlsTemp, tmpSessionsTemp, - sqlId, waitClassId, sessionId, sessionidS, - 0.0, "", useridL, usernameSess, programSess, + sqlId, waitClassId, sessionId, sessionidS, + 0.0, backendSess, useridL, usernameSess, programSess, false, eventFlag, 0, ASH.getCommand_type()); } } @@ -677,7 +680,7 @@ public String getSqlText(String sqlId) { private void loadDataToTempSqlSession(SqlsTemp tmpSqlsTemp, SessionsTemp tmpSessionsTemp, String sqlId, double waitClassId, Long sessionId, String sessionidS, Double sessionSerial, - String sessioniSerialS, Long useridL, String usernameSess, String programSess, + String backendType, Long useridL, String usernameSess, String programSess, boolean isDetail, String eventDetail, double sqlPlanHashValue, String sqlOpname) { int count = 1; @@ -700,8 +703,8 @@ private void loadDataToTempSqlSession(SqlsTemp tmpSqlsTemp, SessionsTemp tmpSess } /** Save data for session row */ - tmpSessionsTemp.setSessionId(sessionidS, sessioniSerialS, programSess, "", usernameSess); - tmpSessionsTemp.setTimeOfGroupEvent(sessionidS + "_" + sessioniSerialS, waitClassId, count); + tmpSessionsTemp.setSessionId(sessionidS, backendType, programSess, "", usernameSess); + tmpSessionsTemp.setTimeOfGroupEvent(sessionidS, waitClassId, count); /** Save event detail data for sql and sessions row */ if (isDetail) { @@ -713,7 +716,7 @@ private void loadDataToTempSqlSession(SqlsTemp tmpSqlsTemp, SessionsTemp tmpSess count); } tmpSessionsTemp.setTimeOfEventName( - sessionidS + "_" + sessioniSerialS, + sessionidS, waitClassId, eventDetail, count); diff --git a/src/org/ash/history/GanttH.java b/src/org/ash/history/GanttH.java index 2a91f1a..739f45e 100644 --- a/src/org/ash/history/GanttH.java +++ b/src/org/ash/history/GanttH.java @@ -273,7 +273,7 @@ private void loadDataToJPanelsPrivate(double beginTime, double endTime) { sqlIdHash = "SQL ID"; String[][] columnNamesSqls = {{"Activity %", sqlIdHash, "SQL Type"}}; - String[][] columnNamesSessions = {{"Activity %", "PID", "User Name", "Program"}}; + String[][] columnNamesSessions = {{"Activity %", "PID", "User Name", "Program", "Backend Type"}}; /** Array SqlIdText for SQL Text tab*/ Map arraySqlIdText50SQLTextTab = new HashMap(); @@ -610,11 +610,12 @@ private Object[][] loadDataToSessionsGantt() { String USERNAME = "USERNAME"; String PROGRAM = "PROGRAM"; String SESSIONID = "SESSIONID"; + String BACKENDTYPE = "BACKENDTYPE"; int i = 0; int sizeGanttTable = 100; int sizeMainSqls = database.getSessionsTemp().getMainSessions().size(); - Object[][] data = new Object[Math.min(sizeGanttTable, sizeMainSqls)][4]; + Object[][] data = new Object[Math.min(sizeGanttTable, sizeMainSqls)][5]; final GanttDrawingPartHelper partHelper = new GanttDrawingPartHelper(); @@ -632,6 +633,7 @@ private Object[][] loadDataToSessionsGantt() { data[i][1] = me.getValue().get(SESSIONID); data[i][2] = me.getValue().get(USERNAME); data[i][3] = me.getValue().get(PROGRAM); + data[i][4] = me.getValue().get(BACKENDTYPE); /** Exit when rows > 500 */ if (i + 1 == Math.min(sizeGanttTable, sizeMainSqls)) { diff --git a/src/org/ash/history/detail/GanttDetailsH.java b/src/org/ash/history/detail/GanttDetailsH.java index 7d7eb81..bd95de1 100644 --- a/src/org/ash/history/detail/GanttDetailsH.java +++ b/src/org/ash/history/detail/GanttDetailsH.java @@ -201,7 +201,7 @@ private void loadDataToJPanelsPrivate(double beginTime, double endTime){ sqlIdHash = "SQL ID"; String[][] columnNamesSqls = {{"Activity %", sqlIdHash, "SQL Type"}}; - String[][] columnNamesSessions = {{"Activity %", "PID", "User Name", "Program"}}; + String[][] columnNamesSessions = {{"Activity %", "PID", "User Name", "Program", "Backend Type"}}; /** Array SqlIdText for SQL Text tab*/ Map arraySqlIdText50SQLTextTab = new HashMap(); diff --git a/src/org/ash/history/detail/GanttSessions.java b/src/org/ash/history/detail/GanttSessions.java index c2f460d..733bc8f 100644 --- a/src/org/ash/history/detail/GanttSessions.java +++ b/src/org/ash/history/detail/GanttSessions.java @@ -92,11 +92,12 @@ private Object[][] loadDataToSessionsGanttPr(){ String USERNAME = "USERNAME"; String PROGRAM = "PROGRAM"; String SESSIONID = "SESSIONID"; + String BACKENDTYPE = "BACKENDTYPE"; int i = 0; int sizeGanttTable = 100; int sizeMainSqls = database.getSessionsTempDetail().getMainSessions().size(); - Object[][] data = new Object[Math.min(sizeGanttTable, sizeMainSqls)][4]; + Object[][] data = new Object[Math.min(sizeGanttTable, sizeMainSqls)][5]; final GanttDrawingPartHelper partHelper = new GanttDrawingPartHelper(); @@ -114,6 +115,7 @@ private Object[][] loadDataToSessionsGanttPr(){ data[i][1] = me.getValue().get(SESSIONID); data[i][2] = me.getValue().get(USERNAME); data[i][3] = me.getValue().get(PROGRAM); + data[i][4] = me.getValue().get(BACKENDTYPE); /** Exit when rows > 100 */ if (i+1==Math.min(sizeGanttTable, sizeMainSqls)){ diff --git a/src/org/ash/util/Dictionary.java b/src/org/ash/util/Dictionary.java index 81d81ff..f306ff1 100644 --- a/src/org/ash/util/Dictionary.java +++ b/src/org/ash/util/Dictionary.java @@ -309,9 +309,9 @@ public Object[][] getContents() { {"_sqlPlanDetail.text","save to local DB"}, {"scaleAutoRadioButton.text","Auto"}, - {"scaleX1Button.text","1xCPU_COUNT"}, - {"scaleX15Button.text","1.5xCPU_COUNT"}, - {"scaleX2Button.text","2xCPU_COUNT"}, + {"scaleX1Button.text","10 sessions"}, + {"scaleX15Button.text","20 sessions"}, + {"scaleX2Button.text","50 sessions"}, // PostgreSQL Wait Types {"CPULabel.text","CPU"}, diff --git a/src/org/ash/util/EventColors.java b/src/org/ash/util/EventColors.java index bda2f64..e3a9d6d 100644 --- a/src/org/ash/util/EventColors.java +++ b/src/org/ash/util/EventColors.java @@ -70,14 +70,16 @@ public EventColors(){ this.seriesNameColor.put("BackendRandomLock", new Color(11,244,6)); this.seriesNameColor.put("BackgroundWorkerLock", new Color(12,243,249)); this.seriesNameColor.put("BgWorkerStartup", new Color(13,242,7)); + this.seriesNameColor.put("BgWorkerShutdown", new Color(113,142,7)); this.seriesNameColor.put("BgWriterHibernate", new Color(14,241,248)); this.seriesNameColor.put("BgWriterMain", new Color(15,240,8)); this.seriesNameColor.put("BtreePage", new Color(16,239,247)); this.seriesNameColor.put("BtreeVacuumLock", new Color(17,238,9)); this.seriesNameColor.put("buffer_content", new Color(18,237,246)); - this.seriesNameColor.put("buffer_io", new Color(19,236,10)); + this.seriesNameColor.put("buffer_io", new Color(19,136,10)); this.seriesNameColor.put("buffer_mapping", new Color(220,35,245)); this.seriesNameColor.put("BufFileWrite", new Color(22,233,244)); + this.seriesNameColor.put("BufFileRead", new Color(22,233,44)); this.seriesNameColor.put("CheckpointerCommLock", new Color(23,232,12)); this.seriesNameColor.put("CheckpointerMain", new Color(24,231,243)); this.seriesNameColor.put("CheckpointLock", new Color(25,230,13)); diff --git a/src/org/jfree/chart/JFreeChart.java b/src/org/jfree/chart/JFreeChart.java index f582b85..2c91b7c 100644 --- a/src/org/jfree/chart/JFreeChart.java +++ b/src/org/jfree/chart/JFreeChart.java @@ -1260,7 +1260,7 @@ else if (hAlign == HorizontalAlignment.RIGHT) { y = frame.getY(); } else if (vAlign == VerticalAlignment.CENTER) { - y = frame.getCenterY() - (dimensions.height / 2.0); + y = frame.getCenterY() - (dimensions.height / 2.0) - 20; } else if (vAlign == VerticalAlignment.BOTTOM) { y = frame.getMaxY() - dimensions.height; diff --git a/src/org/jfree/chart/renderer/category/StackedAreaRenderer.java b/src/org/jfree/chart/renderer/category/StackedAreaRenderer.java index 0e66c20..0248e21 100644 --- a/src/org/jfree/chart/renderer/category/StackedAreaRenderer.java +++ b/src/org/jfree/chart/renderer/category/StackedAreaRenderer.java @@ -250,7 +250,10 @@ public void drawItem(Graphics2D g2, RectangleEdge edge1 = plot.getRangeAxisEdge(); GeneralPath left = new GeneralPath(); - GeneralPath right = new GeneralPath(); + // GeneralPath right = new GeneralPath(); + // dcvetkov, https://stackoverflow.com/questions/13137843/jfreechart-need-to-remove-vertical-white-lines-in-stackedareachart + GeneralPath right = left; + if (y1 >= 0.0) { // handle positive value transY1 = (float) rangeAxis.valueToJava2D(y1 + stack1[1], dataArea, edge1); diff --git a/src/org/jfree/chart/renderer/xy/StackedXYAreaRenderer2.java b/src/org/jfree/chart/renderer/xy/StackedXYAreaRenderer2.java index 03bc8ea..c86739a 100644 --- a/src/org/jfree/chart/renderer/xy/StackedXYAreaRenderer2.java +++ b/src/org/jfree/chart/renderer/xy/StackedXYAreaRenderer2.java @@ -280,7 +280,9 @@ public void drawItem(Graphics2D g2, RectangleEdge edge1 = plot.getRangeAxisEdge(); GeneralPath left = new GeneralPath(); - GeneralPath right = new GeneralPath(); + GeneralPath right = left; + // GeneralPath right = new GeneralPath(); + if (y1 >= 0.0) { // handle positive value transY1 = (float) rangeAxis.valueToJava2D(y1 + stack1[1], dataArea, edge1); diff --git a/src/org/jfree/chart/renderer/xy/StackedXYAreaRenderer3.java b/src/org/jfree/chart/renderer/xy/StackedXYAreaRenderer3.java index 07d4e52..cdff007 100644 --- a/src/org/jfree/chart/renderer/xy/StackedXYAreaRenderer3.java +++ b/src/org/jfree/chart/renderer/xy/StackedXYAreaRenderer3.java @@ -315,7 +315,9 @@ public void drawItem(Graphics2D g2, RectangleEdge edge1 = plot.getRangeAxisEdge(); GeneralPath left = new GeneralPath(); - GeneralPath right = new GeneralPath(); + GeneralPath right = left; + //GeneralPath right = new GeneralPath(); + // if (y1 >= 0.0) { // handle positive value transY1 = (float) rangeAxis.valueToJava2D(y1 + stack1[1], dataArea, edge1);