使用公共类实现 Monolog

Raj*_*aja 4 php oop logging monolog

我成功地实现了用于测试目的的 Monolog 记录器。现在我正在尝试在项目中使用它。该项目不使用任何MVC框架。

我正在尝试编写一个公共类文件来包装对 Monolog 实例的访问。

常用类文件: 文件:app_log.php

require 'autoload.php';
use Monolog\Logger;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Processor\UidProcessor;
use Monolog\Processor\WebProcessor;
use Monolog\Processor\MemoryUsageProcessor;
use Monolog\Processor\ProcessIdProcessor;
use Monolog\Formatter\LineFormatter;

class app_log {
  public function info(){
    $logger = new Logger('applog');
    $handler = new RotatingFileHandler('useractivity.log', 0, Logger::INFO);
    $handler->setFormatter(new LineFormatter("[%datetime%] %extra.process_id% %channel%.%level_name%: %message% %extra% %context% \n"));
    $logger->pushHandler($handler);
    $logger->pushProcessor(new WebProcessor);
  }  
}
Run Code Online (Sandbox Code Playgroud)

其他文件:users.php

include_once 'app_log.php';
class users extends dbconnector{
    function login(){
      // Some project code. 
      $logger = new app_log();
      $logger->info('User logged successfully');
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,效果很好,我想包括文件名、方法名称、请求参数。但我得到的是app_log.php文件名users.php,而方法名称则'info''login'日志中。

例子:

[2018-06-07 20:55:50] 4410 applog.INFO: User logged successfully {"file":"/var/www/portal/lib/app_log.php","line":59,"class":"app_log","function":"info"} []
Run Code Online (Sandbox Code Playgroud)

你们能帮忙解决这部分吗?

yiv*_*ivi 5

恐怕你的整个设计都是错误的。

Logger您应该创建一个单一的实例$logger以用作应用程序周围的服务,而不是每次需要登录时都实例化一个新的。

如果不了解有关您的应用程序的更多信息(并且必须重写您的应用程序无论如何都会使问题变得过于广泛),则很难猜测如何在这里实现依赖项注入

但一个简单而幼稚的方法是:

class users extends dbconnector {

    protected $logger;

    public function _construct(Logger $logger) {
       $this->logger = $logger;
    }

    function login() {
      $this->logger->info('User logged successfully');
    }
}
Run Code Online (Sandbox Code Playgroud)

进而:

$logger  = new Logger('applog');
$handler = new RotatingFileHandler('useractivity.log', 0, Logger::INFO);
$handler->setFormatter(new LineFormatter("[%datetime%] %extra.process_id% %channel%.%level_name%: %message% %extra% %context% \n"));
$logger->pushHandler($handler);
$logger->pushProcessor(new WebProcessor);
$logger->pushProcessor(new IntrospectionProcessor);

$users = new users($logger);
Run Code Online (Sandbox Code Playgroud)

如果您将该Logger实例注入需要它的对象中,则可以直接使用它,而无需创建自己的“包装器”(在您的示例中设计得很糟糕),并且日志文件中的输出将符合您的期望。

请注意,您没有使用IntrospectionProcessor,您需要它来捕获文件名和文件行号。在上面的示例中,我还将其推入$logger实例中Logger

(还要注意,简单地将此处理器添加到您的代码中并不能解决您的问题,因为对的调用Logger::info()始终发生在app_log::info())。

请记住,您需要添加相应的use语句:use Monolog\Processor\IntrospectionProcessor;

我不知道你的系统的所有细节,也无法为你构建所有的细节,但如果依赖注入对你来说仍然太多,你可以暂时用全局状态方法作弊。

例如:

function get_logger() {
   static $logger;

   if ($logger !== null) {
      return $logger;
   }

   $logger  = new Logger('applog');
   $handler = new RotatingFileHandler('useractivity.log', 0, Logger::INFO);
   $handler->setFormatter(new LineFormatter("[%datetime%] %extra.process_id% %channel%.%level_name%: %message% %extra% %context% \n"));
   $logger->pushHandler($handler);
   $logger->pushProcessor(new WebProcessor);
   $logger->pushProcessor(new IntrospectionProcessor);

   return $logger;
}
Run Code Online (Sandbox Code Playgroud)

您可以将其放入您的文件中require_once,并且在需要访问记录器的每个位置中,您可以简单地执行以下操作:

 get_logger()->info('write to the log!');
Run Code Online (Sandbox Code Playgroud)

这不是我所赞同的,但在您对其他 OOP 主题的理解有所进步之前,这是一个糟糕的解决方法。这只不过是一个穷人的单身人士,无论如何,这通常是一种应该避免的模式;但这现在可以帮助你..