How to Analyze Apache Logs with AWStats

How to analyze Apache logs with AWStats

How to analyze Apache logs with AWStats

Before I had access to fancy analytics dashboards, AWStats was the tool I relied on to turn raw Apache log files into readable, visual reports — visitor counts, top pages, referrers, search engine keywords, and more. It’s still one of the fastest ways to get meaningful insight straight from your server’s own logs, without sending any data to a third party. Here’s how I set it up.

What Is AWStats?

AWStats (Advanced Web Statistics) is a free, open-source log analyzer that generates advanced web, streaming, FTP, or mail server statistics graphically. For Apache specifically, it parses access.log and produces detailed HTML reports covering traffic patterns, visitor behavior, and more.

Why I Use AWStats

Prerequisites

Step 1: Install AWStats

On Debian/Ubuntu:

sudo apt update
sudo apt install awstats -y

On CentOS/RHEL:

sudo yum install epel-release -y
sudo yum install awstats -y

Step 2: Locate the Configuration Directory

AWStats configuration files typically live in:

/etc/awstats/

The main config template is awstats.conf, which you copy and customize per domain.

Step 3: Create a Configuration File for Your Site

sudo cp /etc/awstats/awstats.conf /etc/awstats/awstats.mydomain.com.conf

Edit the new file:

sudo nano /etc/awstats/awstats.mydomain.com.conf

Update these key directives:

LogFile="/var/log/apache2/access.log"
LogType=W
LogFormat=1
SiteDomain="mydomain.com"
HostAliases="www.mydomain.com localhost 127.0.0.1"
DNSLookup=0
DirData="/var/lib/awstats"

Let me explain the important ones:

Step 4: Ensure Your Apache Log Format Matches

AWStats expects the “combined” log format by default. Check your virtual host or main config for:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
CustomLog ${APACHE_LOG_DIR}/access.log combined

If your logs use a custom format, you’ll need to adjust LogFormat in the AWStats config to match (AWStats supports custom format strings, but combined is by far the easiest to work with).

Step 5: Create the Data Directory

sudo mkdir -p /var/lib/awstats

Step 6: Run AWStats for the First Time

sudo /usr/lib/cgi-bin/awstats.pl -config=mydomain.com -update

You should see output like:

Create/Update database for config "/etc/awstats/awstats.mydomain.com.conf" by AWStats version 7.8 (build...)
From data in log file "/var/log/apache2/access.log"...
Phase 1 : First bypass old records, searching new record...
Direct access after last parsed record (after line 45021)
Jumped lines in file: 45021
 Found 45021 already parsed records.
Phase 2 : Now process new records (log format: 1)...
Jumped lines in file: 0
 Parsed lines in file: 12043
 Found 12043 new qualified records.

This confirms it successfully parsed your log file and built its statistics database.

Step 7: Set Up the Web Interface

AWStats includes a CGI script to view reports interactively. Enable CGI on Apache:

sudo a2enmod cgi

Add a configuration block, typically at /etc/apache2/conf-available/awstats.conf:

Alias /awstatsclasses "/usr/share/awstats/lib/"
Alias /awstats-icon/ "/usr/share/awstats/icon/"
Alias /awstatscss "/usr/share/doc/awstats/examples/css/"

ScriptAlias /awstats/ /usr/lib/cgi-bin/

<Directory "/usr/lib/cgi-bin">
    Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
    AddHandler cgi-script .pl
    Require ip 192.168.1.0/24
</Directory>

Enable the config and restart Apache:

sudo a2enconf awstats
sudo systemctl restart apache2

Step 8: View the Report

Visit:

http://your-server-ip/awstats/awstats.pl?config=mydomain.com

You’ll get a full dashboard including:

Step 9: Automate Updates with Cron

I never want to run the update command manually every day, so I schedule it:

sudo crontab -e

Add:

0 * * * * /usr/lib/cgi-bin/awstats.pl -config=mydomain.com -update > /dev/null 2>&1

This runs hourly, keeping the statistics database fresh without needing to reprocess the entire log file each time (AWStats is smart enough to only process new lines since the last update).

Excluding Internal or Bot Traffic from Reports

One thing I always configure is excluding my own internal IPs and known monitoring bots so they don’t skew the visitor statistics. This is done with the SkipHosts and SkipUserAgents directives in the config file:

SkipHosts="127.0.0.1 192.168.1.0/24"
SkipUserAgents="Nagios-check UptimeRobot GoogleHC"

Without this, internal health checks and office traffic can make it look like your site has far more organic visitors than it actually does, which throws off any real analysis of user behavior.

Generating Static HTML Reports Instead of Using CGI

If you’d rather not enable CGI execution on your production Apache server (a reasonable security preference), AWStats can generate fully static HTML reports instead:

sudo /usr/share/awstats/tools/awstats_buildstaticpages.pl \
  -config=mydomain.com \
  -update \
  -dir=/var/www/html/stats \
  -awstatsprog=/usr/lib/cgi-bin/awstats.pl

This produces plain HTML files you can serve like any other static content, avoiding the need to expose an executable Perl script on your web server at all — my preferred approach for production sites where I want statistics but want to minimize the attack surface.

Comparing Month-Over-Month Trends

Because AWStats builds a persistent database per domain, I can revisit any past month’s report just by changing the URL parameters:

http://your-server-ip/awstats/awstats.pl?config=mydomain.com&month=06&year=2026

This makes month-over-month comparisons simple — I regularly check whether traffic, bandwidth, or error rates are trending up or down without needing a separate historical tool.

Real-World Use Case

I once used AWStats to diagnose a sudden traffic spike that looked great on the surface — until I checked the “robots/crawlers” report and realized nearly 80% of the “traffic” was actually an aggressive scraper bot repeatedly hitting product pages. That insight, which a basic visitor counter wouldn’t have surfaced, let me add rate-limiting rules targeting that specific user agent.

Common Mistakes I’ve Made

Security Best Practices

Performance Optimization Tips

Troubleshooting Common Issues

“Error: SiteDomain parameter not defined” — make sure SiteDomain is set in your config file.

Reports show zero visits despite traffic — double-check that LogFile points to the correct, currently-in-use access log, and that LogFormat matches your Apache config.

CGI script returns 500 error — verify mod_cgi is enabled and the script has execute permissions:

sudo chmod +x /usr/lib/cgi-bin/awstats.pl

FAQs

Does AWStats work with log files that have already been rotated and compressed? Yes, AWStats can process .gz compressed log files directly, which is useful when combined with logrotate.

Can I analyze multiple domains with one AWStats installation? Yes — just create a separate config file per domain (e.g., awstats.domain2.com.conf) and run updates for each.

Is AWStats as accurate as JavaScript-based analytics tools like Google Analytics? It measures things differently — AWStats counts server-side requests, so it includes bot traffic more prominently and doesn’t rely on client-side JavaScript execution, which some ad blockers disable. Neither approach is strictly “more accurate”; they answer slightly different questions.

How resource-intensive is AWStats? It’s quite lightweight for typical traffic volumes, though very large log files can take longer to process on the first run. Incremental updates after that are fast.

Summary and Key Takeaways

AWStats turns your existing Apache access logs into detailed, self-hosted analytics reports without any third-party tracking. Setting it up involves creating a per-domain config, making sure your Apache log format matches, and scheduling regular updates via cron. I’ve found it invaluable for spotting traffic anomalies, understanding visitor behavior, and keeping tabs on error rates — all straight from data my server was already collecting.

References

Exit mobile version