set-up · apache · with or without Docker
Apache log analytics from the combined log you already keep
Apache log analytics with no new module and, for most sites, no change to Apache. One command finds your site's CustomLog in Apache's settings and sends each new line to your Skald.
Apache log analytics is reading the access log Apache writes for every request, and turning it into visits, sources and pages. Skald reads Apache's standard combined LogFormat: the address, the time, the request, the status, the size, the referrer and the user agent.
30-day free trial · no card · we set it up within one working day · free to self-host
$ curl -fsSL https://<your Skald>/traffic-kit/<code> | sudo bash Skald: installing the log shipper for example.com. == 1. How it runs here with docker (Docker works here) == 2. The access log of example.com found in the web server's settings: /var/log/apache2/example.com-access.log Done. The shipper for example.com runs with docker and sends to your Skald.
Sample output, shortened. ${APACHE_LOG_DIR} in your CustomLog line is read as /var/log/apache2.
[01] the log format
Apache's combined LogFormat, one token at a time
This is the line Apache ships with. Skald reads it as it is. Click a token to see what Apache writes there, and what Skald does with it.
apache2.conf · LogFormat … combined
click a token"%{Referer}i": where they came from
What Apache writes
The page the visitor came from, when the browser says, such as "https://chatgpt.com/".
What Skald does with it
The source of the visit: an AI assistant, a search engine, a campaign or Direct. Many apps strip it, so AI clicks are a floor.
[02] one command
How the one command finds your Apache CustomLog
You do not tell it where the log is. It reads Apache's settings the way Apache does, and picks the virtual host of your site.
- It reads
/etc/apache2/sites-enabled/on Debian and Ubuntu, and/etc/httpd/conf.d/andhttpd.confon the Red Hat family. - It finds the virtual host whose
ServerNameorServerAliasis your site, orwww.your site. - It takes that host's
CustomLog, with${APACHE_LOG_DIR}read as/var/log/apache2. - Several logs: it asks, the biggest first. None: it tries
/var/log/apache2/access.logand/var/log/httpd/access_log. - It runs the shipper with Docker if Docker works, or else as a systemd service with Python 3.9 or newer.
$ curl -fsSL https://<your Skald>/traffic-kit/<code> | sudo bash
Your Skald shows the real line in Settings > Connections. The code works once, for 24 hours.
$ curl -fsSL https://<your Skald>/traffic-kit/<code> | sudo bash -s -- --log /var/log/apache2/example.com-access.log
--yes asks nothing. --dry-run shows every step and changes nothing.
[03] one field, if you run Next.js
An Apache LogFormat for a Next.js site
A click inside a Next.js site sends no HTML request, and a link prefetch looks the same in a plain log. One field at the end of the LogFormat tells them apart.
Add this at the very end, inside the LogFormat quotes:
rsc_prefetch=%{Next-Router-Prefetch}iThen test and reload. On Debian and Ubuntu:
$ sudo apachectl configtest && sudo systemctl reload apache2
On the Red Hat family the service is httpd. Apache writes - when the header was not sent. Any other site can skip this.
- 09:14:02 203.0.113.24 "GET /pricing/" 200 "GPTBot/1.2"AI · training
- 09:14:03 198.51.100.7 "GET /" 200 "chatgpt.com" Safaripeople · from ChatGPT
- 09:14:04 198.51.100.7 "GET /docs/?_rsc=1x" 200 rsc_prefetch=-a click: page view
- 09:14:04 198.51.100.7 "GET /pricing/?_rsc=2y" 200 rsc_prefetch=1a prefetch: not a page
Sample lines. With the field, a click inside the site is a page view and a prefetch never is.
[04] check and undo
Check the Apache shipper, or take it away
The check reads only. Each line says OK, or PROBLEM with the fix under it, or CANNOT TELL.
- The log must be readable by group adm. If not, the check prints the fix:
sudo chgrp admandsudo chmod 640on the file, and the same group and mode in logrotate's create line. - One log per site. On Debian, a virtual host with no CustomLog writes to
other_vhosts_access.log, shared by other sites. The check says when a log is shared. - Never lost, never twice. The shipper saves its place only after Skald has a batch, and numbered batches are never counted twice.
$ sudo skald-ship-check ✓ OK the web server (apache2) is running ✓ OK the access log /var/log/apache2/example.com-access.log is there and group adm may read it ✓ OK the access log is growing (written in the last 10 minutes) ✓ OK www.example.com writes to /var/log/apache2/example.com-access.log ✓ OK the send address answers (401 without a token is expected) ✓ OK skald-ship is running (0 restarts)
$ sudo skald-ship-uninstall
Sample output, shortened.
[05] honest limits
What Apache log analytics with Skald does not do
What it does not do
- It does not edit Apache. The Next.js field is yours to add; the check only says when it is missing.
- It does not read Apache's common format, which has no referrer and no user agent. Use combined.
- It has no country for an Apache line unless a GeoIP country file is set on the Skald server. Without one, the country says Not recorded.
- It does not record the request's size for Security on Apache. That optional field is documented for nginx only.
- It sees only requests that reach Apache. Behind a CDN, cached pages need the CDN's own log or the Skald Worker.
- It sends lines written after the install. Older lines in the file are not sent.
keep reading
More on Apache log analytics
questions
Apache log analytics FAQ
Straight answers, including what Skald does not do.
Which Apache LogFormat does Skald read?
Apache's combined format: LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined. It holds everything Skald needs. Apache's common format has no referrer and no user agent, and Skald does not read it: switch the CustomLog line to combined.
Do I need to install an Apache module?
No. Skald reads the log file Apache already writes, and the shipper runs beside Apache, not inside it. The only change some sites make is one field at the end of the LogFormat, for a Next.js site.
My virtual host has no CustomLog line. What happens?
On Debian and Ubuntu, a virtual host with no CustomLog of its own writes to other_vhosts_access.log, which every such site shares. Give the site its own CustomLog, so its lines are not mixed with other sites. sudo skald-ship-check says when a log is shared with other host names.
Does it work on Red Hat, Rocky or AlmaLinux?
The one command reads httpd's settings too: /etc/httpd/conf/httpd.conf and /etc/httpd/conf.d/. A relative path such as logs/access_log is read from /etc/httpd. If it finds no log, it tries /var/log/httpd/access_log, and --log names any other file.
Does it need Docker?
No. It uses Docker when Docker works on the server, or else a systemd service with Python 3.9 or newer. If neither is there, it stops and says what to install.
Will a request be lost or counted twice?
No. The shipper saves its place only after Skald has taken a batch, and batches are numbered so Skald drops one it already has. It follows logrotate's renames and copytruncate.
$ tail -f access.log | skald
See what AI does with your site. Free for 30 days.
No card. We set up hosted Skald for you within one working day, or you self-host it free. Every line of your log, sorted and added up.