Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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

4 Answers 4

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...

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

domain=$1.$2;

#echo $domain;
#exit 0


rm $domain.conf

echo "<VirtualHost *:80>" >> $domain.conf;
echo "        ServerAdmin no-reply@network.local" >> $domain.conf;
echo "        ServerName $1.network.local" >> $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" ];
        then
        rcapache2 restart;
fi

chmod 666 $domain.conf

cat $domain.conf
echo "Created!";

exit 0

Hope it helps.

-sean

share|improve this answer
    
Looks nice, I will try it out. I assume you have to run this script in /etc/httpd/conf.d/ ? –  Jakobud 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
2  
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

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

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

BEGIN {
        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!!!!
        LOGBASE="/var/log/httpd/access"

        SSL=""

        # Automagicly set first 
        SITE=tolower($1);
        PORT=$2

        if ($2 == 443)
        {
                SSL="-ssl"
        }

        # Extract all but first two fields (vhostname vhostport to be exactly) into LINE
        LINE=substr($0,index($0,$3));

        # 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;
                close(ap_rotatelog);
        }
        else
        {
                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 http://httpd.apache.org/docs/2.2/logs.html#virtualhost

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. –  Jakobud Aug 5 '11 at 19:36
1  
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 www.example.org works well enough. So does a a central syslog/Splunk server. –  Stefan Lasiewski Aug 5 '11 at 20:45

Your Answer

 
discard

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.