Analytics

The easiest way to have exactly the web analytics we want while using minimum resources and preserving privacy is to do it ourselves using the logs instead of complex scripting and user monitoring. Claude.ai helped with initial planning.

e.g. https://clickforcharity.net/stats.html

A lightweight, privacy-first analytics system with per-site dashboards. Each site shows its own traffic stats with day/week/month navigation.

What’s New

  • Per-site stats: Each site gets its own /stats.html page
  • Dynamic navigation: View by day, week, or month with forward/back arrows
  • JSON-based storage: Daily reports stored as small JSON files (~1-5 KB each)
  • Client-side aggregation: Week/month views calculated in the browser
  • No external services: All data stays on your servers
  • Easy deployment: Just two files (Python script + HTML dashboard)

Files

  • analytics.py – Parses Apache/Nginx logs, generates daily JSON reports
  • stats.html – Interactive dashboard with period navigation
  • DEPLOYMENT.md – Step-by-step guide for clickforcharity.net
  • sample-access.log – Test log file (you can delete after testing)

How It Works

Parser (analytics.py)

  1. Reads web server logs
  2. Skips bots and errors (4xx/5xx status codes)
  3. Groups stats by day
  4. Generates report-YYYY-MM-DD.json files

Dashboard (stats.html)

  1. Loads required JSON files on startup
  2. Aggregates data for selected period (day/week/month)
  3. Displays metrics, charts, and tables
  4. All processing happens in the browser

File Organization

/data/
  └── analytics/
      ├── report-2026-02-15.json
      ├── report-2026-02-14.json
      └── ... (keep forever for historical trends)

/var/www/html/
  └── stats.html (public dashboard)

/usr/local/bin/
  └── analytics.py (runs via daily cron)

Key Features

Statistics Tracked

  • Visitors – Unique IPs per day
  • Pageviews – Total page views per day
  • Top Pages – Most visited URLs
  • Referrers – Traffic sources (Direct, Google, etc.)
  • Browsers – Browser/device breakdown
  • Bandwidth – Data transferred

More can be added and refinements made as the need arises.

Filters

  • Bots: Excluded (Googlebot, crawlers, etc.)
  • Errors: 4xx/5xx responses excluded
  • Methods: Only GET/HEAD requests counted

Period Navigation

  • Day: Single day stats
  • Week: Sunday-Saturday aggregated
  • Month: Full calendar month aggregated
  • Arrows: Navigate forward/backward through periods

Technical Details

  • Language: Python 3 (parser), Vanilla JavaScript (dashboard)
  • Dependencies: None (uses Python standard library only)
  • Browser support: All modern browsers (Chrome, Firefox, Safari, Edge)
  • Data sensitivity: IP addresses not exposed, only aggregated counts
  • Chart library: Chart.js (CDN-hosted)

Footprint

  • Per day: ~1-5 KB per JSON file
  • 365 days: ~2-5 MB total
  • Cost: Negligible

Current Disk Usage:

  • Data directory: 12 KB total
  • Each JSON report: ~2-2.5 KB
  • Parser script: 7.2 KB
  • Dashboard HTML: 20 KB

Projections:

  • Per year (365 days): ~900 KB – 1 MB
  • 10 years of history: ~9-10 MB
  • Essentially negligible

Memory:
RAM is zero except during the cron run (a few seconds at 2 AM). The parser processes the log file once daily and exits.

Summary:
✅ Disk: ~1 MB/year (trivial)
✅ RAM: Idle 99.9% of the time
✅ CPU: Seconds per day when cron runs
✅ Bandwidth: Minimal (tiny JSON files loaded client-side)

This is about as lightweight as analytics can get!

Notes

  • Raw logs are managed by the web server (typically rotate after 7-30 days)
  • JSON files are kept forever (tiny footprint, useful for historical trends)
  • No central collection needed – each site is independent
  • Dashboard works offline once loaded (all processing client-side)
  • No JavaScript framework dependencies – vanilla JS only

Below Is Redundant

This page is a mess because web analytics is a mess. I will try again with Matomo, this time on clickforcharity.top, which doesn’t use WordPress so it’s efficient. Also, it is apparently possible to run Matomo using the server logs, so it may be worth a try again for the other sites too.
https://matomo.org/log-analytics/

Outlinks are what we need to know. The docs have a page about them and a way (possibly) to increase accuracy of tracking. Ideally the logs should show this anyway, and that will be better than JavaScript.
Here is our outlinks page. It seems to be working.

It also has a signup plugin to allow users (SatoshiHost? — if we put it on a VPS) to sign up and use Matomo on their own site.

Matomo (see below) turned out to be very resource-heavy. AWStats is enough for what we need. It simply reads the existing logs and presents them in an understandable format.
https://clickforcharity.net/awstats/
For all our sites, we don’t need SEO or any of the other stuff designers have to do normally, and so we are lucky!

Awstats config location

E.g., to ignore a certain IP address:
My Files/domains/DOMAIN.COM/awstats/.data/awstats.DOMAIN.COM.conf
E.g., Uptime Kuma is 89.116.44.57, use SkipHosts="89.116.44.57"

#-----------------------------------------------------------------------------
# ADDED BY ANDY (exclude IP Addresses)
#-----------------------------------------------------------------------------

SkipHosts=”89.116.44.57“

But apparently AWStats overwrites that file every 24 hours, so we need to prevent that. https://bobcares.com/blog/awstats-exclude-ip/

Yes, you will need to SSH to the server in order to run the command.
I do see SSH is enabled/allowed on your account, so you should be able to SSH to your account and then run the following:

To make it immutable:
chattr +i domains/DOMAIN.COM/awstats/.data/awstats.DOMAIN.COM.conf

To make it editable again:
chattr -i domains/DOMAIN.COM/awstats/.data/awstats.DOMAIN.COM.conf

# Copy this file into awstats.www.mydomain.conf and edit this new config file
# to setup AWStats (See documentation in docs/ directory).
# The config file must be in /etc/awstats, /usr/local/etc/awstats or /etc (for
# Unix/Linux) or same directory as awstats.pl (Windows, Mac, Unix/Linux...)
# To include an environment variable in any parameter (AWStats will replace
# it with its value when reading it), 

So, perhaps this is not the actual config file. I don’t know what else to do.

Open Web Analytics
Logaholic

These two didn’t work well. Logaholic didn’t work at all. Softaculous has a lot of out-of-date scripts.

Matomo can do anything that we need that Google Analytics can do, but without compromising the security of our users. We can control what data it collects, even down to the level of location tracking (country, region, etc.).

  • We can install it easily on each site using Softaculous, so there is no other domain involved. No cross-site scripting, etc.
  • We will know exactly what data we are collecting and thus be able to make a meaningful “privacy policy” page.

Matomo is installed at stat.satoshihost.com [July 2024: abandoned this because it was slowing down the page loads]
It says “Google Tag Manager was detected on your website.” So although we are not using it, it’s still there; we need to get rid of it.