Source of file Logger.php
Size: 7,032 Bytes - Last Modified: 2021-01-12T22:04:13+00:00
C:/Users/MAKS/Code/_PROJECTS/amqp-agent/src/Helper/Logger.php
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
Covered by 5 test(s):
56
Covered by 5 test(s):
57
Covered by 5 test(s):
58596061626364656667
Covered by 2 test(s):
686970717273747576
Covered by 1 test(s):
77787980818283848586
Covered by 1 test(s):
87
Covered by 1 test(s):
888990919293949596
Covered by 1 test(s):
979899100101102103104105106
Covered by 1 test(s):
107
Covered by 1 test(s):
108109110111112113114115116117118119120
Covered by 3 test(s):
121122
Covered by 3 test(s):
123
Covered by 1 test(s):
124
Covered by 1 test(s):
125126
Covered by 1 test(s):
127
Covered by 1 test(s):
128129
Covered by 1 test(s):
130
Covered by 1 test(s):
131132133134
Covered by 3 test(s):
135
Covered by 1 test(s):
136
Covered by 1 test(s):
137138
Covered by 1 test(s):
139
Covered by 1 test(s):
140141
Covered by 1 test(s):
142
Covered by 1 test(s):
143144145146
Covered by 3 test(s):
147148149
Covered by 3 test(s):
150
Covered by 3 test(s):
151
Covered by 3 test(s):
152
Covered by 3 test(s):
153154155156
Covered by 3 test(s):
157158159160161162163164165166167168169170171
Covered by 3 test(s):
172
Covered by 3 test(s):
173174
Covered by 3 test(s):
175
Covered by 3 test(s):
176
Covered by 3 test(s):
177
Covered by 3 test(s):
178
Covered by 3 test(s):
179180181182
Covered by 3 test(s):
183184185186187188189190191192
Covered by 1 test(s):
193194195196197198199200201202
Covered by 1 test(s):
203
Covered by 1 test(s):
204
Covered by 1 test(s):
205206
Covered by 1 test(s):
207208209210211212213214215216217218
Covered by 3 test(s):
219
Covered by 3 test(s):
220
Covered by 3 test(s):
221
Covered by 3 test(s):
222223
Covered by 3 test(s):
224225226
| <?php /** * @author Marwan Al-Soltany <MarwanAlsoltany@gmail.com> * @copyright Marwan Al-Soltany 2020 * For the full copyright and license information, please view * the LICENSE file that was distributed with this source code. */ declare(strict_types=1); namespace MAKS\AmqpAgent\Helper; use MAKS\AmqpAgent\Helper\Utility; /** * A class to write logs, exposing methods that work statically and on instantiation. * This class DOES NOT implement `Psr\Log\LoggerInterface`. * * Example: * ``` * // static * Logger::log('Some message to log.', 'filename', 'path/to/some/directory'); * // instantiated * $logger = new Logger(); * $logger->setFilename('filename'); * $logger->setDirectory('path/to/some/directory'); * $logger->write('Some message to log.'); * ``` * * @since 1.0.0 */ class Logger { /** * The filename of the log file. * @var string */ public $filename; /** * The directory where the log file gets written. * @var string */ public $directory; /** * Passing null for $directory will raise a warning and force the logger to find a reasonable directory to write the file in. * @param string|null $filename The name wished to be given to the file. Pass null for auto-generate. * @param string|null $directory The directory where the log file should be written. */ public function __construct(?string $filename, ?string $directory) { $this->filename = $filename; $this->directory = $directory; } /** * Logs a message to a file, generates it if it does not exist and raises a user-level warning and/or notice on misuse. * @param string $message The message wished to be logged. * @return bool True on success. */ public function write(string $message): bool { return self::log($message, $this->filename, $this->directory); } /** * Gets filename property. * @return string */ public function getFilename() { return $this->filename; } /** * Sets filename property. * @param string $filename The filename. * @return self */ public function setFilename(string $filename) { $this->filename = $filename; return $this; } /** * Gets directory property. * @return string */ public function getDirectory() { return $this->directory; } /** * Sets directory property. * @param string $directory The directory. * @return self */ public function setDirectory(string $directory) { $this->directory = $directory; return $this; } /** * Logs a message to a file, generates it if it does not exist and raises a user-level warning and/or notice on misuse. * @param string $message The message wished to be logged. * @param string|null $filename [optional] The name wished to be given to the file. If not provided a Notice will be raised with the auto-generated filename. * @param string|null $directory [optional] The directory where the log file should be written. If not provided a Warning will be raised with the used path. * @return bool True if message was written. */ public static function log(string $message, ?string $filename = null, ?string $directory = null): bool { $passed = false; if (null === $filename) { $filename = self::getFallbackFilename(); Utility::emit( [ 'yellow' => sprintf('%s() was called without specifying a filename.', __METHOD__), 'green' => sprintf('Log file will be named: "%s".', $filename) ], null, E_USER_NOTICE ); } if (null === $directory) { $directory = self::getFallbackDirectory(); Utility::emit( [ 'yellow' => sprintf('%s() was called without specifying a directory.', __METHOD__), 'red' => sprintf('Log file will be written in: "%s".', $directory) ], null, E_USER_WARNING ); } $file = self::getNormalizedPath($directory, $filename); // create log file if it does not exist if (!is_file($file) && is_writable($directory)) { $signature = 'Created by ' . __METHOD__ . date('() \o\\n l jS \of F Y h:i:s A (Ymdhis)') . PHP_EOL; file_put_contents($file, $signature, 0, stream_context_create()); chmod($file, 0775); } // write in the log file if (is_writable($file)) { // empty the the file if it exceeds 64MB // @codeCoverageIgnoreStart clearstatcache(true, $file); if (filesize($file) > 6.4e+7) { $stream = fopen($file, 'r'); if (is_resource($stream)) { $signature = fgets($stream) . 'For exceeding 64MB, it was overwritten on ' . date('l jS \of F Y h:i:s A (Ymdhis)') . PHP_EOL; fclose($stream); file_put_contents($file, $signature, 0, stream_context_create()); chmod($file, 0775); } } // @codeCoverageIgnoreEnd $timestamp = Utility::time()->format(DATE_ISO8601); $log = $timestamp . ' ' . $message . PHP_EOL; $stream = fopen($file, 'a+'); if (is_resource($stream)) { fwrite($stream, $log); fclose($stream); $passed = true; } } return $passed; } /** * Returns a fallback filename based on date. * @since 1.2.1 * @return string */ protected static function getFallbackFilename(): string { return 'maks-amqp-agent-log-' . date("Ymd"); } /** * Returns a fallback writing directory based on caller. * @since 1.2.1 * @return string */ protected static function getFallbackDirectory(): string { $backtrace = Utility::backtrace(['file'], 0); $fallback1 = strlen($_SERVER["DOCUMENT_ROOT"]) ? $_SERVER["DOCUMENT_ROOT"] : null; $fallback2 = isset($backtrace['file']) ? dirname($backtrace['file']) : __DIR__; return $fallback1 ?? $fallback2; } /** * Returns a normalized path based on OS. * @since 1.2.1 * @param string $directory The directory. * @param string $filename The Filename. * @return string The full normalized path. */ protected static function getNormalizedPath(string $directory, string $filename): string { $ext = '.log'; $filename = substr($filename, -strlen($ext)) === $ext ? $filename : $filename . $ext; $directory = $directory . DIRECTORY_SEPARATOR; $path = $directory . $filename; return preg_replace("/\/+|\\+/", DIRECTORY_SEPARATOR, $path); } } |