Question

using the apache log4php and its being called by a helper method in my class:

class MyClass{

    function log($msg, $level='info'){
        $log = @Logger::getLogger("MyLogger");
        $log->$level($msg);
    }
}

The issue with the above code is the file:line column in logger will always report the line num for the help method. I can get the original line num and file that calls the helper method using php's debug_backtrace():

$bt = debug_backtrace();
$caller = array_shift($bt);

So my question is, is there a way within my helper method to set the file:line column? I'm thinking that I might need to overwrite a Logger::method or something?

Was it helpful?

Solution

My solution is a hack to the source code, which should be avoided. There is an answer by @Sven that should cover most scenarios but for me my log calls have to go through a helper method.

In the LoggerLoggingEvent.php class file add the method:

/**
 * Set the event location info
 * @param LoggerLocationInfo $locationInfo
 */
public function setLocationInformation(LoggerLocationInfo $locationInfo) {
    $this->locationInfo = $locationInfo;
}

Then in your log class method use:

/**
 * Log an INFO message
 * @param string $msg The message to log
 * @return none
 */
public function log($msg, $level='info'){

    // Manually construct a logging event
    $level = LoggerLevel::toLevel($level);
    $logger = Logger::getLogger(__CLASS__);
    $event = new LoggerLoggingEvent(__CLASS__, $logger, $level, $msg);

    // Override the location info
    $bt = debug_backtrace();
    $caller = array_shift($bt);
    $location = new LoggerLocationInfo($caller);
    $event->setLocationInformation($location);

    // Log it
    $logger->logEvent($event);
}

OTHER TIPS

The solution is not to have a log function on your own, but to use the logger right there where you now make the call to your own log function.

class MyClass {
    public function __construct() {
        $this->logger = Logger::getLogger("MyLogger");
    }
    public function anywhere() {
        // $this->log("Foo"); // Don't do this,
        $this->logger->info("Foo"); // do this.
    }
}

A generic logging framework cannot know how many layers of indirection your log call really took, and strip these from the backtrace. You also loose the ability to pass exceptions to the logger.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top