Apache: Automatic log splitting per Virtual Host?
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 [email protected]" >> $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
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.
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.