Monitoring Bandwidth Usage per Virtual Host in Apache: Tools and Techniques


1 views

When managing multiple websites on a single Apache server through virtual hosts, tracking individual bandwidth consumption becomes crucial for:

  • Performance optimization
  • Traffic pattern analysis
  • Resource allocation decisions
  • Anomaly detection (DDoS, hotlinking)

Apache doesn't provide per-virtual-host bandwidth metrics out of the box, but we can leverage its logging system:

# In httpd.conf or virtual host configuration
LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_combined
CustomLog logs/vhost_access.log vhost_combined

This creates a log file where %v represents the virtual host name and %b shows bytes transferred.

AWStats can parse Apache logs to generate detailed reports:

# Install AWStats
sudo apt-get install awstats

# Configure for virtual hosts
LogFile="/var/log/apache2/vhost_access.log"
SiteDomain="example.com"
HostAliases="www.example.com"
Include "awstats.vhost.conf"

While not providing historical data, mod_status gives current traffic insights:

<Location /server-status>
    SetHandler server-status
    Require host example.com
</Location>

ExtendedStatus On

GoAccess processes logs in real-time with visual output:

# Installation
wget https://tar.goaccess.io/goaccess-1.4.tar.gz
tar -xzvf goaccess-1.4.tar.gz
cd goaccess-1.4/
./configure --enable-utf8 --enable-geoip=legacy
make
sudo make install

# Usage with virtual host logs
goaccess /var/log/apache2/vhost_access.log --log-format=VCOMBINED

For developers needing precise control, consider mod_accounting:

# Compile and install
git clone https://github.com/yoanm/mod_accounting.git
cd mod_accounting
apxs -i -a -c mod_accounting.c

# Configuration
<VirtualHost *:80>
    AccountingDB /var/log/apache2/accounting.db
    AccountingDBDriver sqlite3
    ServerName example.com
    # ... other directives
</VirtualHost>

For enterprise environments, consider logging to SQL:

# Using mod_log_sql
LogFormat "%v %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" sqlcombined
CustomLog "|/usr/bin/logscheduler.pl" sqlcombined

When running multiple websites on a single Apache server through virtual hosts, administrators often need granular visibility into resource consumption. While overall server bandwidth metrics are readily available, tracking usage per virtual host requires specific configuration or additional tools.

Apache's mod_logio module provides the most straightforward method for tracking bandwidth at the virtual host level:

<VirtualHost *:80>
    ServerName example.com
    CustomLog logs/example.com-access.log combined
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    TransferLog logs/example.com-transfer.log
</VirtualHost>

The %b parameter in the log format records the response size in bytes. You can then process these logs using tools like awstats or goaccess to generate bandwidth reports.

For more comprehensive solutions, consider these specialized tools:

1. GoAccess (Real-time Analysis)

goaccess /var/log/apache2/example.com-access.log --log-format=COMBINED

2. AWStats (Historical Reporting)

# Sample AWStats configuration for virtual host
LogFile="/var/log/apache2/example.com-access.log"
SiteDomain="example.com"
HostAliases="www.example.com"

For developers preferring a custom approach, this Python script parses Apache logs:

#!/usr/bin/env python3
import re
from collections import defaultdict

def analyze_vhost_bandwidth(logfile):
    bandwidth = defaultdict(int)
    pattern = r'^.*\"(GET|POST).*\" (\d+) (\d+)'
    
    with open(logfile) as f:
        for line in f:
            match = re.search(pattern, line)
            if match:
                status, size = match.groups()[1:]
                if status == '200':
                    bandwidth['total'] += int(size)
    
    return bandwidth

print(analyze_vhost_bandwidth('/var/log/apache2/example.com-access.log'))

For large-scale deployments, consider logging to a database:

# MySQL logging configuration
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" mysql
CustomLog "|/usr/bin/mysql --user=logger --password=xxx apache_logs --execute=\"INSERT INTO access_log VALUES (NULL, '%h', '%l', '%u', '%t', '%r', '%>s', '%b', '%{Referer}i', '%{User-Agent}i');\"" mysql

For AWS users, CloudWatch can monitor per-host metrics when properly configured with Application Load Balancers and appropriate logging.