php-fpm не сохраняет журналы ошибок для пула

Вопрос или проблема

Я использую php-fpm с Caddy, и не могу заставить php-fpm регистрировать ошибки. Ранее я использовал nginx, и nginx довольно хорошо захватывает и отображает ошибки php в своих же логах, поэтому у меня никогда не было проблем, но с caddy я решил включить журнал ошибок php-fpm, и он просто… не работает. Но давайте начнем с начала:

ОС: Ubuntu 22.04.1

Приложение: Symfony 7.1 с monolog (упоминаю это на случай, если он останавливает распространение ошибок или что-то в этом роде)

Конфигурация Caddy v2.8.4:

[REDACTED] {
  tls [REDACTED]
  root * [REDACTED]
  file_server
  php_fastcgi unix//var/run/php/php8.3-fpm.sock
  log {
    output file /var/log/caddy/[REDACTED].log
    level ERROR
  }

Конфигурация пула php-fpm 8.3.12:


listen = /var/run/php/php8.3-fpm.sock

listen.owner = [REDACTED]
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
user = [REDACTED]
group = www-data
php_value[memory_limit] = 8G
catch_workers_output = yes
php_flag[display_errors] = on
php_admin_value[error_log] = /var/log/php-fpm/[REDACTED].log
php_admin_flag[log_errors] = on

Основной журнал php-fpm работает нормально, но он в основном содержит информацию о перезапусках службы, поэтому он не очень полезен. Журнал, принадлежащий пулу, не сохраняется.

Что я сделал:

  • Я убедился, что права доступа и владельцы файлов журнала установлены правильно. Файл журнала существует. Я touchнул его и скопировал пути, чтобы избежать опечаток. Директория /var/log/php-fpm имеет права 777, как и файл журнала. Это временно, чтобы исключить возможность проблем с правами.
  • Я вижу в phpinfo, что значения, установленные в конфигурации пула, вступают в силу.
  • Я перезагрузил все.
  • Когда я посещаю страницу, возвращающую ошибку 500, никаких логов не сохраняется. Файл журнала всегда пустой.

введите описание изображения сюда

Есть ли что-то еще, что я пропустил? Есть ли у кого-то идея, на что я мог бы посмотреть, чтобы разобраться в этом?

Я разобрался. Чтобы отладить это, я внедрил синтаксическую ошибку в файл index.php. Я сделал это, чтобы исключить возможность вмешательства Symfony, и вот, ошибка была зафиксирована. Это указало на то, что это Symfony, который использует свой собственный обработчик ошибок.

В основном, в dev среде все ошибки регистрируются в файле [корень проекта]/var/logs/dev.log, в соответствии с конфигурацией по умолчанию monolog:

when@dev:
    monolog:
        handlers:
            main:
                type: stream
                path: "%kernel.logs_dir%/%kernel.environment%.log"
                level: debug
                channels: ["!event"]
            # раскомментируйте, чтобы получить журнал в вашем браузере
            # возможно, вам придется разрешить большие размеры заголовков в конфигурации вашего веб-сервера
            #firephp:
            #    type: firephp
            #    level: info
            #chromephp:
            #    type: chromephp
            #    level: info
            console:
                type: console
                process_psr_3_messages: false
                channels: ["!event", "!doctrine", "!console"]

Однако в prod среде логи отправляются в stderr:

when@prod:
    monolog:
        handlers:
            main:
                type: fingers_crossed
                action_level: error
                handler: nested
                excluded_http_codes: [404, 405]
                buffer_size: 50 # Сколько сообщений должно быть сохранено? Предотвратить утечки памяти
            nested:
                type: stream
                path: php://stderr
                level: debug
                formatter: monolog.formatter.json
            console:
                type: console
                process_psr_3_messages: false
                channels: ["!event", "!doctrine"]
            deprecation:
                type: stream
                channels: [deprecation]
                path: php://stderr
                formatter: monolog.formatter.json

Так что да, Symfony в основном сам обрабатывает ошибки, поэтому php-fpm их не регистрирует.

Вот пост автора Symfony о том, почему рекомендуется регистрировать в stderr: https://symfony.com/blog/logging-in-symfony-and-the-cloud

Ответ или решение

Почему php-fpm не сохраняет логи ошибок для пула: Причины и решения

Использование php-fpm в сочетании с Caddy может вызывать трудности в настройке логирования ошибок. При переходе от nginx, который хорошо обрабатывает и отображает ошибки PHP в собственных логах, создание аналогичной конфигурации в Caddy может привести к моральной дилемме, когда ошибки PHP не сохраняются в ожидаемом формате. Рассмотрим подробнее возможные причины и решения данной проблемы.

1. Конфигурация php-fpm

Прежде всего, важно убедиться, что параметры конфигурации вашего пула в php-fpm настроены корректно:

  • catch_workers_output установлен в yes, что позволяет поглощать вывод ошибок рабочими процессами PHP.
  • Параметры php_admin_value[error_log] и php_admin_flag[log_errors] установлены, что указывает php-fpm на необходимость ведения журнала ошибок. В вашем случае путь к логам /var/log/php-fpm/[REDACTED].log задан корректно и лог-файл существует с нужными правами.

Однако, несмотря на все ваши настройки, если php-fpm не записывает ошибки в указанный лог, необходимо обратить внимание на несколько дополнительных аспектов конфигурации вашей среды.

2. Особенности Symfony и Monolog

Данная проблема была разрешена благодаря пониманию, как Symfony обрабатывает ошибки с помощью компонента Monolog. В среде разработки (dev) все ошибки записываются в файл dev.log, расположенный в каталоге логов вашего проекта. В производственной среде (prod) ошибки перенаправляются в stderr, что является частью конфигурации Monolog.

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

when@prod:
    monolog:
        handlers:
            main:
                type: stream
                path: "%kernel.logs_dir%/%kernel.environment%.log"
                level: debug

Это поможет вам отправить все логи PHP в желаемый файл.

3. Проблемы с правами доступа

Несмотря на то, что вы указали, что права доступа к директории и файлу логов настроены корректно (до 777), стоит помнить, что такие права могут представлять собой потенциальную угрозу безопасности. Убедитесь, что пользователь, от имени которого запускается процесс php-fpm, имеет необходимый доступ к директории и файлу логов.

4. Проверка конфигурации Caddy

Убедитесь, что конфигурация сервера Caddy правильно маршрутизирует запросы к php-fpm. Проверьте, что вы используете корректные директивы, такие как php_fastcgi, для обработки запросов PHP.

5. Рекомендуемые практики

Для лучшего управления логами и обеспечения производительности:

  • Освойте альтернативные методы управления логированием через Monolog, которые могут удовлетворить ваши требования в зависимости от среды.
  • Рассмотрите интеграцию системы мониторинга (например, ELK, Papertrail), которая может помочь в управлении и анализе логов, а также ведении их в реальном времени.

Заключение

Как видно из анализа, причина отсутствия логов ошибок в php-fpm может быть связана не только с настройками самого php-fpm, но и с поведением Symfony. Обновление конфигурации Monolog для логирования ошибок в файл вместо stderr решит проблему, сохраняя все ошибки, которые происходят во время выполнения приложения. Следование рекомендациям по правам доступа и проверка конфигурации Caddy могут значительно улучшить ваш рабочий процесс и предотвратить аналогичные проблемы в будущем.

Оцените материал
Добавить комментарий

Капча загружается...