常见的独白实现 class
Monolog implementation with common class
我成功实现了用于测试目的的 Monolog 记录器。现在我正试图在一个项目中使用它。该项目不使用任何 MVC 框架。
我正在尝试编写一个通用 class 文件来包装对 Monolog 实例的访问。
普通class文件:文件: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);
}
}
其他文件: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');
}
}
至此效果很好,我想包括文件名、方法名、请求参数。但是我在日志中得到的是 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"} []
你们能帮忙解决这部分吗?
恐怕你的整个设计都是错误的。
与其在每次需要记录时都实例化一个新的 Logger
,不如创建一个 $logger
作为应用程序周围的服务。
在不了解您的应用程序的更多信息的情况下(并且必须重写您的应用程序会使问题 过于宽泛 ),很难猜测如何实现 依赖在此处注入。
但是一个简单而幼稚的方法是:
class users extends dbconnector {
protected $logger;
public function _construct(Logger $logger) {
$this->logger = $logger;
}
function login() {
$this->logger->info('User logged successfully');
}
}
然后:
$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
实例注入到需要它的对象中,您可以直接使用它而无需创建自己的 "wrapper"(在您的示例中设计不佳),并且日志文件中的输出将符合您的期望。
请注意,您没有使用 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;
}
您可以将它放在您 require_once
的文件中,并且在您需要访问记录器的每个地方,您可以简单地执行以下操作:
get_logger()->info('write to the log!');
这不是我认可的东西,而是一个糟糕的解决方法,可以让您在对其他 OOP 主题的理解有所进步之前继续前进。这只不过是一个穷人的人 singleton,这通常是一种无论如何都要避免的模式;但这现在可以帮助你..
WebProcessor
不会添加你需要的数据,我的意思是文件和行。
IntrospectionProcessor
满足您的需求,试试
$logger->pushProcessor(new IntrospectionProcessor());
我成功实现了用于测试目的的 Monolog 记录器。现在我正试图在一个项目中使用它。该项目不使用任何 MVC 框架。
我正在尝试编写一个通用 class 文件来包装对 Monolog 实例的访问。
普通class文件:文件: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);
}
}
其他文件: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');
}
}
至此效果很好,我想包括文件名、方法名、请求参数。但是我在日志中得到的是 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"} []
你们能帮忙解决这部分吗?
恐怕你的整个设计都是错误的。
与其在每次需要记录时都实例化一个新的 Logger
,不如创建一个 $logger
作为应用程序周围的服务。
在不了解您的应用程序的更多信息的情况下(并且必须重写您的应用程序会使问题 过于宽泛 ),很难猜测如何实现 依赖在此处注入。
但是一个简单而幼稚的方法是:
class users extends dbconnector {
protected $logger;
public function _construct(Logger $logger) {
$this->logger = $logger;
}
function login() {
$this->logger->info('User logged successfully');
}
}
然后:
$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
实例注入到需要它的对象中,您可以直接使用它而无需创建自己的 "wrapper"(在您的示例中设计不佳),并且日志文件中的输出将符合您的期望。
请注意,您没有使用 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;
}
您可以将它放在您 require_once
的文件中,并且在您需要访问记录器的每个地方,您可以简单地执行以下操作:
get_logger()->info('write to the log!');
这不是我认可的东西,而是一个糟糕的解决方法,可以让您在对其他 OOP 主题的理解有所进步之前继续前进。这只不过是一个穷人的人 singleton,这通常是一种无论如何都要避免的模式;但这现在可以帮助你..
WebProcessor
不会添加你需要的数据,我的意思是文件和行。
IntrospectionProcessor
满足您的需求,试试
$logger->pushProcessor(new IntrospectionProcessor());