Мы — долго запрягаем, быстро ездим, и сильно тормозим.
www.lissyara.su —> статьи —> FreeBSD —> WWW —> mod_log_sql

Модуль для записи статистики apache в БД MySQL

Автор: lissyara.


    Озадачился тем, чтобы писать логи апача в БД. Начал стругать скрипт на шелле, но - понял, что это полумера... Порывшись в инете понял - метод есть - модуль к апачу, который пишет логи сразу в БД. Пошёл в порты, смотреть, есть ли он там:
/usr/home/lissyara/>
/usr/home/lissyara/>cd /usr/ports/
/usr/ports/>make search name='mod_log_sql'
Port:   mod_log_sql-1.18_2
Path:   /usr/ports/www/mod_log_sql
Info:   Allows Apache to log to a MySQL database
Maint:  lev@FreeBSD.org
B-deps: apache-1.3.34_3 expat-1.95.8_3 gettext-0.14.5
gmake-3.80_2 libiconv-1.9.2_1 mysql-client-4.1.16_1 perl-5.8.7_2
R-deps: apache-1.3.34_3 expat-1.95.8_3 mysql-client-4.1.16_1 perl-5.8.7_2
WWW:    http://www.grubbybaby.com/mod_log_mysql/

Port:   mod_log_sql-1.100
Path:   /usr/ports/www/mod_log_sql2
Info:   Allows Apache to log to a MySQL database
Maint:  apache@FreeBSD.org
B-deps: apache-1.3.34_3 expat-1.95.8_3 gettext-0.14.5 gmake-3.80_2
libiconv-1.9.2_1 mysql-client-4.1.16_1 perl-5.8.7_2
R-deps: apache-1.3.34_3 expat-1.95.8_3 mysql-client-4.1.16_1 perl-5.8.7_2
WWW:    http://www.outoforder.cc/projects/apache/mod_log_sql/

/usr/ports/>

Нашлось, аж 2 штуки. Как самый умный, я решил поставить второй - /usr/ports/www/mod_log_sql2, но, тут меня ждал облом - он не хотел собираться... Кое-как собрал - не работает... Плюнул, снёс, поставил другой - /usr/ports/www/mod_log_sql - этот сразу поставился, и заработал. Надо заметить, что, на самом деле, оба порта - один и тот же модуль, но разных версий... Итак:

/usr/ports/>cd /usr/ports/www/mod_log_sql
/usr/ports/www/mod_log_sql/>make && make install && make clean

После установки, создаём БД, заводим пользователя и даём ему привилегии на эту БД:

/usr/home/lissyara/>mysql --user=root --password=root_password \
? --execute="CREATE DATABASE apache_logs"
/usr/home/lissyara/>mysql --user=root --password=root_password \
? --execute="GRANT USAGE ON *.* TO apache@localhost IDENTIFIED \
? BY 'apache' WITH MAX_QUERIES_PER_HOUR 0 \
? MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0"
/usr/home/lissyara/>mysql --user=root --password=root_password \
? --execute="GRANT ALL PRIVILEGES ON apache_logs.* \
? TO apache@localhost WITH GRANT OPTION"
/usr/home/lissyara/>

Минимальная рабочая конфигурация такова:
/usr/local/etc/apache/httpd.conf

<IfModule mod_log_sql.c>
# инфа для соединения с MySQL -
# хост, имя пользователя, пароль
LogSQLLoginInfo         localhost apache apache
# БД, в которую будут писаться логи
LogSQLDatabase          apache_logs
# Создавать или нет таблицу, для хранения логов
# (В принципе, никто не запрещает создать её самому,
# у такого решения будут даже плюсы - не будет лишних
# граф...)
LogSQLCreateTables      on
# Сокет MySQL
LogSQLSocketFile        /tmp/mysql.sock
# Порт, на котором висит MySQL - Если порт стандартный (3306)
# то можно эту строчку закомментировать (или просто не писать :))
LogSQLTCPPort           3306
# имя таблицы, в которую писать логи
LogSQLTransferLogTable access_log
</IfModule>

Для расширенной настройки пригодится следующая табличка:
?
что означает
имя колонки
тип колонки
пример
A User agent agent varchar(255) Mozilla/4.0(compat;MSIE 6.0;Windows)
a CGI arguments request_args varchar(255) user=Smith&cart=1231
b байт передано bytes_sent int unsigned 32561
c текст cookie cookie varchar(255) Apache=syn.line.net.1300102700823
H HTTP протокол request_protocol varchar(10) HTTP/1.1
h имя удал. хоста remote_host varchar(50) blah.foobar.com
I Request ID id char(19) POlFcUBRH30AAALdBG8
l Ident user info remote_logname varchar(50) bobby
M Machine ID machine_id varchar(25) web01
m HTTP метод запроса request_method varchar(6) GET
P PID процесса child_pid smallint unsigned 3215
p HTTP порт server_port smallint unsigned 80
R реферер referer varchar(255) http://www.biglinks4u.com/page.html
r полный запрос request_line varchar(255) GET /foo.htm HTTP/1.1
S время в UNIX time_stamp int unsigned 1005598029
s статус запроса status smallint unsigned 404
T время обработки request_duration smallint unsigned 2
t время request_time char(28) [02/Dec/2001:15:01:26 -0800]
U краткий запрос request_uri varchar(255) /books-cycroad.html
u узер (из авторизации) remote_user varchar(50) bobby
v виртуальный хост virtual_host varchar(50) www.lissyara.su

А собственно расширенная конфигурация будет выглядеть примерно так:
/usr/local/etc/apache/httpd.conf
<IfModule mod_log_sql.c>
# инфа для соединения с MySQL -
# хост, имя пользователя, пароль
LogSQLLoginInfo         localhost apache apache
# БД, в которую будут писаться логи
LogSQLDatabase          apache_logs
# Создавать или нет таблицу, для хранения логов
# (В принципе, никто не запрещает создать её самому,
# у такого решения будут даже плюсы - не будет лишних
# граф...)
LogSQLCreateTables      on
# Сокет MySQL
LogSQLSocketFile        /tmp/mysql.sock
# Порт, на котором висит MySQL - Если порт стандартный (3306)
# то можно эту строчку закомментировать (или просто не писать :))
LogSQLTCPPort           3306
# Таблица, в которую будут записываться логи (можно сделать несколько
# и разместить их внутри директив `VirtualHost` - тогда каждый
# виртуальный хост будет писать логи в свою таблицу)
LogSQLTransferLogTable access_log
# что писать, а что нет в таблицу с логами. В данном варианте, пишется
# вообще всё - но если не хотите писать всё, то неиспользуемые колонки
# будут содержать `NULL`
LogSQLTransferLogFormat AabcHhIlMmPpRrSsTtUuv
# также можно настроить и исключения - что писать, а что нет
# в логи:
# Следующий параметр определяет что писать в логи (если не подходит
# под шаблон - то не пишется. Если параметр не задан - пишется всё)
# также надо заметить, что эти параметры являются регистрозависимыми
# т.е. *.JPG файлы не пройдут по нижепредложенному варианту...
LogSQLRequestAccept     *.gif *.jpg *.html
# какие файлы надо игнорировать (если по предыдущей, разрешающей,
# директиве они прошли, можно зарезать их тут), также в доках на модуль
# приводится интересный пример использования этой директивы - чтобы не
# засирать логи попытками малолетних кулхацкеров взомать сервер, надо
# поместить в неё следующие словечки: root.exe cmd.exe default.ida ...
# Также можно зарезать всю графику в логах: .jpg .gif .png
LogSQLRequestIgnore     statistic.html test.gif
# Какие удалёные хосты игнорировать при ведении логов
# в этом примере не будут учитываться запросы со всех моих
# хостов - forum.lissyara.su, www.lissyara.su, mx.lissyara.su  и других...
LogSQLRemhostIgnore     lissyara.su
# следующий параметр предназначен для автоматического создания
# всех таблиц для всех виртуальных хостов машины - например для
# машины где очень много виртуальных хостов - соответственно руками
# всё прописывать очень обломно :)
LogSQLMassVirtualHosting on
# надо заметить, что есть ещё интересные параметры - можно регистрировать
# работу других модулей, и их результатов - в оригинале, на сайте
# разаработчика есть пример для модуля mod_gzip,
# но я пока с этим не разбирался...
</IfModule>

Вот такой будет конфиг... Также неплохо бы создать индексы - пригодится если будете делать выборки из этой таблицы... После внесения всех необходимых пунктов перезапускаем апач, и смотрим, создались ли таблицы:
/usr/home/lissyara/>/usr/local/etc/rc.d/apache.sh restart
Stopping apache.
Waiting for PIDS: 37566.
Starting apache.
/usr/home/lissyara/>mysql --user=apache --password=apache \
? --database=apache_logs --execute="SHOW TABLES"
+-----------------------+
| Tables_in_apache_logs |
+-----------------------+
| access_log            |
| cookies               |
| headers_in            |
| headers_out           |
| notes                 |
+-----------------------+
/usr/home/lissyara/>

Замеченные баги: Самое главное - недостаточный размер некоторых столбцов, создаваемых автоматически - в частности `referer` - бывает достаточно длинным (если чувак пришёл с поисковика, например) и он не влазиет весь. Пришлось поменять тип столбца на `text`, аналогично со столбцом `request_uri`.
Также, по неизвестной причине, не пишет скока байт отдано скриптами - типа *.php... Абидно...



размещено: 2006-01-29,
последнее обновление: 2008-06-23,
автор: lissyara


DarkHost, 2006-11-30 в 14:57:15

Я думаю, что при большой нагрузке(access.log порядка 10Gb к концу дня) это будет слишком тормозить web-сервер.

VladB, 2007-10-17 в 18:29:10

При большой нагрузке "пробки" может выбить =)

сиськи, 2008-06-23 в 5:04:09

у меня access.log не занимает много места... точнее я поставил там combinet в кофиге апаче

а кто использовал? как оно работает?

patryk, 2009-12-06 в 1:08:05

спасибо за статью.

именно то, что искал.
а вот причиной этого самого поиска как раз и были действия "малолетних кулхацкеров".

asm, 2011-12-28 в 17:04:51

Все бы классно, но проблема ротации логов..



 

  Этот информационный блок появился по той простой причине, что многие считают нормальным, брать чужую информацию не уведомляя автора (что не так страшно), и не оставляя линк на оригинал и автора — что более существенно. Я не против распространения информации — только за. Только условие простое — извольте подписывать автора, и оставлять линк на оригинальную страницу в виде прямой, активной, нескриптовой, незакрытой от индексирования, и не запрещенной для следования роботов ссылки.
  Если соизволите поставить автора в известность — то вообще почёт вам и уважение.

© lissyara 2006-10-24 08:47 MSK

Время генерации страницы 0.1169 секунд
Из них PHP: 25%; SQL: 75%; Число SQL-запросов: 86 шт.
Исходный размер: 36262; Сжатая: 8476