Цифровой дворник

analytics

Обложка

Заходишь в свою веб-аналитику, а там тишина. За сутки — горстка просмотров и пара посетителей. Вроде сайт живой, статьи публикуются, кто-то их читает. Но панель упорно показывает, что кроме тебя и пары друзей никто не заходит.

Знакомо? У меня так было с блогом. Пока я не полез в access-логи веб-сервера и не обнаружил, что на сайт ходят толпы ботов, а аналитика их просто не видит. Дальше — почему так вышло и что я с этим сделал.

Как Umami считает визиты

Umami (и почти любая JS-аналитика) работает через скрипт на странице:

<script async src="https://analytics.example/script.js"
        data-website-id="..."></script>

Логика простая: браузер загружает страницу → выполняет скрипт → скрипт шлёт событие на api/send. Всё считает клиент, на стороне сервера — только приём.

И вот тут первая ловушка: боты не исполняют JavaScript. Поисковики, AI-краулеры, SEO-сканеры скачивают HTML и уходят. Они не запускают скрипт аналитики, поэтому для Umami их просто не существует.

Вторая ловушка: Umami по умолчанию фильтрует ботов по User-Agent. Даже если какой-то краулер решит выполнить скрипт, встроенная детекция ботов его отсеет. То есть панель намеренно показывает только «настоящих» людей.

Звучит разумно, пока тебе не нужно понять: а кто вообще стучится в мой сайт?

Что я увидел в логах

Когда я сравнил картину из Umami и из access-логов Caddy, разница оказалась смешной.

Umami за сутки: около полусотни просмотров, двадцать с лишним посетителей.

А в логах веб-сервера за тот же день — толпа. Вот кто приходил:

  • AhrefsBot — SEO-краулер
  • GPTBot, ChatGPT-User — краулеры OpenAI
  • ClaudeBot — Anthropic
  • PerplexityBot — Perplexity
  • Googlebot, Yandex, Bing — поисковики
  • TelegramBot — превью ссылок в мессенджере
  • плюс всякая мелочь вроде сканеров уязвимостей

Суммарно — под сотню обращений в день. И ни одного из них в Umami.

Вывод простой: JS-аналитика считает людей, а не трафик. Если хочешь видеть всех — надо смотреть логи сервера.

GoAccess вместо панели

GoAccess — это терминальный (и не только) анализатор логов, который гоняет access-лог и выдаёт отчёт: кто, откуда, сколько, какие страницы, какие статусы, какие боты. Никакого JS — только то, что реально дошло до сервера.

Ставится элементарно:

apt install goaccess

Но есть нюанс. Caddy по умолчанию пишет логи в stderr, а не в файл. Чтобы GoAccess их увидел, нужен файл:

log {
    output file /var/log/caddy/access.log
}

Тут я наступил на граблю: Caddy в systemd крутится под ProtectSystem=full, и файл лога вне разрешённых путей он создать не может — падает с «permission denied». Лечится drop-in'ом:

# /etc/systemd/system/caddy.service.d/rw-logs.conf
[Service]
ReadWritePaths=/var/log/caddy

Потом systemctl daemon-reload && systemctl reload caddy.

JSON-логи Caddy — не для GoAccess

Вторая засада: Caddy пишет логи в JSON, а GoAccess ест классический Combined Log Format. Приходится конвертировать. Я сделал это через jq:

jq -r 'select(.request != null)
  | select((.request.headers["User-Agent"][0] // "") | test("Uptime-Kuma|curl/|Python-urllib"; "i") | not)
  | "\(.request.client_ip // .request.remote_ip) - - [\(.ts|strftime("%d/%b/%Y:%H:%M:%S %z"))] \"\(.request.method) \(.request.uri) \(.request.proto)\" \(.status) \(.size // 0) \"\(.request.headers.Referer[0] // "-")\" \"\(.request.headers["User-Agent"][0] // "-")\""' \
  access.log > access.clf

Заметили фильтр? Я отсекаю собственный мониторинг (Uptime-Kuma долбит сайт каждые 30 секунд — за сутки это тысячи строк шума) и свои же curl-запросы. Иначе отчёт превращается в статистику «сколько раз мой мониторинг пинговал самого себя».

Дальше — рендер:

goaccess --log-format='%h %^[%d:%t %^] "%r" %s %b "%R" "%u"' \
  --date-format='%d/%b/%Y' --time-format='%H:%M:%S' \
  -f access.clf -o /var/www/logs/index.html --no-global-config

Обновляю отчёт по cron раз в пять минут. Финальный штрих — отдаю HTML через Caddy на поддомен logs.example, закрытый тем же allow-list'ом, что и админки (снаружи пускаю только свои IP).

Что в итоге

Теперь у меня два инструмента, и каждый на своём месте:

  • Umami — чтобы видеть живых людей: что читают, откуда пришли, что держится на странице. Тут чистота важнее полноты.
  • GoAccess по логам — чтобы видеть весь трафик: людей, ботов, сканеры, статусы 404 и 500, откуда реально ломятся.

Один не заменяет другой. Панель аналитики молчит про ботов не потому, что их нет, а потому что она про них не должна знать. А логи не знают про поведение человека на странице, зато честно показывают каждый запрос.

Мораль: если кажется, что «на сайт никто не заходит» — проверьте логи, прежде чем расстраиваться. Возможно, там как раз наоборот — заходят, и ещё как.


А у вас чем смотрите трафик? Только панель, или логи тоже смотрите?

#selfhosting #analytics #monitoring #network #goaccess #umami