PHPで自作のアクセスログファイルを作成する方法(排他処理書き込みサンプル)
PHPで自作のアクセスログファイルを作ろう
ログをデータベースに都度インサートするのは負荷が大きいので、
テキストファイルに書き溜めてから一括インポートしています。
基本中の基本的なプログラミングですが、書きたい。
1、実現したいこと
最終行にどんどん追加される感じのデータを作る。
Linuxのアクセスログと同じです。
新しいデータが最終行に追記されていく。
DBにインポートする場合はCSV形式にします。
ここで絶対にやらないといけないのが「排他処理」です。
ようは「ファイルロック」をして順番に書き込むようにしないといけない。
本当に必要なのか?と疑問に思って排他処理無しでやってみましたが、
1時間1000回の処理でも全くダメでした。絶対要る。
2、PHPでのアクセスログファイル排他処理書き込みサンプル
$genzaijikan = date("Y_m_d_H");
//CSV用まとめ
$csvmatome = '"'.$id.'","'.$url.'","'.$cat.'"';
$fp = fopen("/var/www/log/".$genzaijikan.".txt", "a+");
flock($fp, LOCK_EX);
fwrite($fp,$csvmatome."\n");
flock($fp, LOCK_UN);
fclose($fp);
最低限のコードだとシンプル。
どうにかCSVの形にして、fopenの「a+」で開いてfwriteで書き込む。
書き込む前にファイルロック(LOCK_EX)をして、書き込んだらロックを外す(LOCK_UN)。
「a+」はファイルが存在しない場合は自動で作成してくれるので、
アクセスログファイルとしてはファイル名を日時にすればOK。
上記は1時間単位でのファイル分けです。
1時間前のファイルをDBへインポート、という感じにすればヨシ。
3、まとめ
できる限りデータベースの負荷を減らそう。
DBへ都度インサートするのが簡単で確実ですが、
インデックスを貼っている場合はとても負荷が大きいのでダメです。
そうリアルタイムで必要ないデータの場合はまとめてCSVインポートしよう。
ログファイルをメモリ領域に保存すると爆速になる。
より速度を求める場合はそうしてみてください。
どうせDBに保存したらゴミになるデータなのでほぼ問題は無いと思う。
サーバーが複数ある場合はNFSに書き込むと楽です。
そこからDBでLOAD DATA INFILEでインポートするのがたぶん最速。
このあたりで負荷削減できると楽しい。