In mod_php you can use the apache_note()
function to log variables in the Apache Access Log:
<?php
apache_note('SCRIPT_TIME', '1234');
?>
With the Apache config:
LogFormat "%h %l %u %t [%D/%{SCRIPT_TIME}n] \"%r\" %>s %b" inc_info
...
CustomLog /path/to/access_log inc_info
But the apache_note()
function is not available in PHP-FPM.
Likewise, you can't use apache_setenv()
or setenv()
to set environment variables (to be logged via %{SCRIPT_TIME}e
).
One possibility is to set a header that Apache can log with "%{SCRIPT_TIME}i", but you need to be careful to not let sensitive information be sent to the client (e.g. knowing accurate processing time for a login script can be a security issue). But more importantly, it does not work if content has already been sent to the client, as you can no longer send headers (as per the full example below).
Or, PHP could write it's own log file, but this would be duplicating a lot of what the Apache log already does, has the potential to miss log entries (e.g. if the script has an error), and will be created under the Apache user permissions (rather than being written to as root).
Just for more detail, this is the code I use to log the script processing time:
<?php
define('SCRIPT_START', microtime(true));
function log_shutdown() {
if (!defined('SCRIPT_END')) {
define('SCRIPT_END', number_format(round((microtime(true) - SCRIPT_START), 4), 4));
}
if (function_exists('apache_note')) {
apache_note('SCRIPT_TIME', SCRIPT_END);
}
}
register_shutdown_function('log_shutdown');
?>
And from a timing point of view, while Apache does provide "%D", to log "the time taken to serve the request", this is heavily dependent on the users internet connection.
This relates to me trying to enable HTTP/2 on my server, with the config:
Protocols h2 http/1.1
<FilesMatch \.php$>
CGIPassAuth on
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
SetHandler "proxy:fcgi://127.0.0.1:9001"
</FilesMatch>
Also related is the Nginx version