Awstats Auswertung multipler Vhosts und Alias- und Subdomains

Dieses Thema im Forum "Tipps - Tricks - Mods" wurde erstellt von mattula, 24. Apr. 2013.

  1. mattula

    mattula Member

    Hallo zusammen,

    ich beschreibe hier, wie ich folgende Anforderung gelöst habe:


    1. Awstats Auswertung je Domain, auch wenn die Domains alle unter einem Vhost laufen (wie es z.B. bei Typo3 üblich ist)
    2. Auswertung der Logdateien mehrerer identischer Webserver (ISPConfig Mirror Setup), die hinter einem Loadbalancer stehen
    3. Kein Eingriff in das ISPConfig System, der z.B. durch ein Update zerstört werden könnte
    4. Integration in ISPConfig dahgingehend, dass für neu angelegte Websites automatisch auch die passenden Statistiken erstellt werden.
    5. Auswertung soll auch mehrfach täglich möglich sein.
    6. Automatische Komprimierung der Logfiles nach Auswertung
    7. Möglichkeit der Mandantenfähigkeit beim Zugriff auf die Statistiken
    8. Ein zentraler Statistik Webhost


    OK, erstmal ein kurzer Überblick zur Umsetzung:



    Setup:
    1x ISPConfig Controlpanel Server (ispcfg.foo.bar)
    2x ISPConfig Webserver (Mirror Setup) angebunden an ispcfg.foo.bar
    2x ISPConfig DB-Cluster (Heartbeat/DRBD) angebunden an ispcfg.foo.bar
    1x ISPConfig Webserver (stats.foo.bar) angebunden an ispcfg.foo.bar

    Anmerkung: Das Ganze funktioniert auch mit einem einzigen ISPConfig Server, der alles macht.

    Die einzelnen ISPConfig Webhosts leiten ein CustomLog (parallel zur vlogger Config) an den lokalen logger.

    Der logger schickt es an den lokalen Syslog Server (in dem Fall rsyslogd).
    Der rsyslogd schickt es an den zur Auswertung auserkorenen zentralen Webhost (in meinem Fall auch ein Host im ISPConfig Verbund - der oben zuletzt genannte.)

    Auf dem zentralen Host, nennen wir ihn stats.foo.bar empfängt der rsyslog die Apache Logs der anderen Webserver inkl. seines eigenen.
    Der rsyslogd schreibt die Logs in ein Verzeichnis je Vhost.

    Die Website stats.foo.bar ist ein per ISPConfig ganz normal angelegter Vhost.

    Ein stark modifiziertes cron_daily.php (aus der ISPConfig Distri) befragt die ISPConfig Master-DB nach allen vorhandenen Vhosts, Sub- und Aliasdomains und wertet darauf basierend die gesammelten Logfiles aus.

    Die fertigen Statistiken werden dann in die Document Root von stats.foo.bar geschrieben und dort nach Vhost Hauptdomain separiert in Unterverzeichnissen abgelegt.

    Falls nicht vorhanden, wird sicherheitshalber ein htaccess Schutz auf das stats Verzeichnis gelegt, welches unter http://stats.foo.bar/sites erreichbar ist. Als Authentifikation wird einfach auf das htpasswd File verwiesen, welches sich in der statistics Config der Website stats.foo.bar per ISPConfig mit Passwort versehen lässt.

    Diese htaccess kann natürlich ersetzt werden. Die Unterverzeichnisse können separat geschützt werden, ... Das ist die gewünschte Mandantenfähigkeit. :)



    Kommen wir zu den verschiedenen Konfigurationen


    Erstmal die Log Config für Apache.


    Es wird z.B. folgende Datei erstellt und nach /etc/apache2/sites-available/ verlinkt:

    /etc/apache2/sites-available/custom-ispconfig.conf
    Code:
    #########################################################
    # Custom ISPConfig Logfile configuration for remote logging
    #########################################################
    
    LogFormat "%v %{Host}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined_custom_ispconfig
    CustomLog "| /usr/bin/logger -p local0.info -t apache2" combined_custom_ispconfig
    
    Auf diese Art und Weise wird das Logging einfach parallel zur ISPconfig Methode per vlogger rausgeleitet. D.h. die ISPConfig eigene Logverwaltung und Auswertung wird nicht tangiert.


    Die lokale rsyslog Config

    /etc/rsyslog.d/apache2-remote.conf
    Code:
    # remote logging
    
    if $syslogfacility-text == 'local0' and ( $syslogtag contains_i 'apache2' ) then @stats.foo.bar
    
    # don't write to other logfiles
    if $syslogfacility-text == 'local0' and ( $syslogtag contains_i 'apache2' ) then ~
    
    Es wird alles erstmal an den zentralen Host weitergeleitet. Ich empfehle allerdings die IP statt des Namens einzutragen.


    Das war's dann schon mit der Konfiguration auf dem oder den Webhosts.


    rsyslog Konfig auf dem zentralen Sammler


    Remote Logging einschalten nicht vergessen.


    /etc/rsyslog.d/apache2-local.conf
    Code:
    # Apache2 Log reception
    
    # strip the first space from message
    $template Message,"%msg:2:$%\n"
    
    # Field 2 = Apache LogFormat: %v = The canonical ServerName of the server serving the request
    # Field 3 = Apache LogFormat: %{Host}i = The content of Host: header in the request sent to the server.
    $template ApacheAccessLogFile,"/var/log/custom-ispconfig/httpd/%msg:F,32:2%/%$YEAR%%$MONTH%%$DAY%-access.log"
    
    
    if $syslogfacility-text == 'local0' and ( $syslogtag contains_i 'apache2' ) then -?ApacheAccessLogFile;Message
    
    # don't write to other logfiles
    if $syslogfacility-text == 'local0' and ( $syslogtag contains_i 'apache2' ) then ~
    
    Hier verwenden wir ein wenig rsyslog magic und schreiben die empfangenen Apache Logdaten in jeweils ein Unterverzeichnis je Vhost.


    Dann benötigen wir noch eine eigene Awstats Config:


    /etc/custom-ispconfig/awstats/awstats.conf.override

    Code:
    
    LogFormat = "%other %virtualname %host %other %logname %time1 %methodurl %code %bytesd %refererquot %uaquot"
    LoadPlugin="geoip GEOIP_STANDARD /usr/share/GeoIP/GeoIP.dat"
    DirData="/var/lib/custom-ispconfig/awstats"
    
    Nicht vergessen, auch das Verzeichnis /var/lib/custom-ispconfig/awstats zu erstellen.


    Auch hier ist wieder das Ziel erreicht, keine Konflikte mit der ISPConfig Logauswertung zu bekommen.


    Im Prinzip war es das nun fast schon. Jetzt fehlt nur noch das Auswerte Script. Dafpür habe ich /usr/local/ispconfig/server/cron_daily.php als Grundlage verwendet.


    Es heisst bei mir custom-ispconfig-awstats.php und befindet sich im Anhang. Von diesem Script wird noch eine Datei benötigt: /etc/custom-ispconfig/templates/awstats_index_subdir.php.master
    Diese befindet sich ebenfalls im Anhang im ZIP File custom-ispconfig-awstats.zip


    Das PHP-Script wird dann per Cron, wie das cron_daily.php von einem Shell Script aufgerufen. Ich habe nur noch einen Lock Mechanismus eingebaut, so dass sich das Script bei zu häufigem Aufruf nicht gegenseitig überholt:

    /usr/local/custom-ispconfig-extras/server/custom-ispconfig-awstats.sh

    Code:
    #!/bin/sh
    #
    # $Rev:: 00            $:  Revision of last commit
    # $Author:: mw         $:  Author of last commit
    # $Date:: 2013-04-18 1#$:  Date of last commit
    
    
    PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin
    
    DEBUG=false
    
    MY=`basename $0`
    LOCK_FILE=/var/lock/$MY.lck
    PROC_PID=/var/run/$MY.pid
    
    # needed for debug loggig
    hostname=`hostname`
    logname=$LOGNAME
    
    
    # If pidfile exists exit
    if [ -e $PROC_PID ]; then
      echo
      echo "$MY[$$] Former process pid $(cat $PROC_PID) exits ... exiting."
      echo
      logger -t "$MY[$$]" "Former process pid $(cat $PROC_PID) exits ... exiting."
      exit 1
    fi
    
    logger -t "$MY[$$]" "Doing my job."
    
    # Write pidfile
    echo -n "$$" > $PROC_PID
    
    func_exit() {
    rm -f $PROC_PID && logger -t "$MY[$$]" "[ERROR] Unexpected exit."
    }
    
    func_exit_normal() {
    rm -f $PROC_PID && logger -t "$MY[$$]" "Removed pidfile."
    }
    
    
    trap func_exit EXIT
    
    if [ -f /usr/local/ispconfig/server/lib/php.ini ]; then
            PHPINIOWNER=`stat -c %U /usr/local/ispconfig/server/lib/php.ini`
            if [ $PHPINIOWNER == 'root' ] || [ $PHPINIOWNER == 'ispconfig'  ]; then
                    export PHPRC=/usr/local/ispconfig/server/lib
            fi
    fi
    
    /usr/bin/php -q /usr/local/custom-ispconfig-extras/server/custom-ispconfig-awstats.php
    
    logger -t "$MY[$$]" "Did it."
    
    trap func_exit_normal EXIT
    exit 0
    
    In der ISPConfig der Website stats.foo.bar habe ich noch folgende Apache Directive eingebunden, damit sich durch die Statistikverzeichnisse browsen lässt:



    Code:
    <Directory /var/www/stats.foo.bar/web/sites>
        Options +Indexes
        HeaderName /include/HEADER.html
        IndexIgnore ..
        IndexOptions +FancyIndexing
        IndexOptions +HTMLTable
        IndexOptions +SuppressDescription
        IndexOptions +SuppressSize
        IndexOptions +SuppressIcon
        IndexOptions +SuppressRules
        IndexOptions +SuppressHTMLPreamble
        Order allow,deny
        AllowOverride All
        Allow from all
    </Directory>
    
    Ich hoffe, meine Erklärungen waren ausreichend. Der Gag an der ganzen Sache ist ja eigentlich nur die Ausleitung der Apache Logs an einen zentralen Loghost, ohne mit ISPConfig irgendwo in Konflikt zu geraten. Der Rest ist individuell handhabbar. Z.B. müssen die Statistiken nicht auf einem ISPConfig Server ausgewertet werden. Es muss auch nicht unbedingt die ISPConfig DB befragt werden. Es wäre ebenso denkbar einfach nur die Logs basierend auf ihrem Inhalt auszuwerten, ...


    Es kann auch alles auf einem Host stattfinden. Dann ist nur die zweite rsyslogd Config zu verwenden.


    Anmerkungen:

    Was noch fehlt in meinem Setup, ist eine Löschung alter Apache Logs. Bis Dato werden die Logfiles nur durch das PHP Script komprimiert nach erfolgter Auswertung. Die Rotation erfolgt ja durch die rsyslog Konfig sowieso täglich.


    Die User können nachwievor im ISPconfig wahlweise awstats oder webalizer als Statistik auswählen. Diese Statistiken landen wie gehabt unter vhost/stats. Die Generierung der zentralen Awstats läuft vollkommen unabhängig immer für alle Vhosts. Das lässt sich im PHP-Script anpassen.


    Matthias
     

    Anhänge:

  2. nowayback

    nowayback Well-Known Member

    hi,

    auch wenn ich es nicht brauche: Danke

    das sieht sehr gut aus.

    Grüße
    nwb
     

Diese Seite empfehlen