CakePHP 2.3 ログイン、操作履歴、アクセスログ出力
2017/03/11
CakePHP 2.3系でログイン履歴、操作履歴、アクセスログなどのログ出力方法
ログ出力を作ることになった経緯
今回は、ログイン履歴、操作履歴、アクセスログといったログの出力に関しての説明です。
操作ログの出力に関しては、簡単に出力できるだろうと考えていたのですが、実は意外に実装が難しかったですね。(実はそれほど難しいものじゃないのですが、CakePHPの仕様を分かっていなくてさんざん悩んでしまった、というだけですが...)
最初はもしかすると、操作ログのプラグインがあるんじゃないか、とさえ思ったのですが、そこまで甘くはなかったわけです。
単純なすべてのアクセスのログを取るものや、SQLのログを取るものはありましたが、当然ながらオリジナルで作成している Webシステムに合わせて柔軟なログを出力したい、なんていう要望が叶えられるようなものはなかったワケです。
ログ出力をファイルに出力する方法
今回は、まず下記のサイトを参考に Vendor内に Classを作り、処理を構築しました。
http://neoinspire.net/archives/34#.UfXaItaChph
ちなみに、Vendorに設置した classの呼び出し方法は、CakePHP2.Xでは変更になっていますので、下記のサイトを参考にしました。
http://www.monoreview.com/?p=35
————–(/app/Vendor/accesslogs.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php class AccessLogs{ function write_log() { $msg = date('Y-m-d H:i:s') . "," . env('REQUEST_URI') . "," . env('HTTP_REFERER') . "," . env('HTTP_USER_AGENT') . "," . env('REMOTE_ADDR') . "\n"; $filename = LOGS . 'accesslogs/' . date('Ymd') . '.log'; $log = new File($filename); $log->append($msg); return true; } } ?> |
————–
————–(/app/AppController.php)
1 2 3 4 5 6 7 8 9 |
<?php App::import('Vendor', 'accesslogs'); class AppController extends Controller { public function beforeFilter() { $this->access = new AccessLogs(); $this->access->write_log(); } } |
————–
続けて、「cake/app/tmp/logs/」の中に「accesslogs」というフォルダを作ってください。
Linux系のサーバであれば、書き込み権限を設定してください。
これで、上記に作成したフォルダの中にログが出力されるようになります。
非常に簡単にアクセスログを出力する処理が作れましたので、これは今後の勉強になったかと思っています。
ですが、これをいざ実際に必要としているログイン履歴や、各ページでの操作ログを DBに保存させる処理に拡張しよう、としたら途端に分からなくなったのです。
ログ出力データベースに保存する方法
そんなわけで、寄り道も含めて、全く違う方法で DBにログを保存する方法を探したところ、参考になりそうな下記のサイトが見つかりました。
http://pc.casey.jp/archives/750
こちらを参考にしながら、テーブル名は、Historyに変更し、認証処理など不要な項目を削除しました。
————–(テーブル)
1 2 3 4 5 6 7 8 9 |
CREATE TABLE IF NOT EXISTS `histories` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `system` varchar(64) NOT NULL, `level` varchar(6) NOT NULL, `client` varchar(15) NOT NULL, `message` varchar(512) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1; |
————–
————–(/app/HistoriesController.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php class HistoriesController extends AppController { var $name = 'Histories'; function beforeFilter(){ parent::beforeFilter(); } function admin_index() { $this->write_log(__METHOD__, 'info', 'Display list view.'); $this->set('histories', $this->paginate('History')); } } ?> |
————–
「class AppController extends Controller」の中に「write_log」の関数を編集します。
————–(/app/AppController.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class AppController extends Controller { function write_log($systemName, $level, $message){ $ip = 2; $data = array( 'system' => $systemName, 'level' => $level, 'message' => $message, 'client' => $ip, 'created' => '', ); $this->History->create(); $this->History->save($data); } } |
————–
————–(/View/Histories/admin_index.ctp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php ?> <h1>システム稼動ログ一覧</h1> <table> <tr> <th>日時</th> <th>システム</th> <th>レベル</th> <th>クライアント</th> <th>内容</th> </tr> <!-- $remotes配列をループして、投稿記事の情報を表示 --> <?php foreach ($histories as $history): ?> <tr> <td><?php echo $history['History']['created']; ?></td> <td><?php echo $history['History']['system'];?></td> <td><?php echo $history['History']['level'];?></td> <td><?php echo $history['History']['client'];?></td> <td><?php echo $history['History']['message'];?></td> </tr> <?php endforeach; ?> </table> |
————–
上記までの設定をすることで、ログ出力ができると思います。
一覧ページでリロードするたびにログのレコードが増えていくことが分かるでしょう。
これはこれで問題ないのですが、操作ログとして処理を作成する場合は、History以外のページでもログを出力する必要が出てきますので、その対応を作ってみました。
例えば、ログイン時にログインのログを出力する場合は、Usersでログを出力させる必要があると思いますので、まず「/Model/User.php」に Historyとの belongsToの設定を行います。
————–(/Model/User.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
: : public $belongsTo = array ( 'History' => array( 'className' => 'History', 'foreignKey' => 'id', 'conditions' => '', 'fields' => '', 'order' => '' ), ); : : |
————–
続いて、「/app/HistoriesController.php」には、どのコントローラーからのアクセスなのかの情報を引数として設定します。
————–(/app/HistoriesController.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php class HistoriesController extends AppController { var $name = 'Histories'; function beforeFilter(){ parent::beforeFilter(); } function admin_index() { $ctr_name = $this->name; $this->write_log(__METHOD__, 'info', 'Display list view.', $ctr_name); $this->set('histories', $this->paginate('History')); } } ?> |
————–
さらに、「/app/AppController.php」でデータを保存する処理では、Userテーブルとの連携の設定を行います。(「HistoriesController.php」から送られてくるコントローラー名をもとに、テーブルの連携処理を振り分けます。)
これで、History以外のページからも Historyテーブルへログ保存の処理が行えるようになります。
————–(/app/AppController.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class AppController extends Controller { function write_log($systemName, $level, $message, $ctr_name){ $ip = 2; $data = array( 'system' => $systemName, 'level' => $level, 'message' => $message, 'client' => $ip, 'created' => '', ); if ( $ctr_name == 'Histories' ) { $this->History->create(); $this->History->save($data); } else { $this->User-> History->create(); $this->User-> History->save($data); } } } |
————–
この処理は、ログを出力するコントローラの数が増えれば増えるほど分岐が増えますので、もう少しいい書き方を検討する必要があるとは思いますが。
また、ログインの処理については、よくあるログイン処理をそのまま記述していると、「autoRedirect」が有効になっているため、ログイン認証が有効になったとたんに「loginRedirect」で設定してあるページに遷移してしまいます。
そのため、リダイレクトをさせる前にログ出力の処理を入れるためには、「autoRedirect」を無効にする必要がありますが、その設定に関しては、下記のサイトに分かりやすく説明がありました。
http://hima-j.in/cakephp/cakephp-last-login/
参考になるサイト
最後に、この記事を書くに当たって参考にしたサイトと自分でも書いてみた記事を紹介しておきます。
DBに値を保存する「save」メソッドに関しては下記の 2サイトが分かりやすく説明してありましたので、とても勉強になりました。
http://www.garacter.com/notes/cakephp/model/save
http://www.kaasan.info/archives/2543
また、下記の記事も書いていますのでご覧ください。
CakePHP 2.3 主キー(ID)以外のキーで更新方法 updateAll
CakePHP 2.3で saveの便利な使い方・サンプルソース付き
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
CakePHP3でPHP Simple HTML DOM Parserを使ってスクレイピングする方法
CakePHP3でPHP Simple HTML DOM Parserを使ってスクレイピングをする方法を解説。インストール方法、読み込み方法。および、具体的なスクレイピングを実行するサンプルソースも。
-
-
CakePHP3、CakePHP4、CakePHP5のバージョンを指定してインストールする詳細な手順を解説
CakePHP3のバージョンを指定してインストールする方法を詳細解説。CakePHP3のインストールはComposerを使うため設定もほぼ自動で完了。データベースの接続情報を記載すればアプリ開発のベースが整う。
-
-
国際化と地域化の翻訳機能「__()」を使って定数に変数を埋め込む方法
CakePHP4で定数に変数を埋め込み、翻訳機能「__()」で変数に値を入れる方法を紹介。定型の文章の一部だけを置換したい場合に利用すると便利。
-
-
CakePHP 2.3 テーブルの項目を演算した結果を条件として抽出する方法
アソシエーション(連携)している先のテーブルの項目で演算をする場合の考え方と注意点をサンプルソースを用いて説明しています。分かってしまえば簡単です。
-
-
CakePHP3にOGPをfetch、asignを利用してテンプレートごとに指定する方法を解説
CakePHP3でOGPを設定する方法を解説。fetch、assignを使用しレイアウトファイルに編集した変数にテンプレートファイルから値を指定する。これを利用してOGPを編集する。
-
-
getParam('action')
で取得するアクション名は別関数に移動しても不変CakePHP4系、5系では「getParam()」で処理中のアクション名を取得できる。そのアクションから別関数を呼び出してた関数でアクション名を調べたが同一の名称だった。
-
-
CakePHP4、5の認証処理で認証が通らない際の確認方法と確認箇所の紹介
CakePHP4、5系の認証処理でログイン認証が通らない場合の確認方法、確認箇所を解説。ログ出力し、ステータスを確認するが、ステータスの内容も紹介。それはそのままusernameを変更する際のポイントでもある。
-
-
CakePHP3、CakePHP4のdatetime型カラムの日時の扱い。秒まで表示する方法
CakePHP3の日時カラムで秒まで扱う場合はdate()、strtotime()関数ではうまくいかない。CakePHP3であらかじめ用意された「i18nFormat()」を使用する。
-
-
CakePHP3のユーザ管理・ログイン認証プラグインCakeDC/Usersのインストール解説・3.6以降対応
CakePHP3のユーザ管理プラグイン Usersは、ユーザ登録、メール認証、ログイン認証、ユーザ管理、権限管理、reCAPTCHAなど会員制のサイトを簡単に実現可能。その導入方法、カスタマイズ方法を解説。
-
-
CakePHP3でテーブルにカラム(項目)を追加したときに変更するポイントのまとめ
CakePHP3でシステム開発をする際、途中でカラムを追加した場合に何を変更すればいいかを確認。カラムを追加する前後で Bakeした結果を比較し、変更になった点をリストアップした。