diff --git a/patroni/api.py b/patroni/api.py index 6f3a6ae9..dc737a4f 100644 --- a/patroni/api.py +++ b/patroni/api.py @@ -368,7 +368,11 @@ class RestApiHandler(BaseHTTPRequestHandler): def get_postgresql_status(self, retry=False): try: - row = self.query("""SELECT to_char(pg_postmaster_start_time(), 'YYYY-MM-DD HH24:MI:SS.MS TZ'), + row = self.query("""WITH replication_info AS ( + SELECT usename, application_name, client_addr, state, sync_state, sync_priority + FROM pg_stat_replication + ) + SELECT to_char(pg_postmaster_start_time(), 'YYYY-MM-DD HH24:MI:SS.MS TZ'), pg_is_in_recovery(), CASE WHEN pg_is_in_recovery() THEN 0 @@ -377,8 +381,10 @@ class RestApiHandler(BaseHTTPRequestHandler): pg_xlog_location_diff(pg_last_xlog_receive_location(), '0/0')::bigint, pg_xlog_location_diff(pg_last_xlog_replay_location(), '0/0')::bigint, to_char(pg_last_xact_replay_timestamp(), 'YYYY-MM-DD HH24:MI:SS.MS TZ'), - pg_is_in_recovery() AND pg_is_xlog_replay_paused()""", retry=retry)[0] - return { + pg_is_in_recovery() AND pg_is_xlog_replay_paused(), + (SELECT json_agg(row_to_json(ri)) FROM replication_info ri)""", retry=retry)[0] + + result = { 'state': self.server.patroni.postgresql.state, 'postmaster_start_time': row[0], 'role': 'replica' if row[1] else 'master', @@ -391,6 +397,11 @@ class RestApiHandler(BaseHTTPRequestHandler): 'location': row[2] }) } + + if row[7]: + result['replication'] = row[7] + + return result except (psycopg2.Error, RetryFailedError, PostgresConnectionException): state = self.server.patroni.postgresql.state if state == 'running': diff --git a/tests/test_postgresql.py b/tests/test_postgresql.py index a9d729f6..95a251a2 100644 --- a/tests/test_postgresql.py +++ b/tests/test_postgresql.py @@ -32,8 +32,10 @@ class MockCursor(object): self.results = [(0,)] elif sql == 'SELECT pg_is_in_recovery()': self.results = [(False, )] - elif sql.startswith('SELECT to_char(pg_postmaster_start_time'): - self.results = [('', True, '', '', '', '', False)] + elif sql.startswith('WITH replication_info AS ('): + replication_info = '[{"application_name":"walreceiver","client_addr":"1.2.3.4",' +\ + '"state":"streaming","sync_state":"async","sync_priority":0}]' + self.results = [('', True, '', '', '', '', False, replication_info)] elif sql.startswith('SELECT name, setting'): self.results = [('wal_segment_size', '2048', '8kB', 'integer', 'internal'), ('search_path', 'public', None, 'string', 'user'),