From c63e24daf002eca8a7c152a78bda34fe1c7a1981 Mon Sep 17 00:00:00 2001 From: deepend-tildeclub <58404188+deepend-tildeclub@users.noreply.github.com> Date: Mon, 26 Jan 2026 12:03:25 -0700 Subject: [PATCH] Add user statistics documentation for web traffic This document provides a comprehensive guide on generating and publishing sanitized traffic statistics for user directories on a web server. It includes instructions for opting in, file permissions, and troubleshooting common issues. --- wiki/source/user_statistics.md | 176 +++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 wiki/source/user_statistics.md diff --git a/wiki/source/user_statistics.md b/wiki/source/user_statistics.md new file mode 100644 index 0000000..cafe0d2 --- /dev/null +++ b/wiki/source/user_statistics.md @@ -0,0 +1,176 @@ +--- +title: Userdir traffic stats (sanitized analytics) +category: web +--- + +So you want traffic stats for your `~/public_html` site, This stats system generates a **sanitized** report per user from the server’s nginx logs, then lets you publish it *only if you choose to*. + +## What this gives you + +* Daily totals: requests, pageviews, unique visitors (hashed per-day), bytes +* “Top pages” list (query strings removed) +* Referrers by **domain only** (no full URLs) +* Browser/user-agent buckets (Chrome/Firefox/Bot/etc.) +* HTTP status code counts +* Optionally: a nice HTML dashboard generated by `goaccess` + +No raw IPs are shown in the report. + +## Opt-in (required) + +Nothing is generated for you unless you opt in. + +Create the opt-in flag: + +```sh +mkdir -p ~/.config/tilde-stats +touch ~/.config/tilde-stats/enabled +``` + +That’s it. The nightly job will include you from then on. + +## Where the files are written + +Reports are generated into: + +* `~/.local/share/tilde-stats/index.html` +* `~/.local/share/tilde-stats/stats.json` + +These files are **not automatically public**. + +## Publishing the report on your website + +There are two ways to publish the report: + +* **Copy (recommended)**: keeps `~/.local` private and uses normal web permissions. +* **Symlink (works, but requires permissions)**: points your website at `~/.local/...`, which means nginx must be able to traverse those dot-directories. + +Your stats page will be: + +* `https://tilde.club/~YOURNAME/stats/` + +### Recommended: copy into `~/public_html/stats/` + +```sh +mkdir -p ~/public_html/stats +cp -f ~/.local/share/tilde-stats/index.html ~/public_html/stats/index.html +cp -f ~/.local/share/tilde-stats/stats.json ~/public_html/stats/stats.json +chmod 644 ~/public_html/stats/index.html ~/public_html/stats/stats.json +``` + +### Alternative: symlink into `~/public_html/stats/` (requires permissions) + +```sh +mkdir -p ~/public_html/stats +ln -sf ~/.local/share/tilde-stats/index.html ~/public_html/stats/index.html +ln -sf ~/.local/share/tilde-stats/stats.json ~/public_html/stats/stats.json +``` + +If you use symlinks, nginx must be able to **traverse** the real path under `~/.local/...` (see permissions below). + +## Permissions (important, because Linux will happily sabotage you) + +For nginx to serve a file, it must be able to: + +* **traverse** every directory in the path (execute bit, `+x`) +* **read** the file (`+r`) + +### Minimum permissions for userdir websites + +If your `~/public_html` site already works, you probably already have this, but here’s the standard expectation: + +```sh +chmod 711 ~ +``` + +`chmod 711 ~` lets the web server traverse your home directory without listing it. + +### If you are COPYING files (recommended) + +Make sure your published files are world-readable: + +```sh +chmod 644 ~/public_html/stats/index.html ~/public_html/stats/stats.json +``` + +Your `~/.local/share/tilde-stats/` directory can stay private. + +### If you are SYMLINKING to `~/.local/share/tilde-stats/` (current reality) + +Because the report lives in a dot-directory path, nginx must be able to traverse: + +* `~` +* `~/.local` +* `~/.local/share` +* `~/.local/share/tilde-stats` + +And it must be able to read the report files themselves. + +Use these permissions: + +```sh +chmod 711 ~/.local ~/.local/share ~/.local/share/tilde-stats +chmod 644 ~/.local/share/tilde-stats/index.html ~/.local/share/tilde-stats/stats.json +``` + +Notes: + +* `711` is better than `755` for dot-directories since it allows traversal but not directory listing. +* If the generator writes the files with private permissions, you may need to re-apply the `chmod 644` on the two report files after regeneration if you are serving them directly from `~/.local`. + +## Updating / regenerating + +Stats are generated by an admin-run job (typically nightly). You don’t need to run anything manually. + +If you publish via **copy**, re-run the copy commands after the nightly update to refresh the public version. + +If you publish via **symlink**, the page updates automatically (as long as permissions allow nginx to read it). + +## Disabling / opting out + +Remove the opt-in flag: + +```sh +rm -f ~/.config/tilde-stats/enabled +``` + +No new reports will be generated for you after that. + +(Any old published copies or symlinks you created are your responsibility to delete.) + +## Troubleshooting + +### “My stats page 403s / 404s” + +* Confirm the public files exist: + +```sh +ls -l ~/public_html/stats/ +``` + +* Confirm permissions all the way down the path: + +```sh +namei -l ~/public_html/stats/index.html +``` + +If you’re using symlinks into `~/.local`, also check the target path: + +```sh +namei -l ~/.local/share/tilde-stats/index.html +``` + +Every directory in that output should have `x` for others (traversable), and the file should have `r` for others. + +### “The report exists in ~/.local/share but isn’t public” + +That’s expected. It’s private until you copy or link it into `~/public_html`. + +### “My report is empty” + +Either: + +* No traffic in the selected window, or +* You opted in recently and the next scheduled run hasn’t happened yet. + +(Servers do not read minds, only logs.)