Условия и место записи
Зафиксируйте PostgreSQL 18, экземпляр, узел и период. Для jsonlog нужны соответствующий log_destination и работающий logging_collector; формат, пороги сообщений и регистрация SQL — отдельные настройки. До поиска получите паспорт конфигурации у владельца БД, затем разрешённую копию нужных файлов с учётом ротации. Не считайте файл с расширением .json доказательством правильного источника: проверьте форму нескольких объектов. Эта инструкция читает копию; включение журналирования, перезапуск сервера и изменение расширений не выполняются.
Как отобрать ошибку и сеанс
Начните с узкого интервала и state_code, не с переведённого текста ошибки. Первая команда jq выбирает 23505 и оставляет поля для сопоставления; вторая раскрывает доступные сообщения того же session_id. Работайте с JSONL, где каждая строка — самостоятельный объект, а не с JSON-массивом или CSV. Зафиксируйте имя файла и границы копии, чтобы повторная выгрузка не создала ложные дубликаты. Для связи используйте экземпляр, session_id и line_num; PID и время сохраняйте как дополнительный контекст.
Разбор результата
В примере роль demo_app в базе demo получила ERROR с SQLSTATE 23505. Официальное имя кода — unique_violation: нарушено ограничение уникальности. Это может быть повторная отправка, гонка приложения или другой сбой обработки данных; запись сама не устанавливает злой умысел. Поле line_num задаёт место сообщения внутри сеанса. Имена, адрес 192.0.2.40 и запрос на соединение вымышлены. Поля statement и detail здесь намеренно не добавлены: отсутствующее значение нельзя восстанавливать догадкой или подставлять из другой записи.
Интерпретация и предел вывода
Разделяйте ошибку сервера, итог запроса и бизнес-результат операции. Одно сообщение не показывает, выполнилась ли позднее успешная повторная попытка. Не смешивайте JSON-ключ state_code с sql_state_code из предложенной в документации CSV-таблицы. Строковые null-поля в jsonlog опускаются; неизвестные дополнительные поля следует сохранять, не ломая разбор. Адрес клиента может принадлежать пулеру, а приложение использовать общую роль. Поэтому атрибуция человеку требует отдельной цепочки, связывающей запрос приложения, соединение и доступную пользовательскую сессию.
Следующая проверка
Сопоставьте соседние строки сеанса с журналом приложения и ожидаемой операцией над данными. Определите, какая запись появилась первой и что произошло после ошибки, сохраняя границы наблюдения. Для вопроса «кто прочитал таблицу или выдал право» проверьте существующий аудит отдельно: jsonlog — формат доставки серверных сообщений, а pgAudit добавляет аудит сеанса/объекта через журналирование. Не утверждайте полный охват SELECT/GRANT без настройки и подтверждающей записи. При нехватке данных запишите точный пробел и необходимый источник.
Если записи нет
Проверьте экземпляр, формат назначения, collector, период, часовой пояс, пороги и ротацию, затем путь доставки в SIEM. Для отсутствующего SQL-текста отдельно проверьте применимые настройки регистрации сообщений и запросов. Сравните исходную копию с результатом фильтра: ошибка разбора JSONL отличается от нулевого числа совпадений. Убедитесь, что не читаете файл другого узла или предыдущего периода. Пустой вывод означает лишь отсутствие выбранной записи в доступной копии и не доказывает, что запрос никогда не выполнялся.