There’s already a lot of tutorial on internet on how to install awstats for nginx. I didn’t find any for the configuration I wanted for my outdoor gear website, FishingPicks.com, so I’ll write one, for my record.

I have some custom needs, let’s suppose I have 3 domains :

master-domain.com

alpha.com

beta.com

And I want to have stats for the 2 latest domains. The master-domain.com is used as the master domain of the server, with awstats available at awstats.master-domain.com, instead of having alpha.com/awstats and beta.com/awstats. The idea it to group all the server script/tools (phpmyadmin, zabbix, etc …) under master-domain.com.

We also want to password protect the stats, but with different credential for each vhost.

This file should be empty by default. It’s used to set the settings shared by all your awstats config.

We teach awstats the meaning of each field when parsing the log. The last token (%otherquot) means that “Oh, that string here does not mean anything.”.

Creating a configuration file for each vhost

Awstats is picky about the configuration files : you should have one config file by vhost, they should be named following the convention : awstats.domain.tld.conf, and should be placed inside the /ect/awstats/ directory.

So, for the vhost alpha.com and beta.com, you should create these two files :

awstats.alpha.com.conf

awstats.beta.com.conf

The official method

There is already a model configuration file inside the /ect/awstats/ directory : awstats.conf. Documentation says to clone that file when creating your own config files, with

Then you just edit these files to your needs… Method I’m not fond of. If you take a look at awstats.conf, you’ll see that it’s a very complete conf, with plenty of comments, and all the available settings, all of that for just * suspense music * … 1500 lines.

I’m personally not interested into having multiples conf files, for 1500 lines each, with each files differing of just 4 lines.

The DRY method

If you have ls the /etc/awstats folder, you’ll see that there’s by default 2 files here :

awstats.conf

awstats.conf.local

awstats.conf is the main conf file, origin of all the other conf files. It’ll also fallback to this file if no other config file exists.

awstats.conf.local is an empty file. It’s the parent of all the other config files. If you have some rules that are shared among all your config, you put them here.

What I do is I copy all the contents of awstats.conf into awstats.conf.local, and just put the important rules inside each vhost config, so they’re easier to read, and shorter.

What to put in the conf files

Let’s create the conf files for alpha.com.

vi /etc/awstats/awstats.alpha.com.conf

We start with an empty file, insert the following lines

# Path to you nginx vhost log file
LogFile="/var/log/nginx/access.alpha.com.log"
# Domain of your vhost
SiteDomain="www.alpha.com"
# Directory where to store the awstats data
DirData="/var/lib/awstats/"
# Other alias, basically other domain/subdomain that's the same as the domain above
HostAliases="www.alpha.com"

By default, awstats store all its data inside /var/lib/awstats/, which is the default settings. You could change that to another directory, or have a subdirectory for each vhost, like /var/lib/awstats/alpha.com/.

But even if you use the default setting, you have to set it in each config, as it can not be inherited from awstats.conf.local.

You’re free to add more setting if some of your vhost requires additional customization.
Repeat the same steps for each vhost.

Tune the global settings

Set LogFormat to Combined (if you didn’t use the optional step in formatting the nginx log) LogFormat = 1

You could also enable some plugin, like GeoIP (require additional steps, beside uncommenting the line).

Computing data

Awstats is now configured for each vhost. We will now tell it to read the log files, and generate the stats from them. It’s a boring operation that should be done regularly (e.g, once a day, each 6 hours, etc…) depending on your need. More you wait, more the log file grow in size, and more time it will take to process it. It’ll depend on your website traffic.

To compute the data, a perl script is available in /usr/share/doc/awstats/examples. The awstats_updateall.pl will compute the stats for each available config. It’s easy, just run :

/usr/share/doc/awstats/examples/awstats_updateall.pl now -awstatsprog=/usr/lib/cgi-bin/awstats.pl

The -awstatsprog flag tell the script where to find the awstats.pl script, because awstats_updateall.pl is just a wrapper that is executing awstats.pl for each of your config.

The obvious solution to run this script regularly is to use a cron job. The drawback is that nginx logs are rotated with logrotate. It means that every X days, the log file will be archived (and renamed), and a new log file will be created. If you use a cronjob to compute the stats

Just before the log rotation, you’ll lose all data between the computation and the rotation, as the file is renamed and not accessible by awstats anymore

After the rotation, you’ll also lose all data between the computation and the next rotation.

At the rotation, you’ll experience some weird things.

Solution #1

We could prevent the data loss by telling awstats to always parse 2 logs files : the regular one, and the last archived log.

Logrotate always rename the file using the convention filename.1, filename.2. At each rotation, all filenames are incremented, and filename will become filename.1. A new filename will be created, so the newest archive is always filename.1.

You’ll never lose data because of the rotation, since you’ll parse the rotated file too.

Solution #2

Execute the computation just before the rotation, using logrotate postrotate hook. This is useful especially if your computation interval equal the rotation interval (e.g, you rotate every day at midnight, and you compute also every day at midnight).

Edit the logrotate config for nginx :

vi /etc/logrotate/nginx.conf

I like to rotate log every day, to keep them lighter. By default, nginx rotate logs weekly.

/usr/share/doc/awstats/examples/awstats_updateall.pl now -awstatsprog=/usr/lib/cgi-bin/awstats.pl

directly in the shell, if you don’t want to wait for the log rotation at midnight.

You could use a regular cronjob on a single log file if you compute more than once a day, and use the postrotate hook just for the computation near midnight.

Building the html reports

awstats_updateall.pl will compute new stats, but not build the html pages. Awstats come with 2 options :

Build the static html page yourself

Use cgi to build the page dynamically

I’ll use the dynamic options, explained below. There’s already plenty of articles on internet explaining how to build static pages if it’s the way you want to go.

Exposing awstats

Now that awstats is configured and charged with data, let’s make it viewable by the internet.

Let’s create the subdomain where awstats will live : awstats.master-domain.com, linked to /var/www/awstats.

Let’s assume that the subdomain is already redirected to your server (creating the subdomain is not in the scope of this post), you just have to create the nginx virtual host for awstats.master-domain.com.

How you create it is your own choice, there’s multiple ways (single conf file, ‘sites-enabled’ a la apache, etc …).

When using solution 2 to compute data (using prerotate in nginx’s logrotate settings), is it possible to miss some hits between when awstats is run and when the logs are rotated?

wa0x6e

Yes, it is possible. But the lost data should be insignificant, as it is a matter of milliseconds. You can lose data for events happening between the start and end of the pre-rotate script. The longer the awstats computation takes, larger the lost-data timeframe will be.

You could run the awstats computation more often, so that the one inside the pre-rotate is lighter, thus faster. That should minimize the time the pre-rotate command takes, and you will lose at most 1 or 2 seconds of data.