From 934de70dbc2b0514256bdf5c1b227ca9d9d91a1f Mon Sep 17 00:00:00 2001 From: Oleksii Kliukin Date: Wed, 24 Jun 2015 09:15:50 +0200 Subject: [PATCH 1/2] return current action for a process from a ps output if possible. --- pg_view.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pg_view.py b/pg_view.py index 91aefe1..23619b7 100644 --- a/pg_view.py +++ b/pg_view.py @@ -1133,18 +1133,20 @@ def ident(self): def _get_psinfo(cmdline): """ gets PostgreSQL process type from the command-line.""" pstype = 'unknown' + action = None if cmdline is not None and len(cmdline) > 0: # postgres: stats collector process m = re.match(r'postgres:\s+(.*)\s+process\s*(.*)$', cmdline) if m: pstype = m.group(1) + action = m.group(2) else: if re.match(r'postgres:.*', cmdline): # assume it's a backend process pstype = 'backend' if pstype == 'autovacuum worker': pstype = 'autovacuum' - return pstype + return (pstype, action) @staticmethod def _is_auxiliary_process(pstype): @@ -1228,7 +1230,9 @@ def _read_proc(self, pid, is_backend, is_active): # generated columns result['cmdline'] = raw_result.get('cmd', None) if not is_backend: - result['type'] = self._get_psinfo(result['cmdline']) + result['type'], action = self._get_psinfo(result['cmdline']) + if action: + result['query'] = action else: result['type'] = 'backend' if is_active or not is_backend: From 8a2402d2e5dded479441b4754633273591cbad56 Mon Sep 17 00:00:00 2001 From: Oleksii Kliukin Date: Wed, 24 Jun 2015 10:38:56 +0200 Subject: [PATCH 2/2] Fix the sorting to avoid putting processes with age 0 on top of those that doesn't have age column set altogether. --- pg_view.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pg_view.py b/pg_view.py index 23619b7..9240f1b 100644 --- a/pg_view.py +++ b/pg_view.py @@ -1415,6 +1415,10 @@ def ncurses_produce_prefix(self): self.active_connections, self.max_connections, self.recovery_status) + @staticmethod + def process_sort_key(process): + return process['age'] if process['age'] is not None else maxsize + def diff(self): """ we only diff backend processes if new one is not idle and use pid to identify processes """ @@ -1448,7 +1452,7 @@ def diff(self): # order the result rows by the start time value if len(self.blocked_diffs) == 0: self.rows_diff = self.running_diffs - self.rows_diff.sort(key=lambda process: (process['age'] or maxsize), reverse=True) + self.rows_diff.sort(key=self.process_sort_key, reverse=True) else: blocked_temp = [] # we traverse the tree of blocked processes in a depth-first order, building a list @@ -1457,10 +1461,10 @@ def diff(self): # by the current one from the plain list of process information rows, that's why # we use a dictionary of lists of blocked processes with a blocker pid as a key # and effectively build a separate tree for each blocker. - self.running_diffs.sort(key=lambda process: (process['age'] or maxsize), reverse=True) + self.running_diffs.sort(key=self.process_sort_key, reverse=True) # sort elements in the blocked lists, so that they still appear in the latest to earliest order for key in self.blocked_diffs: - self.blocked_diffs[key].sort(key=lambda process: (process['age'] or maxsize)) + self.blocked_diffs[key].sort(key=self.process_sort_key) for parent_row in self.running_diffs: self.rows_diff.append(parent_row) # if no processes blocked by this one - just skip to the next row