admin管理员组文章数量:1313925
What I have
I'm using log4php, but this could also apply to log4perl, log4j, or any other log4* modules.
I have two different functions: funcA()
and funcB()
. Currently everything logs to one file, and I'd like to separate them for each function. funcA()
and funcB()
share some classes and methods. Each class has code that gets the logger for the class. For example:
class DB {
private static $logger;
private static function getLogger() {
if (is_null(self::$logger)) {
self::$logger = Logger::getLogger(__CLASS__);
}
return self::$logger;
}
public function getData() {
// gets some data from the database
self::getLogger->debug("Got some data");
}
}
funcA()
, funcB()
:
function funcA() {
// Do some funcA-ish stuff
$db = new DB();
$data = $db->getData();
// Do some more funcA-ish stuff
}
function funcB() {
// Do some funcB-ish stuff
$db = new DB();
$data = $db->getData();
// Do some more funcB-ish stuff
}
My log4phpConf.xml
has one file appender for the one log file, and a different Logger for each class, so that I can control the log level for each class.
What I want
I'd like to have two different log files, one for funcA()
and one for funcB()
. But I still want to be able to control the log level for each class.
So the first step is to set up two File Appenders, one for each function. Then, I would need to decide which Appender to assign to each class logger. Some loggers are exclusive to either funcA
or funcB
processing, so those are easy. But for the ones that are shared, I would have to create two loggers for each class, and somehow know which logger to use in each shared method. This would be a maintenance nightmare.
So my thought was to just have two Loggers, one for each function, and then just pass the logger instance into each class so the class can use it. But I'm not sure if that's the right approach, and I wonder if I would then lose my ability to control the log level for each class.
Am I approaching this the wrong way?
What I have
I'm using log4php, but this could also apply to log4perl, log4j, or any other log4* modules.
I have two different functions: funcA()
and funcB()
. Currently everything logs to one file, and I'd like to separate them for each function. funcA()
and funcB()
share some classes and methods. Each class has code that gets the logger for the class. For example:
class DB {
private static $logger;
private static function getLogger() {
if (is_null(self::$logger)) {
self::$logger = Logger::getLogger(__CLASS__);
}
return self::$logger;
}
public function getData() {
// gets some data from the database
self::getLogger->debug("Got some data");
}
}
funcA()
, funcB()
:
function funcA() {
// Do some funcA-ish stuff
$db = new DB();
$data = $db->getData();
// Do some more funcA-ish stuff
}
function funcB() {
// Do some funcB-ish stuff
$db = new DB();
$data = $db->getData();
// Do some more funcB-ish stuff
}
My log4phpConf.xml
has one file appender for the one log file, and a different Logger for each class, so that I can control the log level for each class.
What I want
I'd like to have two different log files, one for funcA()
and one for funcB()
. But I still want to be able to control the log level for each class.
So the first step is to set up two File Appenders, one for each function. Then, I would need to decide which Appender to assign to each class logger. Some loggers are exclusive to either funcA
or funcB
processing, so those are easy. But for the ones that are shared, I would have to create two loggers for each class, and somehow know which logger to use in each shared method. This would be a maintenance nightmare.
So my thought was to just have two Loggers, one for each function, and then just pass the logger instance into each class so the class can use it. But I'm not sure if that's the right approach, and I wonder if I would then lose my ability to control the log level for each class.
Am I approaching this the wrong way?
Share Improve this question asked Jan 30 at 14:03 livefree75livefree75 7638 silver badges21 bronze badges 3 |2 Answers
Reset to default 1It's actually not maintenance nightmare to keep track of the logger. Take into account this abstract fantasy code:
class Something {
protected $loggers = [
'A' => getALogger(),
'B' => getBLogger()
];
protected $currentLoggerKey = null;
public function getLogger() {
return $this->loggers[$this->currentLoggerKey];
}
//...
public function A() {
$this->currentLoggerKey = 'A';
//...
}
public function B() {
$this->currentLoggerKey = 'B';
}
}
And otherwise in each method you just call getALogger()
, and, if A()
or B()
was executed, then it was properly initialized.
It seems you are already familiar with the __CLASS__
magic constant and that it suffices to fetch lookup the log in your Logger
class:
Logger::getLogger(__CLASS__);
You can apply that same principle within any of your functions, too, by using the __FUNCTION__
constant:
function funcA()
{
$logger = Logger::getLogger(__FUNCTION__);
// Do some funcA-ish stuff
$db = new DB();
$data = $db->getData();
// Do some more funcA-ish stuff
}
If now your problem is that the new DB instance uses its own __CLASS__
logger, you can give it an instance property and directly inject the logger when you create it preventing a setting the global static for the class:
function funcA()
{
$logger = Logger::getLogger(__FUNCTION__);
// Do some funcA-ish stuff
$db = new DB($logger);
$data = $db->getData();
// Do some more funcA-ish stuff
}
class DB
{
private static ?Logger $defaultLogger = null;
public function __construct(private ?Logger $logger = null) {}
private static function getDefaultLogger(): Logger
{
return self::$defaultLogger ??= new Logger(__CLASS__);
}
private function getLogger(): Logger
{
return $this->logger ??= self::getDefaultLogger();
}
public function getData(): array
{
// gets some data from the database
$this->getLogger()->debug("Got some data");
}
}
This is not specific to Log4Php only, and is called inversion of control in the Java World (as you mention Log4J), otherwise known as dependency injection and is leading to fine-grained configurability.
本文标签: phpLog to two different log files from two different functions that share classesStack Overflow
版权声明:本文标题:php - Log to two different log files from two different functions that share classes - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741960749a2407262.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
$app = LoggerAppenderPool::get("AppenderA");
or$app = LoggerAppenderPool::get("AppenderB");
, and thenLogger::getRootLogger()->addAppender($app);
. Then I could still control each class's log level via the config file. – livefree75 Commented Jan 31 at 5:13