ラボ > Laravel、Lumen:DB関連
laravel ログをDBに保存するけどロールバックの対象外にしたい(singleton())
トランザクション開始して例外発生でコールバックってのは問題無いけど、ログファイルまでロールバックされると困るとき…
作成日:2024-08-10, 更新日:2024-11-13
やりたいこと
下記のような感じのソースでログだけロールバックさせたくない
▼任意のファイルの任意のメソッド
try {
\DB::beginTransaction();
App\Lib\hoge::foo();
if ( 問題アリのとき ) {
throw new Exception('問題発生');
}
\DB::commit();
}
catch (Exception $e) {
\DB::rollBack();
echo $e->getMessage();
}
▼「App\Lib\hoge.php」
function foo() {
// 処理の内容を任意のテーブルに保存
// DBにログを保存
}
期待する出力内容
例外が発生しなかった時
// 処理の内容を任意のテーブルに保存 // DBにログを保存
例外が発生した時
// DBにログを保存
方法
- ログをDBじゃなくファイル出力
- ログの接続先を変更する
ログをDBじゃなくファイル出力
とりあえず下記のような感じ。一番手っ取り早い
\Log::info(〇〇〇〇);
ログの接続先を変更する
テーブルに何かするときにDBの接続先を変更
※接続先は同じなので「接続先」というより「接続名」といったほうがしっくりくる
- 下準備:接続先(接続名?)を用意
- 切替え:シングルトン(※グローバル変数の代わり)を使って接続先を切り替える
下準備:接続先(接続名?)を用意
接続先は「log_connection」とする
※「config/database.php」の「connections」のトコに追加。「mysql」をマルっとコピペして「log_connection」に変更
クエリ
| クエリビルダ1 |
DB::connection('log_connection')->table(ログテーブル)->insert(['message' => 'エラーメッセージ']);
|
|---|---|
| クエリビルダ2 |
$connection = DB::connection('log_connection');
$result = $connection->insert(['message' => 'エラーメッセージ']);
|
| Eloquent ORM |
$log = new \App\Models\ログテーブル();
$log->message = 'エラーメッセージ';
$log->setConnection('log_connection');
$log->save();
|
切替え:シングルトン(※グローバル変数の代わり)を使って接続先を切り替える
特定の条件のときだけ接続先を変更したい
→グローバル変数を使うのが手っ取り早いんだが…サービスコンテナの「シングルトンインスタンス」ってのを使う
- シングルトンインスタンスの設定
- ログ出力:シングルトンを使って接続先を変更する
シングルトンインスタンスの設定
接続先をログ用に…としたいので「ConnectDB」の「tblLog」としておく
▼app/Providers/AppServiceProvider.php
// 省略
class AppServiceProvider extends ServiceProvider
{
public function register()
{
// 省略
// DBの接続先。ロールバックでログが消えるのを避けたい
$this->app->singleton('ConnectDB', function () {
return (object) ['tblLog' => false];
// usage. 値のセット: app('ConnectDB')->tblLog = true;
// usage. 値の取得: app('ConnectDB')->tblLog
});
}
// 省略
ログ出力:シングルトンを使って接続先を変更する
任意のタイミングで実行
app('ConnectDB')->tblLog = true;
ログ出力をメソッド化している時
個人的に…ログ出力をメソッド化していたので…
app('ConnectDB')->tblLog = true;
// メソッド化しているログ出力を実行
app('ConnectDB')->tblLog = false;
レコード挿入時
if (app('ConnectDB')->tblLog) {
$connection = DB::connection('log_connection');
}
else {
$connection = DB::connection(); // デフォルト設定で接続
}
$result = $connection->insert(['message' => 'エラーメッセージ']);