Skip to content

Commit

Permalink
Additional logging placeholders are now replaced, and filenames are c…
Browse files Browse the repository at this point in the history
…leaned.
  • Loading branch information
lonnieezell committed Jan 13, 2016
1 parent 4cb5eb0 commit 01889eb
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 1 deletion.
90 changes: 89 additions & 1 deletion system/Log/Logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,10 @@ public function log($level, $message, array $context = []): bool
* {session_vars}
* {post_vars}
* {get_vars}
* {env}
* {env:foo}
* {file}
* {line}
*
* @param $message
* @param array $context
Expand All @@ -336,7 +340,7 @@ protected function interpolate($message, array $context = [])
// or error, both of which implement the 'Throwable' interface.
if ($key == 'exception' && $val instanceof \Throwable)
{
$val = $val->getMessage().' '.$val->getFile().':'. $val->getLine();
$val = $val->getMessage().' '.$this->cleanFileNames($val->getFile()).':'. $val->getLine();
}

// todo - sanitize input before writing to file?
Expand All @@ -346,6 +350,31 @@ protected function interpolate($message, array $context = [])
// Add special placeholders
$replace['{post_vars}'] = '$_POST: '.print_r($_POST, true);
$replace['{get_vars}'] = '$_GET: '.print_r($_GET, true);
$replace['{env}'] = ENVIRONMENT;

// Allow us to log the file/line that we are logging from
if (strpos($message, '{file}') !== false)
{
list($file, $line) = $this->determineFile();

$replace['{file}'] = $file;
$replace['{line}'] = $line;
}

// Match up environment variables in {env:foo} tags.
if (strpos($message, 'env:') !== false)
{
preg_match('/env:[^}]+/', $message, $matches);

if (count($matches))
{
foreach ($matches as $str)
{
$key = str_replace('env:', '', $str);
$replace["{{$str}}"] = $_ENV[$key] ?? 'n/a';
}
}
}

if (isset($_SESSION))
{
Expand All @@ -358,4 +387,63 @@ protected function interpolate($message, array $context = [])

//--------------------------------------------------------------------

/**
* Determines the current file/line that the log method was called from.
* by analyzing the backtrace.
*
* @return array
*/
public function determineFile()
{
// Determine the file and line by finding the first
// backtrace that is not part of our logging system.
$trace = debug_backtrace();
$file = null;
$line = null;

foreach ($trace as $row)
{
if (in_array($row['function'], ['interpolate', 'determineFile', 'log', 'log_message']))
{
continue;
}

$file = $row['file'] ?? isset($row['object']) ? get_class($row['object']) : 'unknown';
$line = $row['line'] ?? $row['function'] ?? 'unknown';
break;
}

return [
$file,
$line
];
}

//--------------------------------------------------------------------


/**
* Cleans the paths of filenames by replacing APPPATH, BASEPATH, FCPATH
* with the actual var. i.e.
*
* /var/www/site/application/controllers/Home.php
* becomes:
* APPPATH/controllers/Home.php
*
* @param $file
*
* @return mixed
*/
protected function cleanFileNames($file)
{
$file = str_replace(APPPATH, 'APPPATH/', $file);
$file = str_replace(BASEPATH, 'BASEPATH/', $file);
$file = str_replace(FCPATH, 'FCPATH/', $file);

return $file;
}

//--------------------------------------------------------------------


}
59 changes: 59 additions & 0 deletions tests/Log/LoggerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,65 @@ public function testLogInterpolatesSession()

//--------------------------------------------------------------------

public function testLogInterpolatesCurrentEnvironment()
{
$config = new LoggerConfig();

$logger = new Logger($config);

$expected = 'DEBUG - '.date('Y-m-d').' --> Test message '. ENVIRONMENT;

$logger->log('debug', 'Test message {env}');

$logs = TestHandler::getLogs();

$this->assertEquals(1, count($logs));
$this->assertEquals($expected, $logs[0]);
}

//--------------------------------------------------------------------

public function testLogInterpolatesEnvironmentVars()
{
$config = new LoggerConfig();

$logger = new Logger($config);

$_ENV['foo'] = 'bar';

$expected = 'DEBUG - '.date('Y-m-d').' --> Test message bar';

$logger->log('debug', 'Test message {env:foo}');

$logs = TestHandler::getLogs();

$this->assertEquals(1, count($logs));
$this->assertEquals($expected, $logs[0]);
}

//--------------------------------------------------------------------

public function testLogInterpolatesFileAndLine()
{
$config = new LoggerConfig();

$logger = new Logger($config);

$_ENV['foo'] = 'bar';

// For whatever reason, this will often be the class/function instead of file and line.
$expected = 'DEBUG - '.date('Y-m-d').' --> Test message LoggerTest testLogInterpolatesFileAndLine';

$logger->log('debug', 'Test message {file} {line}');

$logs = TestHandler::getLogs();

$this->assertEquals(1, count($logs));
$this->assertEquals($expected, $logs[0]);
}

//--------------------------------------------------------------------

public function testEmergencyLogsCorrectly()
{
$config = new LoggerConfig();
Expand Down

0 comments on commit 01889eb

Please sign in to comment.