diff --git a/config/configuration.local.php b/config/configuration.local.php index 0b38f28..37a78aa 100644 --- a/config/configuration.local.php +++ b/config/configuration.local.php @@ -1,4 +1,5 @@ array( 'file' => '/var/www/webservice/logs/log.txt', 'format' => '%ip% - [%date%] - %status% %error% - %time% - %func%', - // The greater the verbosity, the more is displayed - // 0 : no log at all - // 1 : log summary - // 2 : log response - 'verbosity' => 1, + 'verbosity' => Logger::NORMAL, ), 'session' => array( 'save_path' => '' diff --git a/config/configuration.logger.normal.php b/config/configuration.logger.normal.php new file mode 100644 index 0000000..6ba548e --- /dev/null +++ b/config/configuration.logger.normal.php @@ -0,0 +1,17 @@ + array( + 'file' => realpath(dirname(__FILE__) . '/..') . '/log/log.txt', + 'format' => '%ip% - [%date%] - %status% %error% - %time% - %func%', + 'verbosity' => Logger::NORMAL, + ), + ); diff --git a/config/configuration.logger.quiet.php b/config/configuration.logger.quiet.php new file mode 100644 index 0000000..c191977 --- /dev/null +++ b/config/configuration.logger.quiet.php @@ -0,0 +1,18 @@ + array( + 'file' => realpath(dirname(__FILE__) . '/..') . '/log/log.txt', + 'format' => '%ip% - [%date%] - %status% %error% - %time% - %func%', + 'verbosity' => Logger::QUIET, + ), + ); + diff --git a/config/configuration.logger.verbose.php b/config/configuration.logger.verbose.php new file mode 100644 index 0000000..984ead3 --- /dev/null +++ b/config/configuration.logger.verbose.php @@ -0,0 +1,17 @@ + array( + 'file' => realpath(dirname(__FILE__) . '/..') . '/log/log.txt', + 'format' => '%ip% - [%date%] - %status% %error% - %time% - %func%', + 'verbosity' => Logger::VERBOSE, + ), + ); diff --git a/src/Utils/Configuration/Configuration.php b/src/Utils/Configuration/Configuration.php index 6568007..9de09be 100644 --- a/src/Utils/Configuration/Configuration.php +++ b/src/Utils/Configuration/Configuration.php @@ -51,12 +51,17 @@ class Configuration { * @param string $filePath * @return void */ - public static function setConfigFilePath($filePath) + public static function setConfigFilePath($filePath, $clearPrevious = false) { if (!file_exists($filePath)) { throw new \RuntimeException("The file path $filePath, does not exist"); } self::$customConfigFilePath = $filePath; + $instance = self::getInstance(); + if ($clearPrevious) { + $instance->clear(); + } + self::getInstance()->loadConfigFromFile(); } /** @@ -88,7 +93,7 @@ class Configuration { * @return void * @throws \RuntimeException */ - public function loadConfigFromFile() + private function loadConfigFromFile() { $this->setCustomConfig($this->getConfigFromFile()); } @@ -162,6 +167,14 @@ class Configuration { return $keys; } + /** + * Allow clearing previously loaded config + */ + public function clear() + { + $this->values = array(); + } + /** * @return string * @throws \Exception @@ -178,6 +191,7 @@ class Configuration { { return self::existsKeys(self::get(), self::parseKeys($keys)); } + /** * @param $name * @param mixed $default the default value for your configuration option diff --git a/src/Utils/Logger/Logger.php b/src/Utils/Logger/Logger.php index f52cf0c..81fe50c 100644 --- a/src/Utils/Logger/Logger.php +++ b/src/Utils/Logger/Logger.php @@ -8,6 +8,8 @@ class Logger { const QUIET = 0; const NORMAL = 1; const VERBOSE = 2; + const NO_FILE_LOGGED = ''; + const NO_LOG_YET_MSG = 'No log yet !'; private static $start; private static $data = array(); @@ -56,6 +58,25 @@ class Logger { ); } + /** + * Clear the static properties, needed for testging + */ + public static function clear() + { + self::$start = null; + self::$data = array(); + self::$log = ''; + } + + /** + * Flush previous static properties and start again + */ + public static function reset($data = array()) + { + self::clear(); + self::start($data); + } + /** * If $key is passed, creates/overwrites existing self::$data[$key] with $info * Otherwise, uses array_merge: @@ -98,6 +119,7 @@ class Logger { * - store the time lapse between start() and stop() calls in self::$data * * @param $data allow storing some info on stop + * @return string saved log message filepath */ public static function stop($data = null) { @@ -108,9 +130,11 @@ class Logger { $time = (microtime(true) - self::$start) * 1000; self::$data['time'] = round($time, 2).'ms'; + $savedLogMessageFilePath = self::NO_FILE_LOGGED; if (Configuration::get('log.verbosity') > Logger::QUIET) { - self::saveLogMessageToFile(self::generateLogMessage()); + $savedLogMessageFilePath = self::saveLogMessageToFile(self::generateLogMessage()); } + return $savedLogMessageFilePath; } /** @@ -122,25 +146,32 @@ class Logger { $patterns = array_map(function($p) { return "%$p%"; }, array_keys(self::$data)); $msg = str_replace($patterns, array_values(self::$data), $format)."\n"; - return $msg . (strlen(self::$log) > 0 ? self::$log : ''); + return $msg . self::$log; } /** * * @param string $msg + * @return string saved log message file path */ private static function saveLogMessageToFile($msg) { $mostRecentLogFileName = Configuration::get('log.file'); + if (!file_exists($mostRecentLogFileName)) { + if (!is_dir(dirname($mostRecentLogFileName))) { + mkdir(dirname($mostRecentLogFileName), 0777, true); + } + touch($mostRecentLogFileName); + } + if(self::isMostRecentLogFileFromYesterday()) { self::makeRoomForNewLogFile($mostRecentLogFileName); - } else { - mkdir(dirname($mostRecentLogFileName), 0777, true); + touch($mostRecentLogFileName); } - touch($mostRecentLogFileName); file_put_contents($mostRecentLogFileName, $msg, FILE_APPEND | LOCK_EX); + return $mostRecentLogFileName; } /** @@ -149,9 +180,6 @@ class Logger { private static function isMostRecentLogFileFromYesterday() { $mostRecentLogFileName = Configuration::get('log.file'); - if (!file_exists($mostRecentLogFileName)) { - return false; - } return filemtime($mostRecentLogFileName) < strtotime("midnight"); } @@ -223,7 +251,7 @@ class Logger { return "$logFileBaseName.$next"; } - public static function data() + public static function getData() { return self::$data; } @@ -232,7 +260,7 @@ class Logger { { $file = Configuration::get('log.file'); if(! file_exists($file)) { - return 'No log yet !'; + return self::NO_LOG_YET_MSG; } $f = fopen($file, 'r'); diff --git a/tests/Utils/Configuration/ConfigurationTest.php b/tests/Utils/Configuration/ConfigurationTest.php index 27631b3..2dbac12 100644 --- a/tests/Utils/Configuration/ConfigurationTest.php +++ b/tests/Utils/Configuration/ConfigurationTest.php @@ -16,12 +16,14 @@ class ConfigurationTest extends TestCase ); protected $defaultConfig; - protected $dummyConfigFilePath; + protected $dummyConfigFilePath1; + protected $dummyConfigFilePath2; public function setUp() { $this->defaultConfig = array('session' => array('save_path' => session_save_path())); - $this->dummyConfigFilePath = realpath(dirname(__FILE__) . '/../../../config/configuration.local.php'); + $this->dummyConfigFilePath1 = realpath(dirname(__FILE__) . '/../../../config/configuration.local.php'); + $this->dummyConfigFilePath2 = realpath(dirname(__FILE__) . '/../../../config/configuration.logger.quiet.php'); } public function testConfigurationInstanceIsTheSame() @@ -118,14 +120,20 @@ class ConfigurationTest extends TestCase public function testDummyConfigFileExists() { - $this->assertEquals(file_exists($this->dummyConfigFilePath), true); + $this->assertEquals(file_exists($this->dummyConfigFilePath1), true); } public function testFileCustomConfigGetsLoadedIfFileExists() { $configPriorToFileLoading = Configuration::get(); - Configuration::setConfigFilePath($this->dummyConfigFilePath); - Configuration::getInstance()->loadConfigFromFile(); - $this->assertSame(Configuration::get(), array_replace_recursive($this->testConfig, include $this->dummyConfigFilePath)); + Configuration::setConfigFilePath($this->dummyConfigFilePath1); + $this->assertSame(Configuration::get(), array_replace_recursive($this->testConfig, include $this->dummyConfigFilePath1)); + } + + public function testSetConfigFilePathWithSecondParamTrueClearsPreviousConfig() + { + $configPriorToFileLoading = Configuration::get(); + Configuration::setConfigFilePath($this->dummyConfigFilePath2, true); + $this->assertSame(Configuration::get(), include $this->dummyConfigFilePath2); } } diff --git a/tests/Utils/Logger/LoggerTest.php b/tests/Utils/Logger/LoggerTest.php index ddcacc6..3223362 100644 --- a/tests/Utils/Logger/LoggerTest.php +++ b/tests/Utils/Logger/LoggerTest.php @@ -6,63 +6,168 @@ use PHPUnit\Framework\TestCase; class LoggerTest extends TestCase{ + private $logData = array(); + private $dummyConfigFileQuiet; + private $dummyConfigFileNormal; + private $dummyConfigFileVerbose; + + private $arbitraryMessage = '!some Ar.bitrary message 123alwer'; + + public function setUp() { - Logger::start(array()); + $this->logData = array( + 'ip' => '(n-a)', + 'date' => date('d.m.Y H:i:s'), + 'func' => '(none)', + 'version' => '(none)', + 'error' => '' + ); + + $this->dummyConfigFileQuiet = realpath(dirname(__FILE__) . '/../../../config/configuration.logger.quiet.php'); + $this->dummyConfigFileNormal = realpath(dirname(__FILE__) . '/../../../config/configuration.logger.normal.php'); + $this->dummyConfigFileVerbose = realpath(dirname(__FILE__) . '/../../../config/configuration.logger.verbose.php'); + + Configuration::setConfigFilePath($this->dummyConfigFileNormal, true); + + Logger::start(); } - public function tearDown() + public function testClearEmptiesData() { + Logger::start(); + Logger::clear(); + $this->assertEquals(empty(Logger::getData()), true); + } + public function testStartEmptyArrayInitializesDataDefaultKeys() + { + Logger::clear(); + Logger::start(array()); + $this->assertSame(array_diff_key(Logger::getData(), $this->logData), array()); } - public function testStartReturnsDefault() + public function testStartWithSomeArrayInitializesDataDefaultKeysPlusPassedOnes() { - $this->assertEquals(is_array(Logger::data()),true); + $paramArray = array( + 'someOtherInfo' => array(1,2,3), + 1 => 'haha' + ); + Logger::clear(); + Logger::start($paramArray); + $expectedDataArray = $paramArray + $this->logData; + $this->assertSame(array_diff_key(Logger::getData(),$expectedDataArray), array()); + } + + public function testStartWithParamArrayOverwritesDataKeyValueIfExists() + { + $overwriteDefaultValue = array('overwriteDefault', 'z', 3); + $paramArray = array('ip' => $overwriteDefaultValue); + Logger::clear(); + Logger::start($paramArray); + $this->assertSame(Logger::getData()['ip'], $overwriteDefaultValue); } public function testInfoWithKeyParamOverwritesDataKeyValue() { + $overwriteDefaultValue = array('overwriteDefault', 'z', 3); + Logger::clear(); + Logger::start(array()); + Logger::info($overwriteDefaultValue, 'ip'); + $this->assertSame(Logger::getData()['ip'], $overwriteDefaultValue); } public function testInfoWithoutKeyParamAndIntKeysGetRenumberedAndDontOverwrite() { + $paramArray = array(0 => 'c', 1 => 'd'); + Logger::clear(); + Logger::start(array(0 => 'a', 1 => 'b')); + Logger::info($paramArray); + $this->assertSame( + array_intersect(Logger::getData(), array('a', 'b', 'c', 'd')), + array('a', 'b', 'c', 'd') + ); } public function testLogDoesNotLogMessagesAccordingToVerbosityParamWhenSmallerThanConfig() { + Configuration::setConfigFilePath($this->dummyConfigFileNormal, true); + Logger::start(); + Logger::log($this->arbitraryMessage, Logger::VERBOSE); + Logger::stop(); + $this->assertSame( + strpos(Logger::getLastLogs(), $this->arbitraryMessage), + false + ); } public function testLogLogsMessagesWhenVerbosityParamIsGreaterThanConfigVerbosity() { + Configuration::setConfigFilePath($this->dummyConfigFileVerbose, true); + Logger::start(); + Logger::log($this->arbitraryMessage, Logger::NORMAL); + Logger::stop(); + $this->assertNotSame( + strpos(Logger::getLastLogs(), $this->arbitraryMessage), + false + ); } - public function testStopComputesElapsedTimeProperly() + public function testStopSavesComputesElapsedTime() { + Logger::clear(); + Logger::start(); + Logger::stop(); + $this->assertEquals(array_key_exists('time', Logger::getData()), true); } public function testStopDoesNotLogAnythingWhenConfigVerbosityIsQuiet() { + Configuration::setConfigFilePath($this->dummyConfigFileQuiet, true); $this->assertEquals(Configuration::get('log.verbosity'), Logger::QUIET); + $this->assertEquals(Logger::stop(), Logger::NO_FILE_LOGGED); } - public function testStopSavesLogFileWhenConfigVerbosityIsNotQuiet() + public function testStopReturnsSavedLogFileWhenConfigVerbosityIsNotQuiet() { + Configuration::setConfigFilePath($this->dummyConfigFileNormal, true); $this->assertNotEquals(Configuration::get('log.verbosity'), Logger::QUIET); - $this->assertNotEquals('No log yet !', Logger::getLastLogs()); + Logger::start(); + $stopReturn = Logger::stop(); + $this->assertEquals(realpath($stopReturn), realpath(Configuration::get('log.file'))); + } + + + private function removeLogs() + { + $logsDir = realpath(dirname(Configuration::get('log.file'))); + $files = glob("$logsDir/*"); + foreach($files as $file){ + if(is_file($file)) unlink($file); + } } - public function testDataReturnsArray() + public function testStopSavesLogFileWhenConfigVerbosityIsNotQuiet() { - $this->assertEquals(is_array(Logger::data()), true); + $this->removeLogs(); + Configuration::setConfigFilePath($this->dummyConfigFileNormal, true); + $this->assertNotEquals(Configuration::get('log.verbosity'), Logger::QUIET); + Logger::start(); + Logger::stop(); + $this->assertNotEquals(Logger::NO_LOG_YET_MSG, Logger::getLastLogs()); } - public function testGetLastLogsReturnsNoLogsWhenNoFileWithConfigLogFileNameExists() + public function testGetDataReturnsArray() { - $this->assertEquals('No log yet !', Logger::getLastLogs()); + $this->assertEquals(is_array(Logger::getData()), true); } - public function testGetLastLogsReturnsALogBufferWhenFileWithConfigLogFileNameExists() + public function testGetLastLogsReturnsNoLogsWhenCallingItBeforeStopOnAnEmptyDir() { + $this->removeLogs(); + Configuration::setConfigFilePath($this->dummyConfigFileNormal, true); + Logger::start(); + Logger::log('Some message', Logger::NORMAL); + $this->assertEquals(Logger::NO_LOG_YET_MSG, Logger::getLastLogs()); } }