Настройка логирования PostgreSQL: параметры, конфигурация, мониторинг | AdminWiki

PostgreSQL настройка логирования: Полное руководство для DevOps и разработчиков

18 декабря 2025 9 мин. чтения #devops #postgresql #postgresql логи #базы данных #логирование #мониторинг #настройка

Представь, что твоя PostgreSQL база данных внезапно начала тормозить, но ты не понимаешь почему. Или произошел сбой, а информации для расследования недостаточно. Правильная настройка логирования PostgreSQL превращает эти ситуации из кошмара в решаемую задачу. Давай разберем, как настроить логирование так, чтобы видеть все важное и не утонуть в потоке данных.

Основные параметры логирования в postgresql.conf

Конфигурация логирования PostgreSQL управляется через файл postgresql.conf. Давай рассмотрим ключевые параметры, которые тебе понадобятся.

Где и как писать логи

postgresql.conf
# Куда писать логи (stderr, syslog, eventlog для Windows)
logging_collector = on
log_directory = 'pg_log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'

# Ротация логов
log_rotation_age = 1d
log_rotation_size = 100MB
log_truncate_on_rotation = off
Важно: Для применения изменений в postgresql.conf требуется перезагрузка (pg_ctl reload) или полный рестарт сервиса PostgreSQL.

Уровни детализации и что логировать

PostgreSQL предлагает гибкую систему уровней логирования. Вот основные из них:

Параметр Значения Описание
log_min_messages debug5..panic Минимальный уровень сообщений для логирования. Рекомендуется warning для production
log_min_error_statement debug5..panic Логировать SQL запросы, которые привели к ошибке
log_min_duration_statement -1 (отключено) или ms Логировать медленные запросы (в миллисекундах)

Пошаговая настройка логирования для production

Давай настроим логирование для реального production-окружения шаг за шагом.

Шаг 1: Базовая конфигурация

postgresql.conf (фрагмент)
# Включаем сбор логов
logging_collector = on
log_directory = '/var/log/postgresql'
log_filename = 'postgresql-%a.log'  # %a - день недели

# Ротация: ежедневно или при достижении 1GB
log_rotation_age = 1d
log_rotation_size = 1GB

# Уровень логирования
log_min_messages = warning          # Логируем warning и выше
log_min_error_statement = error     # Логируем запросы с ошибками
log_min_duration_statement = 1000   # Логируем запросы медленнее 1 секунды

Шаг 2: Настройка формата логов

Правильный формат упрощает парсинг и анализ:

postgresql.conf
# Формат логов (рекомендуется csvlog для машинного анализа)
log_destination = 'csvlog'  # или 'stderr' для человекочитаемого формата

# Если используешь stderr, настрой формат:
# log_line_prefix = '%m [%p] %q%u@%d '
# Где:
#   %m - timestamp с миллисекундами
#   %p - PID процесса
#   %u - имя пользователя
#   %d - имя базы данных
#   %q - не добавляет ничего, если не суперпользователь

# Для csvlog автоматически добавляются все поля
Внимание: При использовании csvlog убедись, что logging_collector = on. Также для csvlog создается дополнительный файл .csv, а не .log.

Шаг 3: Логирование медленных запросов и аудит

Для отладки производительности критически важно логировать медленные запросы:

postgresql.conf
# Логирование всех медленных запросов ( > 500ms )
log_min_duration_statement = 500

# Дополнительная информация о запросах
log_statement = 'none'           # 'none', 'ddl', 'mod', 'all'
log_duration = off               # Логировать длительность ВСЕХ запросов (осторожно!)
log_lock_waits = on              # Логировать ожидания блокировок > deadlock_timeout
deadlock_timeout = 1s

# Аудит подключений/отключений
log_connections = on
log_disconnections = on
log_hostname = on                # Логировать hostname клиента
log_timezone = 'UTC'             # Единый часовой пояс для логов

Практические примеры и сценарии

Пример 1: Настройка для разработки/отладки

postgresql.conf для dev
# Максимальная детализация для отладки
log_min_messages = info
log_min_error_statement = error
log_min_duration_statement = 100  # Все запросы > 100ms
log_statement = 'all'             # Логировать ВСЕ SQL запросы
log_duration = on                 # Длительность всех запросов

# Человекочитаемый формат
log_destination = 'stderr'
log_line_prefix = '%t [%p] [%l-1] user=%u,db=%d,app=%a '

# Временные файлы логов в текущей директории
log_directory = 'pg_log'
logging_collector = on

Пример 2: Production с балансом между информативностью и объемом

postgresql.conf для prod
# Баланс: достаточно информации без переполнения диска
log_min_messages = warning
log_min_error_statement = error
log_min_duration_statement = 1000  # Только действительно медленные
log_statement = 'ddl'              # Только DDL (CREATE, ALTER, DROP)
log_duration = off

# CSV формат для анализа инструментами
log_destination = 'csvlog'
logging_collector = on

# Ротация и управление местом
log_directory = '/var/log/postgresql'
log_rotation_age = 7d              # Храним неделю
log_rotation_size = 500MB
log_truncate_on_rotation = on

# Аудит безопасности
log_connections = on
log_disconnections = on
log_hostname = on

Анализ логов и полезные команды

После настройки логирования важно уметь анализировать полученные данные:

Просмотр логов в реальном времени

bash
# Просмотр логов в реальном времени
tail -f /var/log/postgresql/postgresql-*.log

# Просмотр только ошибок
grep -E "ERROR|FATAL|PANIC" /var/log/postgresql/postgresql-*.log

# Поиск медленных запросов (если log_min_duration_statement настроен)
grep "duration:" /var/log/postgresql/postgresql-*.log | sort -k2 -n

# Анализ CSV логов с помощью psql
psql -c "\copy postgres_log FROM '/var/log/postgresql/postgresql-2024-01-15.csv' WITH CSV;"
psql -c "SELECT * FROM postgres_log WHERE error_severity = 'ERROR';"

Полезные SQL запросы для анализа CSV логов

SQL
-- Топ-10 самых частых ошибок
SELECT error_severity, sql_state_code, message, COUNT(*) as count
FROM postgres_log 
WHERE error_severity IN ('ERROR', 'FATAL', 'PANIC')
GROUP BY error_severity, sql_state_code, message
ORDER BY count DESC
LIMIT 10;

-- Самые медленные запросы (если log_min_duration_statement настроен)
SELECT log_time, user_name, database_name, 
       CAST(duration AS NUMERIC) / 1000 as duration_sec,
       query
FROM postgres_log 
WHERE duration IS NOT NULL
ORDER BY duration DESC
LIMIT 20;

-- Статистика подключений по часам
SELECT EXTRACT(HOUR FROM log_time) as hour,
       COUNT(*) as connections
FROM postgres_log 
WHERE command_tag = 'connect'
GROUP BY hour
ORDER BY hour;

Интеграция с системами мониторинга

Для production-сред важно не только собирать логи, но и интегрировать их в общую систему мониторинга:

  • Prometheus + Grafana: Используй postgres_exporter для сбора метрик, а логи анализируй через Loki
  • ELK Stack (Elasticsearch, Logstash, Kibana): Классическое решение для централизованного логирования
  • Fluentd/Fluent Bit: Легковесные сборщики логов для отправки в различные системы
  • pgBadger: Специализированный анализатор логов PostgreSQL с детальными отчетами
bash - пример использования pgBadger
# Установка pgBadger
sudo apt-get install pgbadger  # для Debian/Ubuntu

# Генерация отчета из логов за последние 7 дней
pgbadger /var/log/postgresql/postgresql-*.log -o /var/www/html/pgbadger_report.html

# Анализ CSV логов
pgbadger --format csv /var/log/postgresql/postgresql-*.csv -o report.html

Частые вопросы (FAQ)

Почему логи не создаются после настройки?

Проверь следующее:

  • Убедись, что logging_collector = on
  • Проверь права на запись в log_directory
  • Выполни pg_ctl reload или перезапусти PostgreSQL
  • Проверь, не указан ли log_destination = 'syslog' (логи могут уходить в системный журнал)

Как ограничить рост логов на диске?

Используй комбинацию параметров:

log_rotation_age = 1d      # Ротация ежедневно
log_rotation_size = 100MB  # Или при достижении размера
log_truncate_on_rotation = on  # Перезаписывать старые логи
# Плюс настройка logrotate или cron для удаления старых файлов

В чем разница между log_statement и log_min_duration_statement?

log_statement логирует ВСЕ запросы определенного типа (ddl, mod, all), независимо от их длительности. log_min_duration_statement логирует только те запросы, выполнение которых превысило указанный порог (в миллисекундах). Для production рекомендуется использовать log_min_duration_statement вместо log_statement = 'all', чтобы избежать огромного объема логов.

Как логировать запросы только от определенного пользователя или базы?

Используй параметры в postgresql.conf с префиксом log_ в сочетании с ALTER ROLE или ALTER DATABASE:

-- Для конкретного пользователя
ALTER ROLE app_user SET log_min_duration_statement = 100;

-- Для конкретной базы данных
ALTER DATABASE app_db SET log_statement = 'mod';

-- Эти настройки переопределяют глобальные из postgresql.conf

Заключение

Правильная настройка логирования PostgreSQL — это не просто включение всех параметров, а тонкий баланс между:

  • Достаточной информативностью для отладки и аудита
  • Разумным объемом данных, которые нужно хранить и анализировать
  • Производительностью самой СУБД (логирование влияет на нее!)
  • Требованиями безопасности и compliance

Начни с базовой конфигурации из этой статьи, адаптируй под свои нужды и обязательно настрой мониторинг и алертинг на основе собранных логов. Помни: хорошие логи — это страховка от многих проблем в будущем.

Поделиться:
Сохранить гайд? В закладки браузера