Running AWStats on Demand with Docker

March 8th 2019 Docker AWStats

Although I'm hosting my blog in Azure, I have a local instance of AWStats configured for analyzing the server logs. Since I'm only looking at the statistics a few times a year at most, I don't really need to have AWStats running all the time on my local server. What if I could just run it on demand when I need it instead?

Docker seemed a perfect tool for the job. I could configure AWStats in a container and run it locally on my workstation when needed. Of course, I wasn't the first one to think of that. I chose to base my configuration on the openmicroscopy/awstats image.

I liked how the command for generating the statistics was separate from running the site. To simplify the use, I decided to wrap all the configuration details in a Docker Compose file.

Following the idea of separate flows for generating and viewing the statistics meant that I had to create two services. The first one would generate the statistics from the log files:

version: '3'
services:
  generate:
    image: openmicroscopy/awstats
    command: /web-logs/*.log
    environment:
      - LOG_FORMAT="%time2 %other %method %url %query %other %logname %host %ua %other %referer %other %code %other %other %bytesd %other %other"
    volumes:
      - ${WEBLOGS}:/web-logs:ro
      - awstats-db:/var/lib/awstats
volumes:
  awstats-db:

The awstats-db named volume will hold the statistics and will be shared between both services. The local directory with the server logs is mounted in read-only mode. I read the local path from an environment variable on the host. The launch command for the service passes in the mount location of the server logs.

The trickiest part was specifying the correct log format. On my local server I still have it set to "2" as documented in the AWStats setup guide for IIS. Although the logs from Azure include additional fields, it seems to work just fine. But when I tried to use the same configuration with this Docker image, it skipped all log entries because of invalid format:

Dropped record (method/protocol '/index.html' not qualified when LogType=W): ...

I'm not sure why the two instances of AWStats behave differently (maybe because the version is different or because they are hosted on a different OS), but the only way I could get it working with this Docker image was to specify the exact format used in Azure logs as you can see in the docker-compose.yml file above.

With the generate service configured, I can now launch it from a PowerShell script to process the logs:

$env:WEBLOGS = "d:\Data\AzureLogs"
docker-compose up generate

Depending on the size of the logs which aren't processed yet, the processing can take a while. The container will automatically stop when the processing is done.

The second service is configured to run the AWStats web interface using the generated statistics:

  web:
    image: openmicroscopy/awstats
    command: httpd
    ports:
      - "8080:8080"
    volumes:
      - awstats-db:/var/lib/awstats

It reads the statistics from the awstats-db named volume shared with the generate service. Port 8080 is exposed so that the site can be accessed at http://localhost:8080. As documented, the httpd command is used to instruct the image to launch the site.

With the statistics already generated, the web service will start almost immediately:

docker-compose up web

Once I'm done with the analysis, I can simply stop the container by sending it an interrupt (Ctrl+C) signal from the shell.

For my use case, this is a superior alternative to hosting AWStats on the server.

Copyright
Creative Commons License