[mysql][Apache] mod_log_sqlを使ってApacheのアクセスログ(access_log)をmysqlのARCHIVEストレージエンジンに保存する
mod_log_sqlを使って、Apacheのアクセスログをmysqlに保存する設定をしたときのメモです。
アクセスログを保存するmysqlのストレージエンジンには、前からずっと気になっていたARCHIVEストレージエンジンを使用しました。
■ ARCHIVEストレージエンジンについて
- ロギングや監査用途に向いている。SELECT、INSERT命令しか使えない
- INSERTのパフォーマンスはMyISAMの1.5倍、InnoDBの3.5倍
- データは圧縮して格納(圧縮率70~80%)
- インデックスは非対応
- 一般ユーザーの利用率は5%程度
すべて以前行ったセミナーでもらった資料より抜粋です。
■ ログを保存するデータベースを作成
mysqlのインストールは完了しているものとして割愛します。
ただmysqlをソースからビルドしてインストールする場合には、configure時に–with-archive-storage-engineオプションを追加しないとARCHIVEストレージエンジンは使用できません。
現在のMySQLでARCHIVEストレージエンジンが有効かどうかを調べるには以下のようにします。
mysql> show variables like 'have_archive'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | have_archive | YES | +---------------+-------+ 1 row in set (0.00 sec)
結果にYESと出ればARCHIVEストレージエンジンを使用できます。
もしNOと出た場合には、–with-archive-storage-engineオプションをつけて再度mysqlをビルドする必要があります。
続いてログ保存用のデータベースを、apachelogsという名前で、ストレージエンジンをARCHIVEで作成します。
/etc/my.cnfに以下のように設定してデフォルトのストレージエンジンをARCHIVEにします。設定後にmysqlを再起動します。
[mysqld] default-storage-engine=archive
ストレージエンジンの設定方法は他にも色々あります(テーブル作成時に設定とか、alter tableとか)が、ここでは割愛します。
続けてログを保存するデータベースの設定をします。
mysql> create database apachelogs; Query OK, 1 row affected (0.00 sec) mysql> use apachelogs; Database changed mysql> grant INSERT, CREATE ON apachelogs.* TO loguser@localhost IDENTIFIED BY 'passwd'; Query OK, 0 rows affected (0.00 sec)
データベースの作成と同時に、apachelogsのデータベースについて、INSERT文とCREATE文の権限をもったloguserを登録しています(パスワードはpasswd)。
■ mod_log_sqlのインストール
mod_log_sqlのページから最新版をダウンロードします(今回はVersion 1.101)。
$ wget http://www.outoforder.cc/downloads/mod_log_sql/mod_log_sql-1.101.tar.bz2 $ tar jxvf mod_log_sql-1.101.tar.bz2 $ cd mod_log_sql-1.101 $ ./configure --with-apxs=/usr/local/apache2/bin/apxs --with-mysql=/usr/local/mysql $ make $ su # make install
apxsとmysqlのパスはお使いの環境に合わせてください。
これで、/usr/local/apache2/module ディレクトリにmod_log_sql.so、mod_log_sql_logio.so、mod_log_sql_mysql.so、mod_log_sql_ssl.soの4つのモジュールができていると思います。
今回はconfigure時にlibmysqlclientがないといったエラーが出たため、最初mod_log_sql_mysqlが作成されませんでした。これについては、MySQLのマニュアルを頼りに、以下のようにしたら解決できました。
$ cp /usr/local/mysql/lib/libmysqlclient.so /usr/lib $ su # /sbin/ldconfig -v | grep mysql /usr/local/mysql/lib: libmysqlclient.so.15 -> libmysqlclient.so (changed)
■ Apacheの設定をする
httpd.confを編集します。まずはロードモジュールの設定です
LoadModule log_sql_module modules/mod_log_sql.so LoadModule log_sql_mysql_module modules/mod_log_sql_mysql.so <ifmodule mod_ssl.c> LoadModule log_sql_ssl_module modules/mod_log_sql_ssl.so </ifmodule> LogSQLLoginInfo mysql://loguser:passwd@localhost/apachelogs LogSQLCreateTables on LogSQLTransferLogTable access_log LogSQLDBParam port 3306 LogSQLDBParam socketfile /tmp/mysql.sock
LogSQLDBParam socketfile のパスはお使いの環境に合わせてください。
設定が終わったらapacheを再起動します。
$ /usr/local/apache2/bin/apachectl configtest Syntax OK $ /usr/local/apache2/bin/apachectl restart
以上で設定が全て完了しました。
webページにアクセスしてからapachelogsデータベースののaccess_logテーブルを表示した結果です
select * from access_log\G *************************** 1. row *************************** id: NULL agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4 bytes_sent: 3442 child_pid: NULL cookie: NULL machine_id: NULL request_file: NULL referer: ... remote_host: ***.***.***.*** remote_logname: NULL remote_user: - request_duration: 0 request_line: NULL request_method: GET request_protocol: HTTP/1.1 request_time: NULL request_uri: /images/logo.gif request_args: NULL server_port: NULL ssl_cipher: NULL ssl_keysize: NULL ssl_maxkeysize: NULL status: 200 time_stamp: 1227704007 virtual_host: NULL bytes_in: NULL bytes_out: NULL ...
ちゃんとaccess_logがデータベースに保存されました。
このあと、パフォーマンスのベンチマークをとったのですが、文が長くなったので次回書きます。
■ 参考URL
http://www.outoforder.cc/projects/apache/mod_log_sql/docs-2.0/?chapter=/
http://www.freewheelburning.com/linux/mod_log_sql.html
http://beausoir.blog100.fc2.com/blog-entry-14.html