diff options
author | Kenny Katzgrau <ext.kkatzgrau@hexiscyber.com> | 2015-03-05 15:00:00 -0500 |
---|---|---|
committer | Kenny Katzgrau <ext.kkatzgrau@hexiscyber.com> | 2015-03-05 15:00:00 -0500 |
commit | 969d38c5e3816eee11adce1d10d61754aa71c7a3 (patch) | |
tree | 04c8365547c4f4e5ba02c2c0468c8ad612838f90 | |
parent | 26b82385fac6f0a8ef55e3fe8612a2f6b1c8426b (diff) | |
download | KLogger-969d38c5e3816eee11adce1d10d61754aa71c7a3.zip KLogger-969d38c5e3816eee11adce1d10d61754aa71c7a3.tar.gz KLogger-969d38c5e3816eee11adce1d10d61754aa71c7a3.tar.bz2 |
Add third options param in constructor, add support for prefixes and extensions.
-rw-r--r-- | .gitignore | 3 | ||||
-rwxr-xr-x | src/Logger.php | 74 | ||||
-rw-r--r-- | tests/LoggerTest.php | 67 |
3 files changed, 134 insertions, 10 deletions
@@ -1,3 +1,4 @@ /tests/logs/*.txt +/tests/logs/*.log /vendor/ -composer.lock
\ No newline at end of file +composer.lock diff --git a/src/Logger.php b/src/Logger.php index 9568385..a563724 100755 --- a/src/Logger.php +++ b/src/Logger.php @@ -29,6 +29,22 @@ use Psr\Log\LogLevel; class Logger extends AbstractLogger
{
/**
+ * KLogger options
+ * Anything options not considered 'core' to the logging library should be
+ * settable view the third parameter in the constructor
+ *
+ * Core options include the log file path and the log threshold
+ *
+ * @var array
+ */
+ private $options = array (
+ 'prefix' => 'log_',
+ 'extension' => 'txt',
+ 'dateFormat' => 'Y-m-d G:i:s.u',
+ 'flushFrequency' => false
+ );
+
+ /**
* Path to the log file
* @var string
*/
@@ -40,6 +56,16 @@ class Logger extends AbstractLogger */
private $logLevelThreshold = LogLevel::DEBUG;
+ /**
+ * The number of lines logged in this instance's lifetime
+ * @var int
+ */
+ private $logLineCount = 0;
+
+ /**
+ * Log Levels
+ * @var array
+ */
private $logLevels = array(
LogLevel::EMERGENCY => 0,
LogLevel::ALERT => 1,
@@ -58,10 +84,11 @@ class Logger extends AbstractLogger private $fileHandle = null;
/**
- * Valid PHP date() format string for log timestamps
+ * This holds the last line logged to the logger
+ * Used for unit tests
* @var string
*/
- private $dateFormat = 'Y-m-d G:i:s.u';
+ private $lastLine = '';
/**
* Octal notation for default permissions of the log file
@@ -70,25 +97,29 @@ class Logger extends AbstractLogger private $defaultPermissions = 0777;
/**
+ /**
* Class constructor
*
- * @param string $logDirectory File path to the logging directory
+ * @param string $logDirectory File path to the logging directory
* @param string $logLevelThreshold The LogLevel Threshold
+ * @param string $logFilePrefix The prefix for the log file name
+ * @param string $logFileExt The extension for the log file
*/
- public function __construct($logDirectory, $logLevelThreshold = LogLevel::DEBUG)
+ public function __construct($logDirectory, $logLevelThreshold = LogLevel::DEBUG, $options = array())
{
$this->logLevelThreshold = $logLevelThreshold;
+ $this->options = array_merge($this->options, $options);
$logDirectory = rtrim($logDirectory, '\\/');
if (! file_exists($logDirectory)) {
mkdir($logDirectory, $this->defaultPermissions, true);
}
- $this->logFilePath = $logDirectory.DIRECTORY_SEPARATOR.'log_'.date('Y-m-d').'.txt';
+ $this->logFilePath = $logDirectory.DIRECTORY_SEPARATOR.$this->options['prefix'].date('Y-m-d').'.'.$this->options['extension'];
if (file_exists($this->logFilePath) && !is_writable($this->logFilePath)) {
throw new RuntimeException('The file could not be written to. Check that appropriate permissions have been set.');
}
-
+
$this->fileHandle = fopen($this->logFilePath, 'a');
if ( ! $this->fileHandle) {
throw new RuntimeException('The file could not be opened. Check permissions.');
@@ -112,7 +143,7 @@ class Logger extends AbstractLogger */
public function setDateFormat($dateFormat)
{
- $this->dateFormat = $dateFormat;
+ $this->options['dateFormat'] = $dateFormat;
}
/**
@@ -153,11 +184,38 @@ class Logger extends AbstractLogger if (! is_null($this->fileHandle)) {
if (fwrite($this->fileHandle, $message) === false) {
throw new RuntimeException('The file could not be written to. Check that appropriate permissions have been set.');
+ } else {
+ $this->lastLine = trim($message);
+ $this->logLineCount++;
+
+ if ($this->options['flushFrequency'] && $this->logLineCount % $this->options['flushFrequency'] == 0) {
+ fflush($this->fileHandle);
+ }
}
}
}
/**
+ * Get the file path that the log is currently writing to
+ *
+ * @return string
+ */
+ public function getLogFilePath()
+ {
+ return $this->logFilePath;
+ }
+
+ /**
+ * Get the last line logged to the log file
+ *
+ * @return string
+ */
+ public function getLastLogLine()
+ {
+ return $this->lastLine;
+ }
+
+ /**
* Formats the message for logging.
*
* @param string $level The Log Level of the message
@@ -188,7 +246,7 @@ class Logger extends AbstractLogger $micro = sprintf("%06d", ($originalTime - floor($originalTime)) * 1000000);
$date = new DateTime(date('Y-m-d H:i:s.'.$micro, $originalTime));
- return $date->format($this->dateFormat);
+ return $date->format($this->options['dateFormat']);
}
/**
diff --git a/tests/LoggerTest.php b/tests/LoggerTest.php index ebe65d8..355b045 100644 --- a/tests/LoggerTest.php +++ b/tests/LoggerTest.php @@ -1,20 +1,85 @@ <?php use Katzgrau\KLogger\Logger; +use Psr\Log\LogLevel; class LoggerTest extends PHPUnit_Framework_TestCase { private $logPath; + private $logger; + private $errLogger; public function setUp() { $this->logPath = __DIR__.'/logs'; - $this->logger = new Logger($this->logPath); + $this->logger = new Logger($this->logPath, LogLevel::DEBUG, array ('flushFrequency' => 1)); + $this->errLogger = new Logger($this->logPath, LogLevel::ERROR, array ( + 'extension' => 'log', + 'prefix' => 'error_', + 'flushFrequency' => 1 + )); } public function testImplementsPsr3LoggerInterface() { $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->logger); } + + public function testAcceptsExtension() + { + $this->assertStringEndsWith('.log', $this->errLogger->getLogFilePath()); + } + + public function testAcceptsPrefix() + { + $filename = basename($this->errLogger->getLogFilePath()); + $this->assertStringStartsWith('error_', $filename); + } + + public function testWritesBasicLogs() + { + $this->logger->log(LogLevel::DEBUG, 'This is a test'); + $this->errLogger->log(LogLevel::ERROR, 'This is a test'); + + $this->assertTrue(file_exists($this->errLogger->getLogFilePath())); + $this->assertTrue(file_exists($this->logger->getLogFilePath())); + + $this->assertLastLineEquals($this->logger); + $this->assertLastLineEquals($this->errLogger); + } + + + public function assertLastLineEquals(Logger $logr) + { + $this->assertEquals($logr->getLastLogLine(), $this->getLastLine($logr->getLogFilePath())); + } + + public function assertLastLineNotEquals(Logger $logr) + { + $this->assertNotEquals($logr->getLastLogLine(), $this->getLastLine($logr->getLogFilePath())); + } + + private function getLastLine($filename) + { + $fp = fopen($filename, 'r'); + $pos = -2; // start from second to last char + $t = ' '; + + while ($t != "\n") { + fseek($fp, $pos, SEEK_END); + $t = fgetc($fp); + $pos = $pos - 1; + } + + $t = fgets($fp); + fclose($fp); + + return trim($t); + } + + public function tearDown() { + #@unlink($this->logger->getLogFilePath()); + #@unlink($this->errLogger->getLogFilePath()); + } } |