Since you said you were on Apache, here are 2 ideas.
First idea (so-so idea, but interesting to think about ...):
Cookies are sent with each request to the server (including all images, etc.). When a user logs into a cookie with PHP and calls it USERTOKEN , then set its value to md5 + salt of this user ID.
Insert %{USERTOKEN}C and %B into the special LogFormat directive.
%{Foobar}C The contents of cookie Foobar in the request sent to the server. Only version 0 cookies are fully supported. %B Size of response in bytes, excluding HTTP headers.
Now you create your own log format, which looks like this:
LogFormat "%B %{USERTOKEN}C" php_bandwidth_log CustomLog "logs/php_bandwidth_log" php_bandwidth_log
Then you create a script to parse php_bandwidth_log and map it to the original user id.
Unfortunately, this idea is not reliable, since someone could still hypothetically access the content of the site without passing a cookie (possibly). In any case, depending on your situation, this may work for you, if not, an alternative and best idea is to basically route all the content using a PHP script so that you can make any entries you want on it.
Second idea (better):
So, create a PHP file that can be called like this /files.php?path=/blah/blah.jpg (simplified for this example, can be imposed by the mod_rewrite rule), and then inside it you can register this user ID and track access to files. It is assumed that you want to track files. This will not keep track of the HTML generated on the page - perhaps you can use the custom Apache registry idea mentioned earlier, but modify it a bit to get this information.
Here are some pseudo codes to help you understand:
if (!$hasSession) { die("Invalid session"); } $size = filesize($path); insert_into_bandwidth_table($userId, $size); header("Content-Type: ..."); readfile($path);
The following is an example of how you can only track the response size for executable PHP scripts, but it will only work if you use PHP as a module.
In PHP add something like this. This basically allows Apache to read this variable for logging purposes:
apache_note("PHP_USER_ID", 1234);
apache_note - apache_note - Get and set notes on apache request
Description: This function is a wrapper for Apache table_get and table_set. It edits the notes table that exists at the time of the request. The purpose of the table is to allow the communication of Apache modules.
More here
Then, in your httpd.conf protocol configuration, do something like this:
LogFormat "%B %{PHP_USER_ID}n" php_bandwidth_log CustomLog "logs/php_bandwidth_log" php_bandwidth_log
Information about the note from the documents:
%{Foobar}n The contents of note Foobar from another module.
And ... just realized that there is an alternative to apache_note if you are not using it as a module. Instead, your PHP code will do the following:
apache_setenv('PHP_USER_ID', $userId, TRUE);
Then, you must use this LogFormat directive to register:
LogFormat "%B %{PHP_USER_ID}e" php_bandwidth_log