php_admin_value or php_flag directives within the virtual host configuration or the global php.ini. If logs are missing, check that the paths for error_log, log_errors, and access_log are correctly defined and writable by the web server user.
Understanding the Logging Architecture
To troubleshoot logging effectively, you must understand how Apache and PHP-FPM interact. Apache handles the initial HTTP request and passes it to PHP-FPM via a FastCGI socket or TCP connection. PHP-FPM then executes the script and returns the response. Errors occurring during this execution are handled by the PHP engine, not Apache directly. Therefore, standard Apache error logs (/var/log/apache2/error.log) will often show only generic "Internal Server Error" messages if PHP itself encounters a fatal error. The detailed stack trace or syntax error message resides within the PHP-specific log files. This separation means that configuring logging requires changes in two distinct layers: the web server configuration and the PHP runtime configuration.
Locating PHP-FPM Logs via Configuration
The most common reason for missing logs is that the default configuration does not write to a persistent file, or the path is incorrect. You need to inspect your PHP configuration files to determine where errors are being sent. In many distributions, the main configuration file is located at/etc/php/<version>/fpm/php.ini. Open this file and search for the following directives:
error_log = /var/log/php-fpm/error.log
log_errors = On
error_reporting = E_ALL
If error_log is commented out or set to syslog, errors may be going to the system logger rather than a readable file. Ensure that log_errors is set to On. If you are using a shared hosting environment or a specific framework like Laravel, these settings might be overridden in the .htaccess file or within the Apache virtual host configuration using php_admin_value. For example, you might find a directive like php_admin_value error_log /var/www/html/storage/logs/laravel.log. Always verify which configuration file is actually being loaded by creating a phpinfo() page or running php -i | grep error_log from the command line.
Checking Apache Virtual Host Settings
Sometimes, the issue lies with how Apache is configured to handle PHP requests. If you are using an<IfModule mod_proxy_fcgi.c> block, ensure that the logging directives are placed correctly. Apache’s own access and error logs can sometimes capture PHP errors if they occur before the request reaches PHP-FPM, such as during URL rewriting. Check your virtual host file (often found in /etc/apache2/sites-available/) for ErrorLog and CustomLog directives. While these do not capture PHP internal errors, they help diagnose if the request is even reaching the PHP handler. If you see 500 errors in the Apache log but no corresponding PHP log entry, the problem likely lies in the PHP-FPM pool configuration or permissions rather than the routing.
Verifying File Permissions and Ownership
Even if the configuration points to the correct file, PHP-FPM will fail silently if it lacks permission to write to that location. The PHP-FPM worker processes run under a specific user, typicallywww-data on Debian-based systems or apache on Red Hat-based systems. You must ensure that the directory containing the log file has write permissions for this user. Use the following commands to fix ownership and permissions:
sudo chown www-data:www-data /var/log/php-fpm
sudo chmod 750 /var/log/php-fpm
If the log file already exists, ensure it is also owned by the correct user. A common mistake is creating the log file as root and then restarting PHP-FPM, resulting in permission denied errors that go unnoticed because the service appears to start successfully. Additionally, check the SELinux status if you are on CentOS or RHEL. SELinux can block PHP-FPM from writing to non-standard directories. Use audit2allow to generate a policy if you suspect security contexts are preventing writes.
Debugging Steps When Logs Are Still Missing
If you have verified the configuration and permissions but still see no logs, follow these diagnostic steps. First, restart both Apache and PHP-FPM to ensure configurations are reloaded. Second, enable display errors temporarily in a development environment by settingdisplay_errors = On in php.ini. This will print errors directly to the browser, confirming that PHP is executing. Third, check the PHP-FPM pool status page. If enabled, accessing http://localhost/status can provide insights into whether the pool is processing requests. Finally, look at the system journal using journalctl -u php-fpm or systemctl status php-fpm to see if there are startup errors or crashes that prevent logging entirely.
Fixing Apache PHP Project: Large Post Requests (40MB) with 500 Internal Error provides context on handling broader Apache-PHP integration issues that may also affect logging behavior.
Frequently Asked Questions
Why are PHP errors showing in Apache logs instead of PHP logs?
This usually happens when the error occurs before PHP-FPM takes over, such as during URL rewriting or module loading. It can also occur if display_errors is enabled and errors are printed to the output buffer which Apache captures.
How do I find the exact php.ini file being used?
Create a file named info.php containing <?php phpinfo(); ?> and access it via your browser. Look for the "Loaded Configuration File" row to identify the active php.ini path.
Can PHP-FPM logs be rotated automatically?
Yes, you should use logrotate to manage log files. Create a configuration file in /etc/logrotate.d/php-fpm to specify rotation frequency, compression, and size limits to prevent disk space exhaustion.
What if my PHP-FPM process crashes immediately after starting?
If the process crashes, it may not have time to write to its error log. Check the system journal (journalctl -u php-fpm) for crash reports and ensure that the user specified in the pool configuration has valid shell access and home directory permissions.
Is it safe to leave display_errors enabled in production?
No, leaving display_errors enabled in production exposes sensitive information about your code structure and database connections to users. Always disable it and rely on file-based logging for debugging in live environments.