Акция Панель управления Ispmanager для VDS — первый месяц бесплатно
до 31.07.2026 Подробнее
Выберите продукт

PostgreSQL 10+: log_line_prefix для pgbadger и логирование медленных запросов

Показываю, как настроить логирование PostgreSQL 10+ так, чтобы pgbadger строил полезные отчёты: правильный log_line_prefix для текстовых логов, переход на csvlog, порог log_min_duration_statement и контекст по блокировкам и autovacuum.
PostgreSQL 10+: log_line_prefix для pgbadger и логирование медленных запросов

Зачем вообще трогать логирование PostgreSQL (и причём тут pgbadger)

Когда начинаются «внезапные» тормоза в базе, чаще всего выясняется простая вещь: логов либо нет, либо они не пригодны для анализа. Для админа/DevOps это превращается в раскопки по косвенным признакам (CPU, iowait, жалобы приложения), вместо прямого ответа: какой запрос, откуда, как долго и как часто.

pgbadger решает задачу «превратить простыню логов PostgreSQL в отчёт»: топ медленных запросов, распределения по времени, источники, пользователи, базы, ошибки. Но качество отчёта зависит от того, что именно вы пишете в лог и насколько стабилен формат.

Ниже — практический пресет для PostgreSQL 10+ (подойдёт и для более новых версий): включаем полезные логи для поиска тормозов и делаем их удобными для pgbadger.

Ключевые параметры логирования: минимальный рабочий набор

Логирование настраивается в postgresql.conf (или через ALTER SYSTEM). Базовый набор параметров, который реально помогает при разборе инцидентов:

  • logging_collector — сбор логов в файлы;
  • log_directory, log_filename, ротация — чтобы логи не росли бесконечно;
  • log_destination — формат логов (текст или CSV);
  • log_line_prefix — поля в начале строки (важно для текстового формата);
  • log_min_duration_statement — логирование медленных запросов по порогу;
  • log_lock_waits, deadlock_timeout — контекст по ожиданиям блокировок;
  • log_checkpoints, log_autovacuum_min_duration — фоновые события, которые тоже влияют на latency.

pgbadger умеет разбирать и текстовые логи, и CSV. Для стабильного парсинга в проде CSV обычно надёжнее: меньше сюрпризов из‑за формата и переносов строк.

Если база крутится на отдельном сервере, полезно сразу закладывать место под логи и отчёты. На практике удобнее держать PostgreSQL и аналитику рядом на небольшой VDS, чтобы pgbadger не гонял большие файлы по сети и не зависел от рабочей станции.

Текстовые логи: какой log_line_prefix нужен, чтобы pgbadger был полезным

Если вы используете обычные текстовые логи (log_destination = 'stderr' при включённом logging_collector), то log_line_prefix критичен. Он должен давать pgbadger стабильные поля для группировки и помогать вам быстро понимать контекст.

Рекомендуемый log_line_prefix

Практичный префикс, который обычно хорошо «ложится» в отчёты и удобен при чтении глазами:

log_line_prefix = '%m [%p] db=%d,user=%u,app=%a,client=%h '

Что означают токены:

  • %m — timestamp с миллисекундами;
  • %p — PID backend-процесса (удобно склеивать события одного подключения);
  • %d — база;
  • %u — пользователь;
  • %aapplication_name (очень полезно, если задаёте его в драйвере/пуле);
  • %h — хост клиента (или пусто для локальных сокетов).

Именованные ключи (db=, user=, app=) помогают даже при «грязных» значениях. Заканчивайте префикс пробелом — мелочь, но снижает шанс «склейки» с последующим текстом.

Частые ошибки

Слишком короткий префикс вроде %t даёт время, но убивает диагностику: сложно понять, кто генерирует нагрузку и из какого сервиса идёт поток запросов.

Слишком «жирный» префикс (добавили всё подряд) увеличивает размер логов и ухудшает читаемость. Добавляйте только то, чем реально будете пользоваться в разборе.

Фрагмент лога PostgreSQL с настроенным log_line_prefix и длительностью запросов

CSV логирование (csvlog): когда лучше выбрать его

Формат csvlog хорош тем, что структура фиксирована: каждое поле — отдельная колонка. pgbadger умеет разбирать CSV и обычно делает это предсказуемее, чем текстовые логи с экзотическими префиксами.

Минимальная настройка для CSV:

logging_collector = on
log_destination = 'csvlog'
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d.csv'
log_rotation_age = 1d
log_rotation_size = 0

В режиме csvlog значение log_line_prefix не играет роли: CSV содержит свои поля. Это удобно, если у вас несколько команд/сервисов и вы хотите исключить «религиозные войны» вокруг формата строки.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Логирование медленных запросов: log_min_duration_statement без боли

log_min_duration_statement — самый быстрый способ начать разбор slow queries без внедрения APM и сложных трассировок. Параметр задаёт порог в миллисекундах: всё, что дольше, попадёт в лог.

  • Для «горячего» продакшена начните с 500–1000 мс.
  • Для проблемного периода можно временно снизить до 100–200 мс.
  • На стейдже допустимо поставить 0 и логировать всё, но на проде это почти всегда слишком шумно.

Пример стартовой настройки:

log_min_duration_statement = 500

В логах вы получите длительность и текст запроса, а pgbadger агрегирует это в топы и распределения.

Нужно ли включать log_duration

log_duration пишет длительность каждого завершённого запроса, даже быстрого. Обычно это лавина. В большинстве случаев достаточно log_min_duration_statement.

log_duration = off

Что делать с «шумными» запросами (healthcheck, heartbeat)

Если приложение делает однотипный быстрый запрос каждые N секунд, а в период деградации он иногда перепрыгивает порог — отчёты могут засоряться. Типовые варианты:

  • поднять порог log_min_duration_statement;
  • отдельно анализировать такие запросы по application_name;
  • пересмотреть healthcheck (убрать тяжёлые join/функции, не дергать «дорогие» таблицы).

pgbadger: как подготовить логи и не споткнуться о мелочи

pgbadger можно запускать разово (для расследования) или по расписанию (ежедневные отчёты). Чтобы не получить сюрпризы:

  • Ротация: один бесконечный файл = медленнее анализ и больше риска упереться в диск.
  • Таймзона: удобнее, когда вся инфраструктура живёт в единой TZ и отчёт совпадает с вашим мониторингом.
  • Кодировка: держите UTF-8, аккуратнее с «грязными» строками в запросах.
  • Переносы строк в запросах (миграции/DDL): CSV обычно переживает это лучше, чем текстовый формат.

Пример запуска pgbadger для текстовых логов

pgbadger /var/lib/postgresql/data/log/postgresql-*.log -o /var/www/pgbadger/report.html

Пример запуска pgbadger для csvlog

pgbadger /var/lib/postgresql/data/log/postgresql-*.csv -f csv -o /var/www/pgbadger/report.html

Путь к логам зависит от дистрибутива и настроек log_directory. На Debian/Ubuntu с пакетной установкой часто логи лежат в /var/log/postgresql/, а при кастомной инсталляции — внутри каталога данных.

Как связать pgbadger-отчёт с реальными проблемами в проде

Отчёт сам по себе — это приборная панель. Чтобы он давал быстрые действия, держите в голове, что именно вы ищете:

  • Top slowest queries: один запрос очень долгий — проблема часто в плане, индексе, статистике, блокировках или внешнем I/O.
  • Most frequent queries: запросы по 20–50 мс, но тысячами раз в секунду — оптимизация приложения, кэшей, батчинга.
  • Errors: ошибки сериализации, таймауты, дедлоки — индикатор конкуренции.
  • Connections: если подключений слишком много, проблема часто в пуллинге и лимитах, а не в самих запросах.

Добавьте контекст: блокировки и autovacuum

Медленный запрос не всегда «плохой» сам по себе — он мог ждать блокировку. Поэтому полезно включить:

log_lock_waits = on
deadlock_timeout = 1s

И отдельно — логирование autovacuum, чтобы видеть, не совпадают ли пики latency с тяжёлыми vacuum:

log_autovacuum_min_duration = 2s

Если после этого в отчётах видно, что тормоза коррелируют с autovacuum, переходите к настройке параметров обслуживания и индексов. У меня есть отдельная практическая заметка про это: как тюнить autovacuum и индексы в PostgreSQL.

Быстрый пресет для PostgreSQL 10+: текстовые логи + pgbadger

Если хотите стартовать с текстовым форматом (stderr) и аккуратным префиксом, берите этот «скелет» и дальше крутите под себя:

logging_collector = on
log_destination = 'stderr'
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d.log'
log_rotation_age = 1d
log_rotation_size = 0

log_line_prefix = '%m [%p] db=%d,user=%u,app=%a,client=%h '

log_min_duration_statement = 500
log_duration = off

log_lock_waits = on
deadlock_timeout = 1s

log_checkpoints = on
log_autovacuum_min_duration = 2s

Почему это хороший старт:

  • есть ротация и предсказуемые имена файлов;
  • есть идентификация источника запросов через app, user, db, client;
  • медленные запросы попадают в лог без спама от быстрых;
  • видны блокировки/дедлоки и фоновые операции.

Что выбрать: csvlog или log_line_prefix

Оба подхода рабочие. На практике выбор обычно такой:

  • csvlog — если нужна максимальная предсказуемость парсинга, планируется централизованный сбор и не хочется зависеть от формата строки.
  • stderr + log_line_prefix — если вы часто читаете логи глазами на сервере, активно используете grep и хотите «человекочитаемую» строку.

Если сомневаетесь — начинайте с csvlog. Когда станет понятно, какие поля важны именно вам, можно дополнительно настроить текстовый формат для оперативной диагностики.

Страница отчёта pgbadger: топ медленных запросов и графики нагрузки

Чек-лист: чтобы анализ slow queries реально заработал

  1. Включён logging_collector и настроена ротация логов.

  2. Выбран формат: либо csvlog, либо корректный log_line_prefix для текстовых логов.

  3. Задан разумный порог log_min_duration_statement (обычно старт — 500–1000 мс).

  4. Есть контекст по ожиданиям: log_lock_waits + deadlock_timeout.

  5. pgbadger запускается по расписанию или хотя бы разово при инцидентах.

  6. С разработчиками согласовано использование application_name в строках подключения.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Если PostgreSQL «под нагрузкой»: на что обратить внимание помимо логов

Логи и pgbadger покажут «симптомы», но для лечения обычно нужно одно из действий:

  • индексы и переписывание запросов (часто видно по повторяющимся медленным SELECT);
  • проверка блокировок и транзакций (особенно долгих idle in transaction);
  • настройка autovacuum и статистики (плохие планы, bloat, внезапные seq scan);
  • дисковая подсистема и fsync-поведение (если тормозит в пиках I/O).

Если вы ещё не выстроили базовую инфраструктуру под проекты, лучше начинать с простой и предсказуемой платформы: виртуальный хостинг для небольших сайтов и сервисов, а для выделенной БД и стабильных логов/отчётов — отдельная VDS.

Первый шаг всё равно один: включить адекватное логирование PostgreSQL, чтобы перестать гадать и начать измерять.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину

Ошибка mount: wrong fs type, bad option, bad superblock в Debian/Ubuntu может означать и простую опечатку в имени раздела, и пробл ...
Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление

Если XFS-раздел внезапно стал доступен только для чтения, а сервер ушёл в emergency mode, главное — не спешить. Разберём безопасны ...
Debian/Ubuntu: как исправить Failed to fetch при apt update OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить Failed to fetch при apt update

Ошибка Failed to fetch при apt update в Debian и Ubuntu обычно связана не с самим APT, а с DNS, сетью, зеркалом, прокси, временем ...