AWStats (он же Advanced Web Statistics) - аналитический инструмент, который собирает и анализирует информацию в логах сервера и предоставляет полученные данные в виде таблиц и графиков. С помощью AWStats можно анализировать логи web-сервера, ftp или почтового сервера. Мы будем собирать статистику только о посещениях веб-сайта.
Исторически так сложилось, что AWStats заточен на работу с логами Apache (httpd). Логи nginx, как написано в FAQ самого инструмента, является "exotic web log format". В этой статье мы рассмотрим, как заставить AWStats читать логи Nginx'а.
Сразу оговорюсь - в репозиториях Epel Awstats есть, но просто так его поставить не получится, т.к. версия из репозитория собрана с использованием Perl 5.24, а в RHEL8 используется Perl 5.26 по умолчанию. Конечно, можно переключиться на версию Perl 5.24, но это повлечёт за собой кучу ненужных телодвижений, связанных со сменой версии других приложений, собранных в Perl 5.26 и включенных в поставку операционной системы.
Перед установкой проверим , что в системе установлен wget
yum install wget
После этого идём на официальную страницу AWStats на SourceForge.NET и копируем ссылку на скачивание RPM-пакета последней версии awstats и скачиваем пакет на сервер
wget https://tenet.dl.sourceforge.net/project/awstats/AWStats/7.8/awstats-7.8-1.noarch.rpm
После завершения загрузки устанавливаем пакет AWStats, соглашаясь на установку всех зависимостей (у меня их было 139 на 17 МБ)
yum localinstall awstats-7.8-1.noarch.rpm
После завершения установки переходим к настройкам анализа лог-файлов. Все основные конфигурационные файлы AWStats находятся в каталоге /usr/local/awstats.
Мы не будем трогать стандартный конфиг, а создадим копию, для своего сайта
cp /etc/awstats/awstats{.model,.my.site}.conf
Откроем наш конфиг для редактирования
nano /etc/awstats/awstats.my.site.conf
В конфигурационном файле нас интересуют следующие параметры:
LogFile="/var/www/user/log/my.site.acces.log"
SiteDomain="my.site"
HostAliases="localhost 127.0.0.1 REGEX[my\.site$]"
DirData="/var/www/user/awstats/my.site/"
По умолчнию формат логов Nginx выглядит следующим образом:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
Посмотреть его можно по пути /etc/nginx/nginx.conf
Сам же, записанный лог, в таком формате, выглядит так:
8.8.8.8 - - [31/May/2021:22:06:25 +0300] "GET /templates/template/i/footer-social2.png HTTP/2.0" 200 4435 "https://my.site/templates/template/css/style.css?ver=1.3.19" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"
В конфигурационном файле AWStats есть краткая подсказка по полям лога, которые он может прочитать:
# %host Client hostname or IP address (or Sender host for mail log)
# %host_r Receiver hostname or IP address (for mail log)
# %lognamequot Authenticated login/user with format: "john"
# %logname Authenticated login/user with format: john
# %time1 Date and time with format: [dd/mon/yyyy:hh:mm:ss +0000] or [dd/mon/yyyy:hh:mm:ss]
# %time2 Date and time with format: yyyy-mm-dd hh:mm:ss
# %time3 Date and time with format: Mon dd hh:mm:ss or Mon dd hh:mm:ss yyyy
# %time4 Date and time with unix timestamp format: dddddddddd
# %time5 Date and time with format iso: yyyy-mm-ddThh:mm:ss, with optional timezone specification (ignored)
# %time6 Date and time with format: dd/mm/yyyy, hh:mm:ss
# %methodurl Method and URL with format: "GET /index.html HTTP/x.x"
# %methodurlnoprot Method and URL with format: "GET /index.html"
# %method Method with format: GET
# %url URL only with format: /index.html
# %query Query string (used by URLWithQuery option)
# %code Return code status (with format for web log: 999)
# %bytesd Size of document in bytes
# %refererquot Referer page with format: "http://from.com/from.htm"
# %referer Referer page with format: http://from.com/from.htm
# %uabracket User agent with format: [Mozilla/4.0 (compatible, ...)]
# %uaquot User agent with format: "Mozilla/4.0 (compatible, ...)"
# %ua User agent with format: Mozilla/4.0_(compatible...)
# %gzipin mod_gzip compression input bytes: In:XXX
# %gzipout mod_gzip compression output bytes & ratio: Out:YYY:ZZpct.
# %gzipratio mod_gzip compression ratio: ZZpct.
# %deflateratio mod_deflate compression ratio with format: (ZZ)
# %email EMail sender (for mail log)
# %email_r EMail receiver (for mail log)
# %virtualname Web sever virtual hostname. Use this tag when same log
# contains data of several virtual web servers. AWStats
# will discard records not in SiteDomain nor HostAliases
# %cluster If log file is provided from several computers (merged by
# logresolvemerge.pl), use this to define cluster id field.
# %extraX Another field that you plan to use for building a
# personalized report with ExtraSection feature (See later).
# If your log format has some fields not included in this list, use:
# %other Means another not used field
# %otherquot Means another not used double quoted field
# If your log format has some literal strings, which precede data fields, use
# status=%code Means your log files have HTTP status logged as "status=200"
# Literal strings that follow data field must be separated from said data fields by space.
Руководствуясь этими данными составим LogFormat AWStats для Nginx
LogFormat="%host %other %logname %time1 %methodurl %code %bytesd %refererquot %uaquot"
Последний параметр из log_format Nginx'а $http_x_forwarded_for в лог не попадает (я, честно говоря, не понимаю, для чего его вообще сюда вписали по умолчанию), поэтому LogFormat для AWStats я закончил на UserAgent'е
Теперь, когда все настройки завершены, необходимо запустить сбор статиситки из логов:
/usr/local/awstats/wwwroot/cgi-bin/awstats.pl -config=my.site -update
Create/Update database for config "/etc/awstats/awstats.my.site.conf" by AWStats version 7.8 (build 20200416)
From data in log file "/var/www/user/log/my.site.acces.log"...
Phase 1 : First bypass old records, searching new record...
Searching new records from beginning of log file...
Phase 2 : Now process new records (Flush history on disk after 20000 hosts)...
Jumped lines in file: 0
Parsed lines in file: 1098071
Found 0 dropped records,
Found 0 comments,
Found 0 blank records,
Found 3 corrupted records,
Found 0 old records,
Found 1098068 new qualified records.
Результаты сбора будут записаны в TXT файл, в папке /var/www/user/awstats/my.syte/. Каждый файл - собранная статистика за месяц.
Тут хотелось бы добавить уточнение по поводу сбора логов. Если вы используете logrotate, то у вас, скорее всего, накопилась куча журналов за прошедшие периоды. Их так же можно прочитать для статистики. Для этого смотрим, какие логи у нас есть
ls -l /var/www/user/log/my.site.acces*
-rw-r----- 1 nginx user 718352307 Jun 1 21:00 /var/www/user/log/my.syte.acces.log
-rw-r--r-- 1 nginx root 10006525160 May 31 13:57 /var/www/user/log/my.syte.acces.log.1
-rw-r----- 1 nginx user 546449764 Jun 1 03:32 /var/www/user/log/my.syte.acces.log-20210601
У меня собралось 3 архивных лога. Имена их запоминаем и возвращаемся к конфигурации awstats для нашего хоста. Мы будем использовать утилиту logresolvemerge из поставки awstats, для "склеивания" нескольких логов. Открываем конфигурационный файл, комментируем диррективу LogFile, прописываем новую, перечислив все найденые логи и запускаем сбор статистики снова:
nano /etc/awstats/awstats.my.site.conf
#LogFile="/var/www/user/log/my.site.acces.log"
LogFile="/usr/local/awstats/tools/logresolvemerge.pl /var/www/user/log/my.site.acces.log-20210601 /var/www/user/log/my.site.acces.log.1 /var/www/user/log/my.site.acces.log |"
/usr/local/awstats/wwwroot/cgi-bin/awstats.pl -config=my.site -update
Create/Update database for config "/etc/awstats/awstats.my.site.conf" by AWStats version 7.8 (build 20200416)
From data in log file "/usr/local/awstats/tools/logresolvemerge.pl /var/www/user/log/my.site.acces.log-20210601 /var/www/user/log/my.site.acces.log.1 /var/www/user/log/my.site.acces.log |"...
Phase 1 : First bypass old records, searching new record...
Searching new records from beginning of log file...
Phase 2 : Now process new records (Flush history on disk after 20000 hosts)...
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Flush history file on disk (unique url reach flush limit of 5000)
Jumped lines in file: 0
Parsed lines in file: 27252758
Found 1 dropped records,
Found 0 comments,
Found 0 blank records,
Found 370 corrupted records,
Found 0 old records,
Found 27252387 new qualified records.
После завершения сбора статистики, не забудьте вернуться в конфиг и раскомментировать основной LogFile, а тот который мы "склеивали" удалить или закомментировать!
Когда статиситка собрана, нам нужно автоматизировать этот процесс. Тут нам помогут cron и logrotate.
Cron мы настроим таким образом, чтобы он собирал статистику каждые 15 минут, а в logrotate добавим задание на сбор статистики перед ротацией.
И так, приступим. Откроем редактор настроек crontab для пользователя root
crontab -e -u root
И пропишем туда задание, на сбор статиситки AWStats каждые 15 минут:
0,15,30,45 * * * * /usr/local/awstats/tools/awstats_updateall.pl now -awstatsprog=/usr/local/awstats/wwwroot/cgi-bin/awstats.pl >/dev/null 2>$1
Далее перйдём к конфигурации logrotate
nano /etc/logrotate.d/nginx
И добавим в конфиг конструкцию prerotate
prerotate
/usr/local/awstats/tools/awstats_updateall.pl now -awstatsprog=/usr/local/awstats/wwwroot/cgi-bin/awstats.pl
Теперь статистика будет обновляться каждые 15 минут, плюс - перед началом ротации логов, что позволит учесть все хиты.
Самый удобный способ просмотра статиситки AWStats - открыть её в браузере. Для этого настроим виртуальный хост так, чтобы по адресу https://awstats.my.site/ открывалась страница с графиками и статистикой посещаемости нашего сайта.
Запускать AWStat необходимо как cgi скрипт, однако Nginx не умеет работать напрямую с fastCGI, поэтому необходимо установить spawn-fcgi и fcgiwrap.
yum install -y spawn-fcgi fcgiwrap
После установки идём в конфиг spawn-fcgi и настраиваем его на работу через unix сокет
nano /etc/sysconfig/spawn-fcgi
И прописываем там следующие настройки
FASTCGI_USER=nginx #Владелец сокета
FASTCGI_GROUP=nginx #Группа владельца сокета
SOCKET=/var/run/spawn-cgi/spawn-cgi.sock #Путь к файлу сокета
PIDFILE=/var/run/spawn-cgi/spawn-cgi.pid #Путь к запущенному процессу
OPTIONS="-u $FASTCGI_USER -g $FASTCGI_GROUP -s $SOCKET -P $PIDFILE -- /usr/sbin/fcgiwrap"
Перед тем, как запустить скрипт, нужно создать дирректорию для сокета
mkdir -p /var/run/spawn-cgi
Добавим наш скрипт в автозагрузку и запустим его
systemctl enable --now spawn-fcgi
systemctl start spawn-fcgi
Осталось настроить виртуальный хост для поддомена awstats.my.site. В папке /etc/nginx/conf.d/ создадим файл awstats.my.site.conf и запишем в него конфиг
nano /etc/nginx/conf.d/awstats.my.site.conf
server { server_name awstats.my.site; set $root_path /usr/local/awstats/wwwroot/cgi-bin/; root $root_path; error_log /var/www/user/log/awstats.my.site.error.log; access_log off; log_not_found off; location ^~ /icon { alias /usr/local/awstats/wwwroot/icon/; } location ^~ classes/ { alias /usr/local/awstats/wwwroot/classes/; } location ^~ css/ { alias /usr/local/awstats/wwwroot/css/; } location ~* \.pl$ { try_files $uri =404; gzip off; include fastcgi_params; fastcgi_pass unix:/var/run/spawn-cgi/spawn-cgi.sock; fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name; fastcgi_index index.pl; } }
Проверим нашу статистику, открыв в браузере http://awstats.my.site/awstats.pl?config=my.site
Чтобы избежать несанкционированного доступа к нашей статистике, закроем её базовой http аутентификацией. Для этого создадим папку для хранения паролей:
mkdir -p /etc/nginx/auth/
Затем создадим файл с паролями для нашего поддомена:
printf "username:`openssl passwd -apr1`\n" >> /etc/nginx/auth/awstats.my.site.htpasswd
После ввода команды, система запросит ввод пароля 2 раза.
Файл для аутентификации готов. Укажем параметры аутентификации в конфигурации хоста, в секции location ~* \.pl$ {}
nano /etc/nginx/conf.d/awstat.my.site.conf
auth_basic "AWStats auth"; auth_basic_user_file /etc/nginx/auth/awstats.my.site.htpasswd;
Теперь просмотр статистики доступен только после ввода логина и пароля.