-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/vendor | ||
/composer.lock |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"name": "nextras/tracy-monolog-adapter", | ||
"type": "library", | ||
"description": "Nextras Tracy-Monolog Adapter", | ||
"keywords": ["monolog", "nette", "nextras", "logger"], | ||
"homepage": "https://github.com/nextras/tracy-monolog-adapter", | ||
"license": "BSD-3-Clause", | ||
"authors": [ | ||
{ "name": "Nextras Project", "homepage": "https://github.com/nextras/tracy-monolog-adapter/graphs/contributors" } | ||
], | ||
"support": { | ||
"issues": "https://github.com/nextras/tracy-monolog-adapter/issues" | ||
}, | ||
"require": { | ||
"php": ">=7.0", | ||
"tracy/tracy": "~2.3", | ||
"monolog/monolog": "~1.9" | ||
}, | ||
"require-dev": { | ||
"nette/di": "~2.2" | ||
}, | ||
"autoload": { | ||
"psr-4": { "Nextras\\TracyMonologAdapter\\": "src/" } | ||
}, | ||
"extra": { | ||
"branch-alias": { | ||
"dev-master": "0.1-dev" | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
New BSD License | ||
--------------- | ||
|
||
Copyright (c) 2016 Nextras contributors (https://nextras.org) | ||
|
||
Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com) | ||
|
||
All rights reserved. | ||
|
||
|
||
Redistribution and use in source and binary forms, with or without modification, | ||
are permitted provided that the following conditions are met: | ||
|
||
* Redistributions of source code must retain the above copyright notice, | ||
this list of conditions and the following disclaimer. | ||
|
||
* Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
|
||
* Neither the name of "Clevis", "Nextras" nor the names of this software contributors | ||
may be used to endorse or promote products derived from this software | ||
without specific prior written permission. | ||
|
||
This software is provided by the copyright holders and contributors "as is" and | ||
any express or implied warranties, including, but not limited to, the implied | ||
warranties of merchantability and fitness for a particular purpose are | ||
disclaimed. In no event shall the copyright owner or contributors be liable for | ||
any direct, indirect, incidental, special, exemplary, or consequential damages | ||
(including, but not limited to, procurement of substitute goods or services; | ||
loss of use, data, or profits; or business interruption) however caused and on | ||
any theory of liability, whether in contract, strict liability, or tort | ||
(including negligence or otherwise) arising in any way out of the use of this | ||
software, even if advised of the possibility of such damage. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
Nextras Tracy-Monolog Adapter | ||
============================= | ||
|
||
[](https://packagist.org/packages/nextras/tracy-monolog-adapter) | ||
[](https://packagist.org/packages/nextras/tracy-monolog-adapter) | ||
|
||
### Installation | ||
|
||
Use composer: | ||
|
||
```bash | ||
$ composer require nextras/tracy-monolog-adapter | ||
``` | ||
|
||
### License | ||
|
||
New BSD License. See full [license](license.md). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?php | ||
|
||
/** | ||
* @license New BSD License | ||
* @link https://github.com/nextras/tracy-monolog-adapter | ||
*/ | ||
|
||
namespace Nextras\TracyMonologAdapter\Bridges\NetteDI; | ||
|
||
use Monolog\Handler\RotatingFileHandler; | ||
use Monolog\Logger as MonologLogger; | ||
use Nette\DI\CompilerExtension; | ||
use Nette\DI\Helpers; | ||
use Nette\DI\Statement; | ||
use Nette\PhpGenerator\ClassType; | ||
use Nextras\TracyMonologAdapter\Logger; | ||
use Nextras\TracyMonologAdapter\Processors\TracyExceptionProcessor; | ||
use Tracy\Debugger; | ||
|
||
|
||
class MonologExtension extends CompilerExtension | ||
{ | ||
public function loadConfiguration() | ||
{ | ||
$builder = $this->getContainerBuilder(); | ||
$logDir = isset($builder->parameters['logDir']) ? Helpers::expand('%logDir%', $builder->parameters) : Debugger::$logDirectory; | ||
|
||
$config = $this->getConfig(); | ||
|
||
if (isset($config['monolog'])) { | ||
$monologLogger = $config['monolog']; | ||
|
||
} else { | ||
$builder->addDefinition($this->prefix('handler')) | ||
->setClass(RotatingFileHandler::class) | ||
->setArguments([$logDir . '/nette.log']) | ||
->setAutowired(false); | ||
|
||
$builder->addDefinition($this->prefix('tracyExceptionProcessor')) | ||
->setClass(TracyExceptionProcessor::class) | ||
->setArguments([$logDir, '@Tracy\BlueScreen']) | ||
->setAutowired(false); | ||
|
||
$monologLogger = $builder->addDefinition($this->prefix('monologLogger')) | ||
->setClass(MonologLogger::class) | ||
->setArguments(['nette']) | ||
->addSetup('pushHandler', ['@' . $this->prefix('handler')]) | ||
->addSetup('pushProcessor', ['@' . $this->prefix('tracyExceptionProcessor')]) | ||
->setAutowired(false); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
hrach
Author
Member
|
||
} | ||
|
||
$builder->addDefinition($this->prefix('tracyLogger')) | ||
->setClass(Logger::class) | ||
->setArguments([$monologLogger]); | ||
|
||
if ($builder->hasDefinition('tracy.logger')) { | ||
$builder->getDefinition('tracy.logger')->setAutowired(false); | ||
} | ||
} | ||
|
||
|
||
public function afterCompile(ClassType $class) | ||
{ | ||
$initialize = $class->getMethod('initialize'); | ||
$initialize->addBody('\Tracy\Debugger::setLogger($this->getByType(\Tracy\ILogger::class));'); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<?php | ||
|
||
/** | ||
* @license New BSD License | ||
* @link https://github.com/nextras/tracy-monolog-adapter | ||
*/ | ||
|
||
namespace Nextras\TracyMonologAdapter; | ||
|
||
use Monolog; | ||
use Throwable; | ||
use Tracy\Helpers; | ||
use Tracy\ILogger; | ||
|
||
|
||
class Logger implements ILogger | ||
{ | ||
/** @const Tracy priority to Monolog priority mapping */ | ||
const PRIORITY_MAP = [ | ||
self::DEBUG => Monolog\Logger::DEBUG, | ||
self::INFO => Monolog\Logger::INFO, | ||
self::WARNING => Monolog\Logger::WARNING, | ||
self::ERROR => Monolog\Logger::ERROR, | ||
self::EXCEPTION => Monolog\Logger::CRITICAL, | ||
self::CRITICAL => Monolog\Logger::CRITICAL, | ||
]; | ||
|
||
/** @var Monolog\Logger */ | ||
protected $monolog; | ||
|
||
|
||
public function __construct(Monolog\Logger $monolog) | ||
{ | ||
$this->monolog = $monolog; | ||
} | ||
|
||
|
||
public function log($message, $priority = self::INFO) | ||
{ | ||
$context = [ | ||
'at' => Helpers::getSource(), | ||
]; | ||
|
||
if ($message instanceof Throwable) { | ||
$context['exception'] = $message; | ||
$message = ''; | ||
} | ||
|
||
$this->monolog->addRecord( | ||
self::PRIORITY_MAP[$priority] ?? Monolog\Logger::ERROR, | ||
$message, | ||
$context | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
<?php | ||
|
||
/** | ||
* @license New BSD License | ||
* @link https://github.com/nextras/tracy-monolog-adapter | ||
*/ | ||
|
||
namespace Nextras\TracyMonologAdapter\Processors; | ||
|
||
use Throwable; | ||
use Tracy\BlueScreen; | ||
use Tracy\Helpers; | ||
|
||
|
||
class TracyExceptionProcessor | ||
{ | ||
/** @var string */ | ||
private $directory; | ||
|
||
/** @var BlueScreen */ | ||
private $blueScreen; | ||
|
||
|
||
public function __construct(string $logDirectory, BlueScreen $blueScreen) | ||
{ | ||
$this->directory = $logDirectory; | ||
$this->blueScreen = $blueScreen; | ||
} | ||
|
||
|
||
public function __invoke(array $record) | ||
{ | ||
if (isset($record['context']['exception'])) { | ||
list($justCreated, $exceptionFileName) = $this->logException($record['context']['exception']); | ||
$record['context']['tracy_filename'] = basename($exceptionFileName); | ||
$record['context']['tracy_created'] = $justCreated; | ||
if ($record['message'] === '') { | ||
$record['message'] = self::formatMessage($record['context']['exception']); | ||
} | ||
unset($record['context']['exception']); | ||
} | ||
return $record; | ||
} | ||
|
||
|
||
/** | ||
* @author David Grudl | ||
* @see https://github.com/nette/tracy | ||
*/ | ||
protected function logException(Throwable $exception): array | ||
{ | ||
$file = $this->getExceptionFile($exception); | ||
if ($handle = @fopen($file, 'x')) { // @ file may already exist | ||
ob_start(); // double buffer prevents sending HTTP headers in some PHP | ||
ob_start(function ($buffer) use ($handle) { fwrite($handle, $buffer); }, 4096); | ||
$this->blueScreen->render($exception); | ||
ob_end_flush(); | ||
ob_end_clean(); | ||
fclose($handle); | ||
return [true, $file]; | ||
} else { | ||
return [false, $file]; | ||
} | ||
} | ||
|
||
|
||
/** | ||
* @author David Grudl | ||
* @see https://github.com/nette/tracy | ||
*/ | ||
private function getExceptionFile(Throwable $exception): string | ||
{ | ||
$dir = strtr($this->directory . '/', '\\/', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR); | ||
$hash = substr(md5(preg_replace('~(Resource id #)\d+~', '$1', $exception)), 0, 10); | ||
foreach (new \DirectoryIterator($this->directory) as $file) { | ||
if (strpos($file, $hash)) { | ||
return $dir . $file; | ||
} | ||
} | ||
return $dir . 'exception--' . @date('Y-m-d--H-i') . "--$hash.html"; // @ timezone may not be set | ||
} | ||
|
||
|
||
/** | ||
* @author David Grudl | ||
* @see https://github.com/nette/tracy | ||
*/ | ||
protected static function formatMessage(Throwable $message): string | ||
{ | ||
$tmp = []; | ||
while ($message) { | ||
$tmp[] = ($message instanceof \ErrorException | ||
? Helpers::errorTypeToString($message->getSeverity()) . ': ' . $message->getMessage() | ||
: Helpers::getClass($message) . ': ' . $message->getMessage() | ||
) . ' in ' . $message->getFile() . ':' . $message->getLine(); | ||
$message = $message->getPrevious(); | ||
} | ||
$message = implode($tmp, "\ncaused by "); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
JanTvrdik
Member
|
||
return trim($message); | ||
} | ||
} |
sem zapomněl, proč je to autowired = false; má to nějaký důvod?
jsem si zatím případ to configu