Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Whenever we create new Virtual Hosts on our dev servers, we always have to manually specify separate access and error logs:

ErrorLog logs/mysite/dev1-error.log
CustomLog logs/mysite/dev1-access.log "common"

Is there anyway to make Apache automatically split up the logs instead of having to specify them every time?

share|improve this question
up vote 3 down vote accepted

I feel your pain, as a web developer I have probably over 200 vhosts in my local dev - I personally don't care about the logs & log them all to the main /var/log/apache...

However what I did do was to write a shell script to add/manage all my vhosts - all you need to do is to tweak it to write logs to wherever you like...

if [ "$1"X = "X" ];
        echo "Must enter domain name"
        exit 0
if [ "$2"X = "X" ];
        echo "Must enter domain suffix"
        exit 0
if [ "$3"X = "X" ];
        echo "you must type "restart" if you want apache restarted "no" if not!"
        exit 0


#echo $domain;
#exit 0

rm $domain.conf

echo "<VirtualHost *:80>" >> $domain.conf;
echo "        ServerAdmin no-reply@network.local" >> $domain.conf;
echo "        ServerName $" >> $domain.conf;
echo "        DocumentRoot /Data/vhome/$1.$2/httpdocs" >> $domain.conf;
echo "        HostnameLookups Off" >> $domain.conf;
echo "        UseCanonicalName Off" >> $domain.conf;
echo "        ServerSignature On" >> $domain.conf;
echo "        ScriptAlias /cgi-bin/ "/Data/vhome/$1.$2/cgi-bin/"" >> $domain.conf;
echo "        ErrorLog /var/log/apache2/error_log" >> $domain.conf;
echo "        CustomLog /var/log/apache2/access_log combined" >> $domain.conf;
echo "    <Directory "/Data/vhome/$1.$2/cgi-bin">" >> $domain.conf;
echo "        AllowOverride All" >> $domain.conf;
echo "        Options +ExecCGI -Includes" >> $domain.conf;
echo "        Order allow,deny" >> $domain.conf;
echo "        Allow from all" >> $domain.conf;
echo "    </Directory>" >> $domain.conf;
echo "    <Directory "/Data/vhome/$1.$2/httpdocs">" >> $domain.conf;
echo "        Options Indexes FollowSymLinks" >> $domain.conf;
echo "        AllowOverride All" >> $domain.conf;
echo "        Order allow,deny" >> $domain.conf;
echo "        Allow from all" >> $domain.conf;
echo "    </Directory>" >> $domain.conf;
echo "       # #XSS prevention" >> $domain.conf;
echo "       # RewriteEngine On" >> $domain.conf;
echo "       # RewriteCond %(REQUEST_METHOD) ^TRACE" >> $domain.conf;
echo "       # RewriteRule .* -[F]" >> $domain.conf;
echo "</VirtualHost>" >> $domain.conf;

if [ "$3" = "restart" ];
        rcapache2 restart;

chmod 666 $domain.conf

cat $domain.conf
echo "Created!";

exit 0

Hope it helps.


share|improve this answer
Looks nice, I will try it out. I assume you have to run this script in /etc/httpd/conf.d/ ? – Jake Wilson Aug 5 '11 at 17:06
no I have it in my /etc/apache/vhosts/ - if you move it, just change your paths, or possibly add a path parameter pointing to the apache includes directory... If you wanted to get it real sexy, you could also have it create the virtual host directory structure & jack a cname into your nameserver configs.... – Sean Kimball Aug 5 '11 at 17:28
You could clean that up using a big here document. Variable expansions are still processed inside. – MikeyB Aug 5 '11 at 18:39
+1 for MikeyB, those hundred echos hurt my eyes :-P – hmontoliu Aug 5 '11 at 19:32

Back when I still used apache, I learned a trick from a coworker. He piped the global access log through an awk script. The awk script in turn would then take care creating the different logfiles.

In httpd.conf:

LogFormat "%V %p %a %l %u %t \"%r\" %s %b \"%200{Referer}i\" \"%200{User-agent}i\" \"%{cookie}n\"" awklogpipe
CustomLog "|/usr/local/bin/apacheawklogpipe" awklogpipe env=!dontlog

The script /usr/local/bin/apacheawklogpipe:

#!/bin/gawk -f

        months["Jan"] = "01";
        months["Feb"] = "02";
        months["Mar"] = "03";
        months["Apr"] = "04";
        months["May"] = "05";
        months["Jun"] = "06";
        months["Jul"] = "07";
        months["Aug"] = "08";
        months["Sep"] = "09";
        months["Oct"] = "10";
        months["Nov"] = "11";
        months["Dec"] = "12";

        # HEADS UP: SET THIS!!!!


        # Automagicly set first 

        if ($2 == 443)

        # Extract all but first two fields (vhostname vhostport to be exactly) into LINE

        # No matter where it is, we will find an apache datestamp.
        match(LINE,/\[[0-9]+\/[A-Z][a-z]+\/[0-9]+:[0-9]+:[0-9]+:[0-9]+[\t ]+[+-][0-9]+\]/);
        split(substr(LINE,RSTART + 1,RLENGTH - 2), ap_log_time, /[\/: ]/);

        #ap_rotatelog= LOGBASE "/" SITE ":" PORT "/access-log" SSL "-" ap_log_time[3] "-" months[ap_log_time[2]] ap_log_time[1];
        ap_rotatelog= LOGBASE "/" SITE  "/access_log" SSL;
        if (system("test -d " LOGBASE "/" SITE ) == 0)
                print LINE >> ap_rotatelog;
                print SITE "\t" SSL "\t" LINE >> LOGBASE "/w3logrotate-error.log";
                close(LOGBASE "/w3logrotate-error.log");

Make sure /usr/local/bin/apacheawklogpipe is executable. All you would need to take care of with this script, is create a directory in /var/log/httpd/access that corresponds to the virtualhostname. I had a script that would create a virtualhost config and create the log directories.

share|improve this answer
You also can use split-logfile (it can be found in support folder when compiling from source) or vlogger to do this. – quanta Aug 5 '11 at 17:14
very nice solution.... – Sean Kimball Aug 5 '11 at 17:25

Another options. Don't split them in httpd.conf. Instead, log everything to your main Access Log, and then split them later with a program like split-logfile. This helps to simplify your log configuration.

This is described at

By adding information on the virtual host to the log format string, it is possible to log all hosts to the same log, and later split the log into individual files. For example, consider the following directives.

LogFormat "%v %l %u %t \"%r\" %>s %b" comonvhost CustomLog
logs/access_log comonvhost

The %v is used to log the name of the virtual host that is serving the request. Then a program like split-logfile can be used to post-process the access log in order to split it into one file per virtual host.

share|improve this answer
That sounds like a nightmare. If I have 30 active sites and I want to look through the log for a single site I have to either sift through a HUGE log file or split it out everytime? Not to mention running a tail -f would suck horribly... No thanks. – Jake Wilson Aug 5 '11 at 19:36
To each his own. I wouldn't want 2x30 logfiles sitting around, and this works well with Simple dynamic virtual hosts. The idea here is to handle log processing afterwards. tail -f access_log | grep works well enough. So does a a central syslog/Splunk server. – Stefan Lasiewski Aug 5 '11 at 20:45

Maybe have a look at mod_macro. This has a more general approach, but I guess that this could help you otherwise as well.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.