How to Split Apache Logs by Virtual Host?

Managing multiple websites on a single Apache server often results in a cluttered, single access log file that combines traffic from every domain. This article provides a straightforward guide on how to configure Apache to automatically separate access logs for each virtual host. We will cover the two primary methods: using the CustomLog directive directly within individual VirtualHost blocks, and using the LogFormat directive alongside the rotatelogs utility to split a combined log dynamically.

Method 1: The VirtualHost Directive Method

The most common and straightforward way to separate your logs is by defining a unique CustomLog path inside each specific <VirtualHost> configuration block. This tells Apache exactly where to send the traffic data for that specific domain.

  1. Open your Apache configuration file for the specific website (usually located in /etc/apache2/sites-available/ on Ubuntu/Debian or /etc/httpd/conf.d/ on CentOS/RHEL).
  2. Locate the <VirtualHost> block for your domain.
  3. Add or modify the CustomLog directive inside that block, specifying a unique filename.

Here is an example of how your configuration blocks should look:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example
    
    # Separate log for example.com
    ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>

<VirtualHost *:80>
    ServerName anothersite.org
    DocumentRoot /var/www/anothersite
    
    # Separate log for anothersite.org
    ErrorLog ${APACHE_LOG_DIR}/anothersite.org-error.log
    CustomLog ${APACHE_LOG_DIR}/anothersite.org-access.log combined
</VirtualHost>

After saving the files, test your configuration with apachectl configtest and restart Apache to apply the changes.

Method 2: The Conditional/Dynamic Log Method

If you manage dozens of virtual hosts and do not want to hardcode log paths for every single one, you can log everything to one master file but include the hostname in the log format. You can then use an environment variable or a piping script to split them automatically.

First, ensure your LogFormat includes the virtual host nickname (%v). Apache usually includes a pre-defined format for this called vhost_combined:

LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined

You can then pipe the global log through Apache’s built-in rotatelogs tool or a tool like split-logfile to automatically parse the %v prefix and generate separate files on the fly:

CustomLog "|/usr/bin/rotatelogs /var/log/apache2/vhost-logs/%Y-%m-%d-access.log" vhost_combined

Verification and Best Practices

Regardless of the method you choose, always verify that the Apache user (usually www-data or apache) has the correct write permissions for the directories where the new log files will be created. Additionally, remember to update your server’s log rotation configuration (such as logrotate) to ensure these new, individual log files are compressed and archived correctly over time, preventing your server’s hard drive from filling up.