Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Tuned Tracy Bars/Panels/BlueScreens for easy-developing.

- [Setup](#setup)
- [TracyBlueScreens - better BlueScreen panels](#tracybluescreen)
- [NavigationPanel - navigate easily through all presenters](#navigationpanel)
- [Logger - register additional Tracy loggers](#logger)

## Setup

Expand All @@ -26,5 +26,16 @@ extensions:
![Container Builder - parameters][container-builder-parameters]
![Container Builder - definitions][container-builder-definitions]

## Logger

`LoggerExtension` replaces Tracy logger with `MultiLogger` so you can register additional logger services.

```neon
extensions:
tracy.logger: Contributte\Tracy\DI\LoggerExtension
```

Extra loggers can then be wired in your app and added to the multi logger.

[container-builder-parameters]: https://raw.githubusercontent.com/contributte/tracy/master/.docs/assets/container-builder-parameters.png "Container Builder - parameters"
[container-builder-definitions]: https://raw.githubusercontent.com/contributte/tracy/master/.docs/assets/container-builder-definitions.png "Container Builder - definitions"
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
],
"require": {
"php": ">=8.2",
"tracy/tracy": "^2.9.0"
"tracy/tracy": "^2.11.2"
},
"require-dev": {
"nette/di": "^3.1.2",
Expand Down
40 changes: 40 additions & 0 deletions src/DI/LoggerExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php declare(strict_types = 1);

namespace Contributte\Tracy\DI;

use Contributte\Tracy\Logger\MultiLogger;
use Nette\DI\CompilerExtension;
use Nette\DI\Definitions\ServiceDefinition;
use Nette\PhpGenerator\ClassType;
use Tracy\Debugger;

class LoggerExtension extends CompilerExtension
{

public function loadConfiguration(): void
{
$this->getContainerBuilder()
->addDefinition($this->prefix('logger'))
->setFactory(MultiLogger::class);
}

public function beforeCompile(): void
{
$builder = $this->getContainerBuilder();

$tracyLogger = $builder->getDefinition('tracy.logger');
assert($tracyLogger instanceof ServiceDefinition);
$tracyLogger->setAutowired(false);

$multiLogger = $builder->getDefinition($this->prefix('logger'));
assert($multiLogger instanceof ServiceDefinition);
$multiLogger->addSetup('addLogger', [$tracyLogger]);
}

public function afterCompile(ClassType $class): void
{
$class->getMethod('initialize')
->addBody('?::setLogger($this->getService(?));', [Debugger::class, $this->prefix('logger')]);
}

}
25 changes: 25 additions & 0 deletions src/Logger/MultiLogger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php declare(strict_types = 1);

namespace Contributte\Tracy\Logger;

use Tracy\ILogger;

class MultiLogger implements ILogger
{

/** @var list<ILogger> */
private array $loggers = [];

public function addLogger(ILogger $logger): void
{
$this->loggers[] = $logger;
}

public function log(mixed $value, string $level = self::INFO): void
{
foreach ($this->loggers as $logger) {
$logger->log($value, $level);
}
}

}
38 changes: 38 additions & 0 deletions tests/Cases/DI/LoggerExtension.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php declare(strict_types = 1);

use Contributte\Tester\Toolkit;
use Contributte\Tester\Utils\ContainerBuilder;
use Contributte\Tracy\DI\LoggerExtension;
use Contributte\Tracy\Logger\MultiLogger;
use Nette\DI\Compiler;
use Tester\Assert;
use Tests\Fixtures\Logger\SpyLogger;
use Tracy\Debugger;
use Tracy\ILogger;

require_once __DIR__ . '/../../bootstrap.php';

Toolkit::test(static function (): void {
SpyLogger::$logs = [];

$container = ContainerBuilder::of()
->withCompiler(static function (Compiler $compiler): void {
$compiler->addConfig([
'services' => [
'tracy.logger' => SpyLogger::class,
],
]);

$compiler->addExtension('logger', new LoggerExtension());
})
->build();

$container->initialize();

Assert::type(MultiLogger::class, Debugger::getLogger());

Debugger::log('foo');
Assert::count(1, SpyLogger::$logs);
Assert::same('foo', SpyLogger::$logs[0]['value']);
Assert::same(ILogger::INFO, SpyLogger::$logs[0]['level']);
});
27 changes: 27 additions & 0 deletions tests/Cases/Logger/MultiLogger.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php declare(strict_types = 1);

use Contributte\Tester\Toolkit;
use Contributte\Tracy\Logger\MultiLogger;
use Tester\Assert;
use Tests\Fixtures\Logger\MemoryLogger;
use Tracy\ILogger;

require_once __DIR__ . '/../../bootstrap.php';

Toolkit::test(static function (): void {
$first = new MemoryLogger();
$second = new MemoryLogger();

$logger = new MultiLogger();
$logger->addLogger($first);
$logger->addLogger($second);
$logger->log('boom', ILogger::ERROR);

Assert::count(1, $first->logs);
Assert::same('boom', $first->logs[0]['value']);
Assert::same(ILogger::ERROR, $first->logs[0]['level']);

Assert::count(1, $second->logs);
Assert::same('boom', $second->logs[0]['value']);
Assert::same(ILogger::ERROR, $second->logs[0]['level']);
});
21 changes: 21 additions & 0 deletions tests/Fixtures/Logger/MemoryLogger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php declare(strict_types = 1);

namespace Tests\Fixtures\Logger;

use Tracy\ILogger;

class MemoryLogger implements ILogger
{

/** @var list<array{value: mixed, level: string}> */
public array $logs = [];

public function log(mixed $value, string $level = self::INFO): void
{
$this->logs[] = [
'value' => $value,
'level' => $level,
];
}

}
21 changes: 21 additions & 0 deletions tests/Fixtures/Logger/SpyLogger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php declare(strict_types = 1);

namespace Tests\Fixtures\Logger;

use Tracy\ILogger;

class SpyLogger implements ILogger
{

/** @var list<array{value: mixed, level: string}> */
public static array $logs = [];

public function log(mixed $value, string $level = self::INFO): void
{
self::$logs[] = [
'value' => $value,
'level' => $level,
];
}

}