Yii ページレベルのログが有効になります
Main.php にログセクションを追加します。
ページ ログ配列は以下に表示されます ( 'class'=>'CWebLogRoute', 'levels'=>'trace', //レベルはトレースです 'categories'=>'system.db.*' //のみデータベースに関する情報を表示します (データベース接続、データベース実行ステートメントなどの情報)、
完全なリストは次のとおりです:
Yii2に付属するログコンポーネントを拡張しました
設定ファイルで次のように使用します:
リーリーyiiログのロジック
Yii は階層型ログ処理メカニズムを使用します。つまり、ログの収集とログの最終処理 (表示、ファイルへの保存、データへの保存など) が分離されています。
ログ情報の収集は CLogger (ログレコーダー) によって完了し、ログ情報の配布と処理は CLogRouter (ログ ルーティング マネージャーと呼ばれます) のスケジューリングに従って処理オブジェクト (CFileLogRoute や CLogRoute から継承されたログ ディレクトリなど) に分散されます。ソースコードを繰り返し読んで、このような階層化された処理により柔軟な拡張が容易になるという Yii の設計思想にさらに感銘を受けました。
ログ情報は、通常情報、プロファイル、トレース、警告、エラー レベルなどのレベルに分類されます。CFileRoute のレベル属性を設定して、指定したレベルのログ情報のみを処理するなど、ログ ルーティングでフィルタリング条件を設定できます。
プログラム内で呼び出された場合:
対応するプロセスは次のとおりです:
質問: ログはいつファイルに書き込まれますか?
追跡を繰り返した結果、プロセッサ CLogRouter::processLogs() が、CLogRouter クラスの init メソッド内の Application オブジェクトの OnEndRequest イベントにバインドされていることがわかりました。同時に、イベント プロセッサーの CLogRouter::collectLogs メソッドも Yii::$_logger の onFlush イベントにバインドされます。これは、ログが多すぎる場合にログを更新し、タイムリーにファイルに書き込むために使用されます。 Yii::log() のメッセージ。コードは次のとおりです:
CApplication::run() メソッドで次のように定義されています。
リーリー
ログ プロセッサによって実行されるタスクには主に次の点が含まれます: CLogger からすべてのログを取得し、フィルタリングします (主に log:routes:levels/categories で定義されたレベルとカテゴリ)
リーリー
ログのフィルタリングが完了しました。次のステップは、ログの最終処理 (ファイルへの書き込み、データベースへの記録など) を実行することです。
リーリー
ただし、この関数には小さなバグがあり、ログ ディレクトリが書き込み可能かどうかを判断するだけで、CFileLogRoute は Linux と同様のログ ローテーション関数 (LogRoate) を実装し、サイズを指定します。とても思慮深くて完璧です! 私も彼から学び、彼のアイデアを吸収したいと思います!
protected/config/main.php の設定:
リーリー
ログコンポーネントを定義するには、プリロード (インスタンス化) が必要です。 CLogRouter をログ ルーティング マネージャーとして構成し、そのログ ルーティング プロセッサ (routes 属性) とその構成属性を設定します。 preload 属性と log 属性の定義は CWebApplication オブジェクトに適用する必要があります (CApplication::__construct の configure 呼び出しを参照してください。configure は CModule から継承されます)。 CWebApplication のコンストラクターで preloadComponents() が実行されると、ログ オブジェクト (つまり、CLogRouter のインスタンス) が作成されます。
コンポーネントを作成して初期化するとき、実際には CModule::getComponent が呼び出されます。この呼び出しでは、YiiBase::createComponent を使用してコンポーネント オブジェクトが作成され、コンポーネントの init が呼び出されて初期化されます。
if($this->hasEventHandler('onEndRequest')) { $this->onEndRequest(new CEvent($this)); }
也就是说,日志的最终处理(比如写入文件,系统日志,发送邮件)是发生在应用程序运行完毕之后的。Yii使用事件机制,巧妙地实现了事件与处理句柄的关联。
也就是说,当应用程序运行完毕,将执行CLogRouter::processLogs,对日志进行处理,。CLogRouter被称之为日志路由管理器。每个日志路由处理器从CLooger对象中取得相应的日志(使用过滤机制),作最终处理。
具体而言Yii的日志系统,分为以下几个层次:
日志发送者,即程序中调用Yii::log($msg, $level, $category),将日志发送给CLogger对象
CLogger对象负责将日志记录暂存于内存之中程序运行结束后,log组件(日志路由管理器CLogRoute)的processLogs方法被激活执行,由其逐个调用日志路由器,作日志的最后处理。
更为详细的大致过程如下:
这里举出一个案例:发生error级别的数据库错误时,及时给相关维护人员发送电子邮件,并同时将这些日志记录到文件之中。规划思路,发送邮件和手机短信是两个不同的功能,Yii已经带了日志邮件发送组件(logging/CEmailLogRoute.php),但这个组件中却使用了php自带的mail函数,使用mail函数需要配置php.ini中的smtp主机,并且使用非验证发送方式,这种方式在目前的实际情况下已经完全不可使用。代替地我们需要使用带验证功能的smtp发送方式。在protected/components/目录下定义日志处理器类myEmailLogRoute,并让其继承自CEmailLogRoute,最主要的目的是重写CEmailLogRoute::sendEmail()方法 ,其中,SMTP的处理细节请自行完善(本文的重点是放在如何处理日志上,而不是发送邮件上)。
接下来,我们就可以定义日志路由处理,编辑protected/config/main.php, 在log组件的routes组件添加新的路由配置:
'log'=>array( 'class'=>'CLogRouter', 'routes'=>array( array( 'class'=>'CFileLogRoute', 'levels'=>'error, warning,trace', ), array( 'class' => 'myEmailLogRoute', 'levels' => 'error', #所有异常的错误级别均为error, 'categories' => 'exception.CDbException', #数据库产生错误时,均会产生CDbException异常。 'host' => 'mail.163.com', 'port' => 25, 'user' => 'jeff_yu', 'password' => 'you password', 'timeout' => 30, 'emails' => 'jeff_yu@gmail.com', #日志接收人。 'sentFrom' => 'jeff_yu@gmail.com', ),
经过以上处理,即可使之实现我们的目的,当然你可以根据自己的需要进一步扩展之。