Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
/.classpath
/.project
/.settings/
/.vscode
github.token
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ java-приложение для работы с блокировками в С
* Исправлена уязвимость при чтении XML
* Обновлены action-ы в gitHubActions
* Прекращена поддержка PostgreSQL версий ниже 10, удалена настройка для отображения типа процесса
* Добавлены новые столбцы `Тип ожидаемого события` и `Имя ожидаемого события`

1.9.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,21 @@ public class DBProcess implements IObject {
private final Date stateChange; //изменено
private final DBProcessQuery query;
private final DBProcessQueryCaller queryCaller;
private final String waitEventType;
private final String waitEventName;

private DBProcessStatus status = DBProcessStatus.WORKING;

public DBProcess(int pid, String backendType, DBProcessQueryCaller queryCaller, String state, Date stateChange, DBProcessQuery query) {
public DBProcess(int pid, String backendType, DBProcessQueryCaller queryCaller, String state, Date stateChange,
DBProcessQuery query, String waitEventType, String waintEventName) {
this.pid = pid;
this.backendType = backendType;
this.queryCaller = queryCaller;
this.state = state;
this.stateChange = stateChange;
this.query = query;
this.waitEventType = waitEventType;
this.waitEventName = waintEventName;
}

public void addBlock(DBBlock block) {
Expand Down Expand Up @@ -126,6 +131,14 @@ public DBProcessQueryCaller getQueryCaller() {
return queryCaller;
}

public String getWaitEventType() {
return waitEventType;
}

public String getWaitEventName() {
return waitEventName;
}

@Override
public List<DBProcess> getChildren() {
return children;
Expand Down Expand Up @@ -160,6 +173,8 @@ public String toString() {
", stateChange=" + stateChange +
", query=" + query +
", queryCaller=" + queryCaller +
", waitEventType=" + waitEventType +
", waitEventName=" + waitEventName +
", status=" + status +
'}';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ public String getRowText(Object element, Columns column) {
return String.valueOf(process.getQuery().isSlowQuery());
case QUERY:
return process.getQuery().getQueryFirstLine();
case WAIT_EVENT_TYPE:
return process.getWaitEventType();
case WAIT_EVENT_NAME:
return process.getWaitEventName();
default:
return "";
}
Expand Down Expand Up @@ -189,6 +193,10 @@ public int compare(Object e1, Object e2, Columns column) {
case SLOW_QUERY:
return Boolean.compare(process1.getQuery().isSlowQuery(),
process2.getQuery().isSlowQuery());
case WAIT_EVENT_TYPE:
return process1.getWaitEventType().compareTo(process2.getWaitEventType());
case WAIT_EVENT_NAME:
return process1.getWaitEventName().compareTo(process2.getWaitEventName());
default:
return 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ protected Object[][] getContents() {
{"block_start_date", "Block started"},
{"block_end_date", "Block ended"},
{"duration", "Duration"},
{"wait_event_type", "Wait event type"},
{"wait_event", "Wait event name"},

// settings dialog
{"processes", "Processes"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ protected Object[][] getContents() {
{"block_start_date", "Блокировка началась"},
{"block_end_date", "Блокировка завершена"},
{"duration", "Длительность"},
{"wait_event_type", "Тип ожидаемого события"},
{"wait_event", "Имя ожидаемого события"},

// settings dialog
{"processes", "Процессы"},
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/ru/taximaxim/pgsqlblocks/utils/Columns.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ public enum Columns {
LOCK_TYPE("lock_type"),
RELATION("relation"),
SLOW_QUERY("slow_query"),
QUERY("query");
QUERY("query"),
WAIT_EVENT_TYPE("wait_event_type"),
WAIT_EVENT_NAME("wait_event");

private final String columnName;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ public class DBBlocksXmlStore extends XmlStore<DBBlocksJournalProcess> {
private static final String USE_NAME = "usename";
private static final String CLIENT = "client";
private static final String PROCESS_STATUS = "processStatus";
private static final String WAIT_EVENT_TYPE = "wait_event_type";
private static final String WAIT_EVENT_NAME = "wait_event";

private final String fileName;

Expand Down Expand Up @@ -96,7 +98,7 @@ private DBProcess parseProcess(Node node) {

int pid = Integer.parseInt(rootElement.getElementsByTagName(PID).item(0).getTextContent());
String backendType = "";
if (hasBackendType(rootElement)) {
if (hasElement(rootElement, BACKEND_TYPE)) {
backendType = rootElement.getElementsByTagName(BACKEND_TYPE).item(0).getTextContent();
}
String appName = rootElement.getElementsByTagName(APPLICATION_NAME).item(0).getTextContent();
Expand All @@ -110,13 +112,19 @@ private DBProcess parseProcess(Node node) {
Date queryStart = DateUtils.dateFromString(rootElement.getElementsByTagName(QUERY_START).item(0).getTextContent());
Date xactStart = DateUtils.dateFromString(rootElement.getElementsByTagName(XACT_START).item(0).getTextContent());
String duration = "";
if (hasDuration(rootElement)) {
if (hasElement(rootElement, DURATION)) {
duration = rootElement.getElementsByTagName(DURATION).item(0).getTextContent();
}
DBProcessQuery query = new DBProcessQuery(queryString, slowQuery, backendStart, queryStart, xactStart, duration);
String state = rootElement.getElementsByTagName(STATE).item(0).getTextContent();
Date stateChange = DateUtils.dateFromString(rootElement.getElementsByTagName(STATE_CHANGE).item(0).getTextContent());
DBProcess process = new DBProcess(pid, backendType, caller, state, stateChange, query);
String waitEventType = "";
String waitEventName = "";
if (hasElement(rootElement, WAIT_EVENT_TYPE)) {
waitEventType = rootElement.getElementsByTagName(WAIT_EVENT_TYPE).item(0).getTextContent();
waitEventName = rootElement.getElementsByTagName(WAIT_EVENT_NAME).item(0).getTextContent();
}
DBProcess process = new DBProcess(pid, backendType, caller, state, stateChange, query, waitEventType, waitEventName);
Element childrenRootElement = (Element)rootElement.getElementsByTagName(CHILDREN_ELEMENT_TAG_NAME).item(0);
NodeList childrenElements = childrenRootElement.getChildNodes();
for (int i = 0; i < childrenElements.getLength(); i++) {
Expand Down Expand Up @@ -165,23 +173,21 @@ private void appendProcess(Document xml, Element root, DBProcess process) {
createSubElement(xml, rootElement, USE_NAME, process.getQueryCaller().getUserName());
createSubElement(xml, rootElement, CLIENT, process.getQueryCaller().getClient());
createSubElement(xml, rootElement, PROCESS_STATUS, process.getStatus().getDescr());
createSubElement(xml, rootElement, WAIT_EVENT_TYPE, process.getWaitEventType());
createSubElement(xml, rootElement, WAIT_EVENT_NAME, process.getWaitEventName());
Element childrenElement = xml.createElement(CHILDREN_ELEMENT_TAG_NAME);
rootElement.appendChild(childrenElement);
process.getChildren().forEach(p -> appendProcess(xml, childrenElement, p));
}

private boolean hasBackendType(Element element) {
return element.getElementsByTagName(BACKEND_TYPE).getLength() > 0;
}

private boolean hasDuration(Element element) {
return element.getElementsByTagName(DURATION).getLength() > 0;
private boolean hasElement(Element element, String elmentTagName) {
return 0 < element.getElementsByTagName(elmentTagName).getLength();
}

public static DBProcess readFromResultSet(ResultSet resultSet) throws SQLException {
int pid = resultSet.getInt(PID);
String backendType = hasBackendType(resultSet.getMetaData()) ? resultSet.getString(BACKEND_TYPE) : "";
String state = resultSet.getString(STATE) == null ? "" : resultSet.getString(STATE);
String backendType = getStringOrBlank(resultSet, BACKEND_TYPE);
String state = getStringOrBlank(resultSet, STATE);
Date stateChangeDate = DateUtils.dateFromString(resultSet.getString(STATE_CHANGE));

String queryString = resultSet.getString(QUERY_SQL);
Expand All @@ -197,22 +203,14 @@ public static DBProcess readFromResultSet(ResultSet resultSet) throws SQLExcepti
String userName = resultSet.getString(USE_NAME);
String client = resultSet.getString(CLIENT);
DBProcessQueryCaller caller = new DBProcessQueryCaller(appName, databaseName, userName, client);
String waitEventType = getStringOrBlank(resultSet, WAIT_EVENT_TYPE);
String waitEventName = getStringOrBlank(resultSet, WAIT_EVENT_NAME);

return new DBProcess(pid, backendType, caller, state, stateChangeDate, query);
return new DBProcess(pid, backendType, caller, state, stateChangeDate, query, waitEventType, waitEventName);
}

private static boolean hasBackendType(ResultSetMetaData metaData) {
try {
int columns = metaData.getColumnCount();
for (int x = 1; x <= columns; x++) {
if (BACKEND_TYPE.equals(metaData.getColumnName(x))) {
return true;
}
}
} catch (SQLException e) {
LOG.error(e.getMessage());
}
return false;
private static String getStringOrBlank(ResultSet resultSet, String columnName) throws SQLException {
String columnValue = resultSet.getString(columnName);
return null == columnValue ? "" : columnValue;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,9 @@ private String getColumnTooltip(Columns column) {
case LOCK_TYPE:
case RELATION:
case SLOW_QUERY:
case QUERY: return column.name();
case QUERY:
case WAIT_EVENT_TYPE:
case WAIT_EVENT_NAME: return column.name();
case DURATION: return "now - XACT_START";
default : return "";
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/query.sql
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ SELECT
datname,
usename,
backend_type,
wait_event_type,
wait_event,
CASE WHEN client_port=-1 THEN 'local pipe'
WHEN length(client_hostname)>0 THEN client_hostname||':'||client_port
ELSE textin(inet_out(client_addr))||':'||client_port
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/query_with_idle.sql
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ SELECT
datname,
usename,
backend_type,
wait_event_type,
wait_event,
CASE WHEN client_port=-1 THEN 'local pipe'
WHEN length(client_hostname)>0 THEN client_hostname||':'||client_port
ELSE textin(inet_out(client_addr))||':'||client_port
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,6 @@ private DBProcessQuery createDBProcessQuery() {

private DBProcess createDBProcess(int pid, DBProcessQuery processQuery) {
DBProcessQueryCaller c = new DBProcessQueryCaller("appName", "test", "user", "client");
return new DBProcess(pid, "type", c, "state", new Date(), processQuery);
return new DBProcess(pid, "type", c, "state", new Date(), processQuery, "", "");
}
}