парсинг журналов postgres для использования пользователем таблицы - PullRequest
0 голосов
/ 04 сентября 2018

Я провожу аудит количества используемых таблиц базы данных и того, какие пользователи участвуют в процессе очистки базы данных. Использование файлов журнала кажется естественным способом получить эти данные. У нас запущен pgBadger для отчетов о производительности, но отчета об использовании, как я описал, не существует. Кто-нибудь знает инструмент (pgBadger или другой), который будет извлекать информацию о таблицах и пользователях из журналов, чтобы я мог рассчитать сводную статистику по нему? Я хотел бы использовать существующие инструменты, а не использовать собственный анализатор журналов.

1 Ответ

0 голосов
/ 13 сентября 2018

В итоге я пишу хакерский анализатор логов.

import re
import psqlparse
import json

statement_re = r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} UTC:[^:]*:(?P<user>\w+)@(?P<db>\w+):.*statement:\s+(?P<stmt>.*)"
log_re = r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}"

def parse_logs(log_file):
    with open(log_file, 'r') as f:
        state = 'looking'
        info = None
        for line in f:
            if state == 'found':
                if re.match(log_re, line) is None:
                    info['stmt'].append(line.strip())
                else:
                    info['stmt'] = "\n".join(info['stmt']).strip()
                    try:
                        parsed_stmt = psqlparse.parse(info['stmt'])[0]
                        info['stmt_type'] = str(type(parsed_stmt)).split(".")[-1][0:-6].lower()
                        info['tables'] = list(parsed_stmt.tables())
                    except:
                        pass
                    print(json.dumps(info))
                    state = 'looking'
            if state == 'looking':
                m = re.match(statement_re, line)
                if m is not None:
                    stmt = m.group('stmt')
                    if stmt not in {'BEGIN', 'COMMIT', 'ROLLBACK', 'SELECT 1'} and 'show' not in stmt:
                        info = {'user': m.group('user'), 'stmt': [stmt]}
                        state = 'found'

parse_logs('postgresql.log')
...