At Hosting4Real we’ve been using Nginx in production as a reverse proxy for quite some time. But using Nginx doesn’t come without problems, one of them is bandwidth calculation. So this blog post will go over how to fix Nginx bandwidth issue in cPanel.
You’ll actually be facing multiple problems, about bandwidth reporting, this is due to the way you’ll usually run Nginx as a reverse proxy for Apache.
I wrote the blog post Nginx support for cPanel AWStats, this one will make sure at least AWStats logs can be processed as it should, another problem is that dynamic requests is sent to Apache, this means you need to make sure that both Apache and Nginx is writing to the same log files. This will make sure that all requests is logged so you’ll also be able to use the access logs afterwards.
All SSL traffic should be sent directly to Apache because this is the only easy way of making sure the certificates etc, work in cPanel, so also make sure you log all static/dynamic requests from apache if it’s served over SSL (This is as simple as using the _SSL access log files in cPanel).
The problems above, isn’t really needed to calculate the bandwidth used in cPanel, because cPanel use something called <domain>-bytes_log, it’s a very simple log file located in /usr/local/apache/domlogs/ the log format for these logs, is the unix timestamp, the amount of bytes, and a dot, an example is showed below:
1386282094 126780 . 1386282094 90184 . 1386282094 39168 . 1386282094 128587 . 1386282094 4816 .
Every 15 minutes or so, cPanel runs it’s internal bandwidth calculator, it’s a tool called cpanellogd, which is also the tool that handles the log processing in cpanel, both for bandwidth, webalizer, awstats etc.
The problem you’ll be facing if you run Nginx in front is, that cpanellogd will truncate the files after it copied it, this also means that the file descriptor(FD) will change.
Since Nginx is using file descriptors for all log files that it write to, we need to do a reload of Nginx to update the file descriptors so it can keep writing to the logs, else we won’t get any data written, resulting in domains don’t use any bandwidth.
So what we’re going to do, is to make sure we can reload Nginx, we can do this by opening nginx init script in /etc/init.d/nginx, and add another argument to the switch called reload:
reload) kill -USR1 `cat $PIDFILE` || echo "Could not reload" ;;
You might want to implement more checking like a config test, to actually make sure you only reload if the config passes the test, else your Nginx processes will just die.
After this parameter is implemented, we can reload Nginx, so it will update the file descriptors as well as getting new configuration if it changed. This saves us for a restart, which takes way longer.
Next step in the process is to make a hook in cPanel to reload Nginx when the bandwidth is processed. In cPanel there’s a pretty nice hook system, and we need to use the Stats::RunAll::post hook which you can find more information about right here.
Let’s create a folder, in /opt/ called reload_nginx:
mkdir -p /opt/reload_nginx/
Now let’s create a script in the above folder called ‘reload_nginx’ and put following content:
#!/bin/bash /etc/init.d/nginx reload
Now we just need to register the hook itself, in cPanel, so it will run every time the bandwidth statistics is updated.
#Make execute bit on the file chmod +x /opt/reload_nginx/reload_nginx #Add to the hook system /usr/local/cpanel/bin/manage_hooks add script \ /opt/reload_nginx/reload_nginx \ --stage post \ --category Stats \ --event RunAll \ --manual
The line above uses the manage_hooks binary in cPanel, adds a new script, with the location of /opt/reload_nginx/reload_nginx, we want to run the script after all logs has been processed, so we use the stage of post, the hook category is called Stats, and the event we hook into is called RunAll.
The –manual flag is added because we don’t have a ‘description’ section added to our bash script.
After this, bandwidth stats in cPanel should be real, because we don’t miss any data anymore.