首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有公共类的Monolog实现

具有公共类的Monolog实现
EN

Stack Overflow用户
提问于 2018-06-07 22:54:54
回答 2查看 2K关注 0票数 4

为了测试目的,我成功地实现了一个Monolog记录器。现在我正试着在一个项目中使用它。这个项目不使用任何MVC框架。

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

公共类文件: file: app_log.php

代码语言:javascript
复制
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);
  }  
}

其他文件: users.php

代码语言:javascript
复制
include_once 'app_log.php';
class users extends dbconnector{
    function login(){
      // Some project code. 
      $logger = new app_log();
      $logger->info('User logged successfully');
    }
}

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

示例:

代码语言:javascript
复制
[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"} []

你们能帮忙吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-11 06:30:06

恐怕你的整个设计都错了。

与其每次需要日志时实例化一个新的Logger,不如创建一个单独的$logger,以便在应用程序周围作为服务使用。

如果不了解更多关于应用程序的信息(而且必须重写应用程序将使问题变得过于宽泛),很难猜测如何在这里实现依赖注入

但一种简单化和天真的做法是:

代码语言:javascript
复制
class users extends dbconnector {

    protected $logger;

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

    function login() {
      $this->logger->info('User logged successfully');
    }
}

然后:

代码语言:javascript
复制
$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);

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

注意,您没有使用IntrospectionProcessor,您需要使用它来捕获文件名和文件行号。在上面的例子中,我还在$logger ( Logger实例)中推送它。

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

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

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

例如:

代码语言:javascript
复制
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;
}

您可以将其放入您require_once的文件中,在每个需要访问记录器的地方,您可以简单地这样做:

代码语言:javascript
复制
 get_logger()->info('write to the log!');

--这不是我支持的东西,但对于您来说,这是一个很难解决的方法,直到您对其他OOP主题有了一定的了解为止。这不过是一个穷人的男人辛格尔顿,这通常是一种可以避免的模式,但这可能对你现在有帮助。

票数 5
EN

Stack Overflow用户

发布于 2018-06-11 06:31:18

WebProcessor不会添加您需要的数据,我指的是文件和行。

IntrospectionProcessor做你需要的事,试一试

代码语言:javascript
复制
$logger->pushProcessor(new IntrospectionProcessor());
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50751195

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档