apache2, virtualdocumentroot und Logfiles in verschiedene Files

Wieder mal ein spezifisches Problem:

Wer mit apache2 einfaches Massenhosting betreiben will, der will nicht für jeden Virtualhost einen VirtualHost-Container in seiner Apache Konfiguration anlegen, denn ab ca. 500 Domains als VHostContainer wird zum einen die Konfiguration sehr unübersichtlich und ausserdem wird der Indianer dadurch langsamer, aufgrund von vielen offenen Filehandles. Muss man ja auch nicht, schliesslich gibt es das vhost_alias Modul, mit welchem man ein VirtualDocumentRoot konfigurieren kann, dass dann das DocumentRoot anhand des übermittelten ServerName oder HTTP-Host Headers auswertet.

In der Apache Konfiguration sieht das dann z.B. so aus:

<VirtualHost *>
UseCanonicalName Off
Options Indexes Includes FollowSymLinks MultiViews
VirtualDocumentRoot /domains/%0/www
VirtualScriptAlias /domains/%0/cgi-bin/
CustomLog access_log vcommon
<Directory /domains/%0/www>
AllowOverride All
</Directory>
</VirtualHost>

Das Problem ist nun, dass alle Logs in ein einziges File “access_log” geloggt werden, und es schwierig ist, hier für die einzelnen gehosteten Domains Statistiken zu erzeugen etc.

Man kann nun aber um dieses Problem zu umgehen Folgendes tun:
Man erzeugt in /etc/apache2 ein Script welches die Ausgabe des Logfiles aufteilt und in mehrere Dateien speichert:


#!/usr/bin/php
<?php

$path = “/var/log/apache2”;
$fh_timeout = 30; // 30 sek.

$fd = fopen(“php://stdin”, “r”);

while(!feof($fd)) {

$row = fgets($fd);

list($vhost,$h,$l,$u,$t,$r,$s,$b,$referrer,$ua) = explode(“;”,$row,10);

if (!${$vhost}) { ${$vhost} = fopen($path.“/”.$vhost.“_access.log”,“a+”); }
$lastwrite[$vhost] = time();
fputs (${$vhost},“$h $l $u $t $r $s $b $referrer $ua”);

foreach ($lastwrite as $vhost => $time) {
if ((
time() – ($time+30)) >=0) {
fclose(${$vhost});
unset(${
$vhost});
unset(
$lastwrite[$vhost]);
}
}
}
?>

Nun müssen wir in der apache2 Konfiguration noch das Logformat ändern und die Ausgabe des Logfiles an unser Script durchpipen:

LogFormat "%V;%h;%l;%u;%t;\"%r\";%>s;%b;\"%{Referer}i\";\"%{User-agent}i\"" vcommon
CustomLog "|/etc/apache2/splitlogs.php" vcommon

Dann Apache einmal neu starten und künftig werden pro Host separate Logfiles erstellt.

Edit: Fast hätte ich es vergessen! Das Script braucht natuerlich eXecutable-Flag also am besten chmod 755 /etc/apache2/splitlogs.php ausführen!