日志和使用上下文信息

有时,一个错误信息不足以修复一个错误。例如,如果你使用最佳实践,并且使用所有可能的错误来开发和测试一个应用,你可以得到一个错误信息。但是,没有执行的上下文,它只是告诉你这里有一个错误,并不清楚究竟是什么导致的。

在我们的例子中,我们将会使用一个非常简单并且代码编写很烂的动作,它会输出Hello <username>!,其中username直接从$_GET中获取。

准备

按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的应用。

如何做…

执行如下步骤:

  1. 首先,我们需要一个控制器。因此,创建protected/controllers/LogController.php
  1. <?php
  2. namespace app\controllers;
  3. use yii\web\Controller;
  4. class LogController extends Controller
  5. {
  6. public function actionIndex()
  7. {
  8. return 'Hello, ' . $_GET['username'];
  9. }
  10. }
  1. 现在,如果我们运行index动作,我们将会得到一个错误信息,Undefined index: username。配置logger将这样的错误写入到文件:
  1. config/web.php
  1. 'components'=>[
  2. ...
  3. 'log' => [
  4. 'targets' => [
  5. [
  6. 'class' => 'yii\log\FileTarget',
  7. 'levels' => ['error'],
  8. 'logFile' => '@runtime/logs/errors.log',
  9. ],
  10. ],
  11. ],
  12. ],
  1. 在次运行index动作,并检查runtime/logs/errors.log。将会有如下日志信息:
  1. 2016-03-06 09:27:09 [127.0.0.1][-][-][error][yii\base\
  2. ErrorException:8] exception 'yii\base\ErrorException' with
  3. message 'Undefined index: username' in /controllers/
  4. LogController.php:11
  5. Stack trace:
  6. #0 /yii2/base/InlineAction.php(55): ::call_user_func_array()
  7. #1 /yii2/base/Controller.php(151): yii\base\
  8. InlineAction->runWithParams()
  9. #2 /yii2/base/Module.php(455): yii\base\Controller->runAction()
  10. #3 /yii2/web/Application.php(84): yii\base\Module->runAction()
  11. #4 /yii2/base/Application.php(375): yii\web\
  12. Application->handleRequest()
  13. #5 /web/index.php(12): yii\base\Application->run()
  14. #6 {main}
  15. 2016-03-06 09:27:09 [127.0.0.1][-][-][info][application] $_GET
  16. = [
  17. 'r' => 'log/index'
  18. ]
  19. $_COOKIE = [
  20. '_csrf' => 'ca689043348e...a69ea:2:{i:0;s:...\"DSS...KJ\";}'
  21. 'PHPSESSID' => '30584oqhat4ek8b0hrqsapsbf4'
  22. ]
  23. $_SERVER = [
  24. 'USER' => 'www-data'
  25. 'HOME' => '/var/www'
  26. 'FCGI_ROLE' => 'RESPONDER'
  27. 'QUERY_STRING' => 'r=log/index'
  28. ...
  29. 'PHP_SELF' => '/index.php'
  30. 'REQUEST_TIME_FLOAT' => 1459934829.3067
  31. 'REQUEST_TIME' => 1459934829
  32. ]
  1. 现在我们可以将我们的应用给一个测试组并不时的检查错误日志。默认情况下,错误报告日志包含了$_GET$_POST$_FILES$_COOKIE$_SESSION$_SERVER变量中的所有的值。如果你不希望展示所有的值,你可以指定一个自定义的变量列表:
  1. 'log' => [
  2. 'targets' => [
  3. [
  4. 'class' => 'yii\log\FileTarget',
  5. 'levels' => ['error'],
  6. 'logVars' => ['_GET', '_POST'],
  7. 'logFile' => '@runtime/logs/errors.log',
  8. ],
  9. ],
  10. ],
  1. 在这个例子中,报告只包含$_GET$_POST两个数组:
  1. ...
  2. 2016-04-06 09:49:08 [127.0.0.1][-][-][info][application] $_GET
  3. = [ 'r' => 'log/index' ]

工作原理…

Yii在打印错误日志信息时,添加了执行上下文和环境的完整信息。如果我们手动打一个日志消息,我们可能知道我们需要的信息,所以我们可以设置一些目标选项来我们真正需要的东西:

  1. 'log' => [
  2. 'targets' => [
  3. [
  4. 'class' => 'yii\log\FileTarget',
  5. 'levels' => ['error'],
  6. 'logVars' => ['_GET', '_POST'],
  7. 'logFile' => '@runtime/logs/errors.log',
  8. ],
  9. ],
  10. ],

先前的代码会将错误日志写到一个名叫errors的文件中,此外对于消息本身,它会将$_GET$_POST变量的内容打到日志中,如果这两个变量不为空的话。

参考