AWStats (XI)
Installation
_$: apt-get install libfcgi-perl
_$: wget http://nginxlibrary.com/downloads/perl-fcgi/fastcgi-wrapper -O /usr/bin/fastcgi-wrapper.pl
_$: wget http://nginxlibrary.com/downloads/perl-fcgi/perl-fcgi -O /etc/init.d/perl-fcgi
_$: chmod +x /usr/bin/fastcgi-wrapper.pl
_$: chmod +x /etc/init.d/perl-fcgi
_$: update-rc.d perl-fcgi defaults 99 00
_$: service perl-fcgi start
_$: netstat -naptu | grep perl
tcp 0 0 127.0.0.1:8999 0.0.0.0:* LISTEN 2569/perl
Update to a more recent version
Installation directories in Ubuntu 12.04:
- /usr/local/awstats
- /usr/share/awstats
_$: mkdir -p apps
_$: cd apps
_$: wget https://prdownloads.sourceforge.net/awstats/awstats-7.5.tar.gz
_$: tar xvfz awstats-7.5.tar.gz
_$: cd awstats-7.5
_$: find . -name "awstats.pl"
./wwwroot/cgi-bin/awstats.pl
_$: find . -name "awstats_buildstaticpages.pl"
./tools/awstats_buildstaticpages.pl
_$: find . -name "maillogconvert.pl"
./tools/maillogconvert.pl
_$: find . -name "logresolvemerge.pl"
./tools/logresolvemerge.pl
Make a back up of the files currently installed:
_$: mv /usr/lib/cgi-bin/awstats{.pl,.pl.bak}
_$: mv /usr/lib/cgi-bin/awstats_buildstaticpages{.pl,.pl.bak}
_$: for file in "awstats_configure.pl awstats_exportlib.pl awstats_updateall.pl maillogconvert.pl"
do
mv /usr/local/awstats/${file} /usr/local/awstats/${file}.bak
done
Recursively copy the files in cgi-bin
to /usr/lib/cgi-bin
:
_$: cp /root/apps/awstats-7.5/wwwroot/cgi-bin/* --recursive /usr/lib/cgi-bin
Recursively copy the files in icon
to /usr/share/awstats
:
_$: cp /root/apps/awstats-7.5/wwwroot/{classes,css,icon,js} --recursive /usr/share/awstats
Copy the files in tools
to /usr/lib/cgi-bin
:
_$: cp /root/apps/awstats-7.5/tools/*.pl /usr/lib/cgi-bin
Tunnel
The AWStats web site will be accesed through port 8443. This port is hidden behind a firewall for good reasons, so in order to see the web site we will need to create a tunnel:
(user@local)_$: ssh -L 8443:localhost:8443 user@<DevOps server>
Once created, all things going to the 8443
port in our machine will be forwarded over the secure channel to the 8443
port in the DevOps server and we will be able to see the web site.
Configuration
- The
awstats.pl
script is located at/usr/lib/cgi-bin
. - The
awstats_buildstaticpages.pl
script is located at/usr/share/awstats/tools
. - The
maillogconvert.pl
script is located at/usr/local/awstats
.
_$: mkdir /usr/local/awstats
_$: cp /usr/share/doc/awstats/examples/awstats_*.pl /usr/local/awstats/
_$: cp /usr/share/doc/awstats/examples/maillogconvert.pl /usr/local/awstats/
_$: cp /usr/share/awstats/tools/logresolvemerge.pl /usr/local/awstats/
_$: cp /etc/awstats/awstats.conf /etc/awstats/awstats.nginx.web.conf
/etc/nginx/sites-available/awstats:
-----------------------------------
server {
listen 8443;
root /var/www/awstats;
location ^~ /awstats-icon {
alias /usr/share/awstats/icon/;
access_log off;
}
location ^~ /awstatscss {
alias /usr/share/doc/awstats/examples/css/;
access_log off;
}
location ^~ /awstatsclasses {
alias /usr/share/doc/awstats/examples/classes/;
access_log off;
}
# Perl execution
location ~ \.pl$ {
include /etc/nginx/fastcgi_params;
fastcgi_index index.pl;
fastcgi_pass 127.0.0.1:8999;
fastcgi_param SCRIPT_FILENAME /usr/lib$fastcgi_script_name;
}
}
Note: The rest of the fastcgi parameters are in /etc/nginx/fastcgi_params
.
_$: ln -s /etc/nginx/sites-available/awstats /etc/nginx/sites-enabled/
_$: service nginx restart
/usr/lib/index.pl:
------------------
#!/usr/bin/perl
print "Content-type:text/html\n\n";
print <<EndOfHTML;
<html>
<head><title>Perl CGI Test</title></head>
<body><h1>Perl CGI is working</h1></body>
</html>
EndOfHTML
_$: chmod +x /usr/lib/index.pl
If we go to http://127.0.0.1:8443/index.pl
we will see the message “Perl CGI is working”.
Analyzing stats from other servers
We must place the configuration files in the /etc/awstats
directory. Those files must conform to the following naming standard: awstats.<name>.conf
. We will use the <name>
part to do the database updates.
Example
- Filename:
awstats.mail.01.conf
- Command needed to update the database:
awstats.pl -config=mail.01 -update
There cannot be two files with the same name despite being in two different directories. For instance, we cannot have /etc/awstats/web1/site.conf
and /etc/awstats/web2/site.conf
at the same time.
On those configuration files we configure the LogFile
and DataDir
sections:
- LogFile:
- mail:
perl /usr/local/awstats/maillogconvert.pl standard < /srv/backup/logs/mail/mailserver/mail.log |
- web:
/srv/backup/logs/<site>/webserver/access.log
- mail:
- DataDir:
- mail:
/var/lib/awstats/mailserver
- web:
/var/lib/awstats/webserver
- mail:
_$: mkdir -p /var/lib/awstats/webserver
_$: mkdir -p /var/lib/awstats/mailserver
/etc/awstats/awstats.webserver.site.conf:
-----------------------------------------
...
LogFile="/srv/backup/logs/site/web/access.log"
...
DirData="/var/lib/awstats/webserver"
...
/etc/awstats/awstats.mailserver.conf:
-------------------------------------
...
LogFile="perl /usr/local/awstats/maillogconvert.pl standard < /srv/backup/logs/mail/mailserver/mail.log |"
...
DirData="/var/lib/awstats/mailserver"
...
Now we create a web page to see the stats for those sites. Please take a time to appreciate how fast, responsive and lean this web page is:
/var/www/awstats/index.html:
----------------------------
<html>
<head>
<title>AWStats</title>
</head>
<body>
<h2>mail.example.com</h2>
<a href="/mailserver/mail.awstats.html">mail.example.com</a></p>
<h2>web.example.com</h2>
<a href="/webserver/site.awstats.html">example.com</a></p>
<a href="/webserver/anothersite.awstats.html">example.net</a></p>
</body>
</html>
Create a script to update the stats:
/root/cron/awstats-update.sh:
-----------------------------
awstats="/usr/lib/cgi-bin/awstats.pl"
WWWPATH="/var/www/awstats"
# mail
$awstats -config=mailserver -update -output > ${WWWPATH}/mailserver/mail.awstats.html
# web
$awstats -config=webserver.site -update -output > ${WWWPATH}/webserver/site.awstats.html
$awstats -config=webserver.anothersite -update -output > ${WWWPATH}/webserver/anothersite.awstats.html
# Fix permissions
/bin/chown www-data:www-data --recursive ${WWWPATH}
and another one to backup the stats already created:
/root/cron/awstats-backup.sh:
-----------------------------
for host in mailserver webserver
do
# Configuration files
cp /etc/awstats/awstats.$host* /srv/backup/awstats/$host/conf
# History files
cp /var/lib/awstats/$host/* /srv/backup/awstats/$host/txt
# HTML Reports
cp /var/www/awstats/$host/* /srv/backup/awstats/$host/www
done
Once created, we can add those scripts to our crontab entries:
_$: crontab -e
...
### AWStats
10 * * * * /root/cron/awstats-update.sh
0 0 2 * * /root/cron/awstats-backup.sh
...
Basic authentication
/etc/nginx/sites-available/awstats:
-----------------------------------
server {
listen 8443;
root /var/www/awstats;
# Authentication
location / {
auth_basic "System user name and password required";
auth_basic_user_file /var/www/awstats/admin/.htpasswd;
}
location ^~ /admin {
deny all;
}
# Icons, images and CSS
location ^~ /awstats-icon {
alias /usr/share/awstats/icon/;
access_log off;
}
location ^~ /awstatscss {
alias /usr/share/doc/awstats/examples/css/;
access_log off;
}
location ^~ /awstatsclasses {
alias /usr/share/doc/awstats/examples/classes/;
access_log off;
}
# Perl execution
location ~ \.pl$ {
include /etc/nginx/fastcgi_params;
fastcgi_index index.pl;
fastcgi_pass 127.0.0.1:8999;
fastcgi_param SCRIPT_FILENAME /usr/lib$fastcgi_script_name;
#fastcgi_intercept_errors on;
}
}
_$: mkdir /var/awstats/admin
Now we will generate passwords for two ficticious users. You can do this using htpasswd
from the apache2-utils or there is also a PIP package with the same name.
_$: htpasswd -bc user1 "pass1" /var/www/awstats/admin/.htpasswd
_$: htpasswd -b user2 "pass2" /var/www/awstats/admin/.htpasswd
_$: nginx -t && service nginx reload
Processing logs from Windows’ IIS
We will split this process in two parts: the first one is the general use case and the second one the checkout step of our web application. In order to create a monthly log for the checkout step, which is extracted from the general use case, we will use the checkoutm.sh
script.
The directory structure is as follows:
/srv/backup/logs/site
├── app
│ ├── fr000001.xml
│ ├── fr000002.xml
│ ...
│ └── freb.xsl
└── web
├── 201311
│ ├── u_ex131119.zip
│ ├── u_ex131120.zip
│ ...
│ ├── u_ex131128.zip
│ ├── u_ex131129.zip
│ └── u_ex131130.zip
├── 201312
│ ├── u_ex131201.zip
│ ├── u_ex131202.zip
│ ...
│ ├── u_ex131228.zip
│ ├── u_ex131229.zip
│ ├── u_ex131230.zip
│ └── u_ex131231.zip
├── unzipped
│ ├── checkout
│ │ ├── checkout.log
│ │ └── checkout.sh
│ ├── u_ex131119.log
│ ├── u_ex131120.log
│ ...
│ ├── u_ex131228.log
│ ├── u_ex131229.log
│ ├── u_ex131230.log
│ └── u_ex131231.log
└── unzip.sh
AWStats configuration
/etc/awstats/awstats.iis.site.conf:
-----------------------------------
...
LogFile="cat /srv/backup/logs/site/web/unzipped/u_ex1312*.log |"
LogFormat=2
SiteDomain="www.example.com"
DNSLookup=0
DirData="/var/lib/awstats/iis"
...
/etc/awstats/awstats.iis.site-checkout.conf:
--------------------------------------------
...
LogFile="/srv/backup/logs/site/web/unzipped/checkout/checkout.log"
LogFormat=2
SiteDomain="www.example.com"
DNSLookup=0
DirData="/var/lib/awstats/iis"
...
Helper shell scripts
/srv/backup/logs/site/web/unzip.sh:
-----------------------------------
# Unzip all files in "unzipped" folder
FOLDER="unzipped"
for f in ./${FOLDER}/*.zip
do
7z x $f -o${FOLDER} && rm $f
done
/srv/backup/logs/site/web/unzipped/checkout/checkoutm.sh:
---------------------------------------------------------
# Creates checkout logs for every month
# Arguments:
# - year: 00, 01, ... , 99
# - month: 01, 02, ... , 12
# Example:
# $ checkoutm.sh 14 03 # March 2014
# $ checkoutm.sh 15 02 # February 2015
if [ $# -eq 2 ]
then
year=${1}
month=${2}
else
year=`date +"%y"`
month=`date +"%m"`
fi
echo "Using year: $year"
echo "Using month: $month"
file="checkout-${year}${month}.log"
# Create file with header
touch ${file}
echo "#Software: Microsoft Internet Information Services 7.5
#Version: 1.0
#Date: 20${year}-${month}-01 00:00:00
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) sc
-status sc-substatus sc-win32-status time-taken" > $file
# Get all entries from this month that are checkout
# grep -h "${year}-${month}" ../u_ex${year}${month}*.log | grep "/intranet/checkout" >> ${file}
grep -h "/intranet/checkout" ../u_ex${year}${month}*.log >> ${file}
# Change windows CRLF to LF (remove ^M)
sed -i 's/\r//g' ${file}
Process regular logs:
_$: cd /srv/backup/logs/site/web
_$: cp ./201312/*.zip ./unzipped
_$: ./unzip.sh
Process checkout logs. In this case we will process all checkouts that happened during January of 2014:
_$: cd /srv/backup/logs/site/web/unzipped/checkout
_$: ./checkoutm.sh 14 01 # 14 --> 2014 ; 01 --> January
We can either wait until awstats is automatically updated or we can manually force an update. To force an update run the following command:
_$: /root/cron/awstats-update.sh
Analyzing old log files
Let’s suppose that in March 2015 some log files are missing and that we realized they were missing in May 2015.
Take a backup of the months after March that are fine:
_$: cd /var/lib/awstats/iis
_$: mkdir ./tmp
_$: mv awstats0[45]2015.iis.site.txt ./tmp
Edit the configuration file so that March is analyzed again, but this time completely ;)
/etc/awstats/awstats.iis.site.conf:
-----------------------------------
...
LogFile="cat /srv/backup/logs/site/web/unzipped/u_ex1503*.log |"
Run awstats
:
_$: awstats="/usr/lib/cgi-bin/awstats.pl"
_$: WWWPATH="/var/www/awstats"
_$: $awstats -config=iis.site -update -output > ${WWWPATH}/iis/site.awstats.html
It might happen that running awstats does not create the file for March. If that happens, do it manually:
_$: touch /var/lib/awstats/iis/awstats032015.iis.site.txt
and run again:
_$: $awstats -config=iis.site -update -output > ${WWWPATH}/iis/site.awstats.html
Once the awstats032015.iis.site.txt
has data, copy back the files for April and May:
_$: cd /var/lib/awstats/iis
_$: mv ./tmp/awstats0[45]2015.iis.site.txt .
_$: rmdir ./tmp
Create PDF reports
Check that the awstats_buildstaticpages.pl
is located in /usr/lib/cgi-bin
:
_$: [[ -f /usr/lib/cgi-bin/awstats_buildstaticpages.pl ]] || echo "Missing"
_$: perl ./awstats_buildstaticpages.pl -month=05 -year=2016 \
-config=webserver.site \
-dir=/tmp -buildpdf=/usr/bin/htmldoc \
-diricon=/usr/share/awstats/icon \
-awstatsprog=/usr/lib/cgi-bin/awstats.pl
Comprobar que los archivos temporales tienen cierto tamaño (han sido rellenados): _$: find /tmp -name “awstats.*.html” -size +500c | sort
Troubleshooting
While really big files are being processed, the following warning may appear: “Flush history file on disk (unique hosts reach flush limit of 20000)”. It is not an error, just information.