Hi, using Cakephp 3.6, is there any way, with minimal modifications, to log the file and line (and perhaps class and function) where the log message was fired, like log4j does?
Up? Searched a lot without finding any solution…
https://book.cakephp.org/3.0/en/core-libraries/logging.html#creating-log-adapters
+
http://php.net/manual/en/function.debug-backtrace.php
Proof of concept :
Sorry, I won’t ask more… If this is useful for anyone; create a file inside src\Log\Engine\MyLog.php
:
<?php
namespace App\Log\Engine;
use App\ArrayUtils;
use Cake\Log\Engine\FileLog;
use Nette\Utils\Strings;
class MyLog extends FileLog
{
public function log($level, $message, array $context = [])
{
$cakeHome = realpath(dirname(realpath(__FILE__)) . DS . ".." . DS . ".." . DS . "..");
$stacks = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 4);
$stack = end($stacks);
$file = ArrayUtils::getString($stack, "file");
$relFile = $file;
if (Strings::startsWith($file, $cakeHome . DS)) {
$relFile = Strings::substring($file, strlen($cakeHome)+1);
}
$class = ArrayUtils::getString($stack, "class");
$function = ArrayUtils::getString($stack, "function");
$line = ArrayUtils::getInt($stack, "line");
parent::log($level, "{$class}::{$function}::{$line} - {$message}", $context);
}
}
ArrayUtils
is just a helper to extract data from an array. Then, configure Cake to use this logger in app.php
:
'error' => [
'className' => 'App\Log\Engine\MyLog',
'path' => LOGS,
'file' => 'error',
'url' => env('LOG_ERROR_URL', null),
'scopes' => false,
'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'],
],