From e5f59d39268b552c6b8416d5f0d8294ec19e26f3 Mon Sep 17 00:00:00 2001 From: n-peugnet Date: Tue, 21 Apr 2020 01:44:13 +0200 Subject: feat: add Logger class to log catched errors Previously, if Sentry was not enabled, the Exceptions weren't logged anywhere. I expect you to use this class in the future @vincent-peugnet ! --- .gitignore | 1 + app/class/Logger.php | 94 +++++++++++++++++++++ index.php | 4 + tests/LoggerTest.php | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 327 insertions(+) create mode 100644 app/class/Logger.php create mode 100644 tests/LoggerTest.php diff --git a/.gitignore b/.gitignore index e8830c1..98ddd57 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .vscode/* .env +*.log *.bundle.js *.bundle.js.map assets/render/* diff --git a/app/class/Logger.php b/app/class/Logger.php new file mode 100644 index 0000000..939dbf8 --- /dev/null +++ b/app/class/Logger.php @@ -0,0 +1,94 @@ + 0) { + self::write('ERROR', $msg, $args); + } + } + + /** + * Log a xarning message using printf format. + */ + public static function warning(string $msg, ...$args) + { + if (self::$verbosity > 1) { + self::write('WARN', $msg, $args); + } + } + + /** + * Log an info message using printf format. + */ + public static function info(string $msg, ...$args) + { + if (self::$verbosity > 2) { + self::write('INFO', $msg, $args); + } + } + + /** + * Log a debug message using printf format. + */ + public static function debug(string $msg, ...$args) + { + if (self::$verbosity > 3) { + self::write('DEBUG', $msg, $args); + } + } + + /** + * Log an exception. + */ + public static function exception(Throwable $e, bool $withtrace = false) + { + if (self::$verbosity > 0) { + $msg = $e->getMessage(); + if ($withtrace) { + // TODO: Maybe print a more beautiful stack trace. + $msg .= PHP_EOL . $e->getTraceAsString(); + } + self::write('ERROR', $msg); + } + } +} diff --git a/index.php b/index.php index f7f6843..fb05952 100644 --- a/index.php +++ b/index.php @@ -1,10 +1,13 @@ wakeup(); @@ -30,5 +33,6 @@ try { if (isreportingerrors()) { Sentry\captureException($e); } + Logger::exception($e, true); echo '

⚠ Woops ! There is a little problem :

', $e->getMessage(), "\n"; } diff --git a/tests/LoggerTest.php b/tests/LoggerTest.php new file mode 100644 index 0000000..18dcb02 --- /dev/null +++ b/tests/LoggerTest.php @@ -0,0 +1,228 @@ +logfile)) { + unlink($this->logfile); + } + } + + /** + * @test + */ + public function initTest(): void + { + Logger::init($this->logfile); + $this->assertFileExists($this->logfile, 'Log file has not been created.'); + $this->assertEmpty(file_get_contents($this->logfile)); + } + + /** + * @test + * @dataProvider errorNotLoggedProvider + */ + public function errorNotLoggedTest(int $verbosity): void + { + Logger::init($this->logfile, $verbosity); + Logger::error('Error.'); + $this->assertEmpty(file_get_contents($this->logfile)); + } + + public function errorNotLoggedProvider(): array + { + return [[0]]; + } + + /** + * @test + * @dataProvider errorLoggedProvider + */ + public function errorLoggedTest(int $verbosity, string $msg, array $args, string $expected): void + { + Logger::init($this->logfile, $verbosity); + Logger::error($msg, ...$args); + $expected = " [ ERROR ] tests/LoggerTest.php(55) $expected\n"; + $this->assertEquals($expected, substr(file_get_contents($this->logfile), 25)); + } + + public function errorLoggedProvider(): array + { + return [ + [1, 'Error %s.', ['test'], 'Error test.'], + [2, 'Error %s %d.', ['test', 2], 'Error test 2.'], + [3, 'Error.', [], 'Error.'], + [4, 'Error.', [], 'Error.'], + ]; + } + + /** + * @test + * @dataProvider warningNotLoggedProvider + */ + public function warningNotLoggedTest(int $verbosity): void + { + Logger::init($this->logfile, $verbosity); + Logger::warning('Error.'); + $this->assertEmpty(file_get_contents($this->logfile)); + } + + public function warningNotLoggedProvider(): array + { + return [[0], [1]]; + } + + /** + * @test + * @dataProvider warningLoggedProvider + */ + public function warningLoggedTest(int $verbosity, string $msg, array $args, string $expected): void + { + Logger::init($this->logfile, $verbosity); + Logger::warning($msg, ...$args); + $expected = " [ WARN ] tests/LoggerTest.php(93) $expected\n"; + $this->assertEquals($expected, substr(file_get_contents($this->logfile), 25)); + } + + public function warningLoggedProvider(): array + { + return [ + [2, 'Error %s.', ['test'], 'Error test.'], + [3, 'Error.', [], 'Error.'], + [4, 'Error.', [], 'Error.'], + ]; + } + + /** + * @test + * @dataProvider infoNotLoggedProvider + */ + public function infoNotLoggedTest(int $verbosity): void + { + Logger::init($this->logfile, $verbosity); + Logger::info('Error.'); + $this->assertEmpty(file_get_contents($this->logfile)); + } + + public function infoNotLoggedProvider(): array + { + return [[0], [1], [2]]; + } + + /** + * @test + * @dataProvider infoLoggedProvider + */ + public function infoLoggedTest(int $verbosity, string $msg, array $args, string $expected): void + { + Logger::init($this->logfile, $verbosity); + Logger::info($msg, ...$args); + $expected = " [ INFO ] tests/LoggerTest.php(130) $expected\n"; + $this->assertEquals($expected, substr(file_get_contents($this->logfile), 25)); + } + + public function infoLoggedProvider(): array + { + return [ + [3, 'Error %s.', ['test'], 'Error test.'], + [4, 'Error.', [], 'Error.'], + ]; + } + + /** + * @test + * @dataProvider debugNotLoggedProvider + */ + public function debugNotLoggedTest(int $verbosity): void + { + Logger::init($this->logfile, $verbosity); + Logger::debug('Error.'); + $this->assertEmpty(file_get_contents($this->logfile)); + } + + public function debugNotLoggedProvider(): array + { + return [[0], [1], [2], [3]]; + } + + /** + * @test + * @dataProvider debugLoggedProvider + */ + public function debugLoggedTest(int $verbosity, string $msg, array $args, string $expected): void + { + Logger::init($this->logfile, $verbosity); + Logger::debug($msg, ...$args); + $expected = " [ DEBUG ] tests/LoggerTest.php(166) $expected\n"; + $this->assertEquals($expected, substr(file_get_contents($this->logfile), 25)); + } + + public function debugLoggedProvider(): array + { + return [ + [4, 'Error %s.', ['test'], 'Error test.'], + ]; + } + + /** + * @test + * @dataProvider exceptionNotLoggedProvider + */ + public function exceptionNotLoggedTest(int $verbosity): void + { + Logger::init($this->logfile, $verbosity); + Logger::exception(new Exception('Error')); + $this->assertEmpty(file_get_contents($this->logfile)); + } + + public function exceptionNotLoggedProvider(): array + { + return [[0]]; + } + + /** + * @test + * @dataProvider exceptionLoggedProvider + */ + public function exceptionLoggedTest(int $verbosity, Throwable $e, string $expected) + { + Logger::init($this->logfile, $verbosity); + Logger::exception($e); + $expected = " [ ERROR ] tests/LoggerTest.php(201) $expected\n"; + $this->assertEquals($expected, substr(file_get_contents($this->logfile), 25)); + } + + public function exceptionLoggedProvider(): array + { + return [ + [1, new Exception('Test 1'), 'Test 1'], + [2, new Exception('Test 2'), 'Test 2'], + [3, new Exception('Test 3'), 'Test 3'], + [4, new Exception('Test 4'), 'Test 4'], + ]; + } + + /** + * @test + */ + public function exceptionBacktraceTest(): void + { + Logger::init($this->logfile, 1); + Logger::exception(new Exception('Error'), true); + $content = file_get_contents($this->logfile); + $expected = " [ ERROR ] tests/LoggerTest.php(222) Error\n"; + $this->assertEquals($expected, substr($content, 25, 43)); + $this->assertRegExp('/(#\d+ [\w\/\.]*\(\d+\): .*\)\n)+#\d+ \{main\}\n/U', substr($content, 68)); + } +} -- cgit v1.2.3