Skip to content

Commit 0b6e4c1

Browse files
committed
feat: add configurable, optional logger / profiler
1 parent 7b1a1f6 commit 0b6e4c1

File tree

5 files changed

+151
-8
lines changed

5 files changed

+151
-8
lines changed

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,12 @@ lint-stan-ci:
172172
$(APP_COMPOSER) stan:ci
173173
.PHONY: lint-stan-ci
174174

175+
#test: ## Run project php-unit and pest tests
176+
# $(APP_COMPOSER) test
177+
#.PHONY: test
178+
175179
test: ## Run project php-unit and pest tests
176-
$(APP_COMPOSER) test
177-
.PHONY: test
180+
$(APP_RUNNER) vendor/bin/pest tests/src/Bridge/Laravel/LoggerFactoryTest.php
178181

179182
test-cc: ## Run project php-unit and pest tests in coverage mode and build report
180183
$(APP_COMPOSER) test:cc

config/cycle.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,21 @@
136136
queryCache: true,
137137
),
138138
],
139+
140+
/*
141+
* Default logger configuration
142+
*
143+
* Use any of channels configured in your logging.php file
144+
*/
145+
'logger' => [
146+
'default' => env('DB_DEFAULT_LOGGER_CHANNEL', null),
147+
'drivers' => [
148+
'sqlite' => env('DB_DEFAULT_LOGGER_CHANNEL', null),
149+
'pgsql' => env('DB_DEFAULT_LOGGER_CHANNEL', null),
150+
'mysql' => env('DB_DEFAULT_LOGGER_CHANNEL', null),
151+
'sqlserver' => env('DB_DEFAULT_LOGGER_CHANNEL', null),
152+
],
153+
],
139154
],
140155

141156
'schema' => [

src/Bridge/Laravel/LoggerFactory.php

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,41 @@
44

55
namespace WayOfDev\Cycle\Bridge\Laravel;
66

7+
use Cycle\Database\Config\DatabaseConfig;
78
use Cycle\Database\Driver\DriverInterface;
89
use Cycle\Database\LoggerFactoryInterface;
9-
use Illuminate\Log\Logger;
10+
use Cycle\Database\NamedInterface;
11+
use Illuminate\Log\LogManager;
1012
use Psr\Log\LoggerInterface;
13+
use Psr\Log\NullLogger;
1114

1215
final class LoggerFactory implements LoggerFactoryInterface
1316
{
14-
public function __construct(private readonly Logger $logger)
15-
{
17+
private array $config;
18+
19+
public function __construct(
20+
private readonly LogManager $manager,
21+
DatabaseConfig $databaseConfig
22+
) {
23+
$this->config = $databaseConfig->toArray()['logger'] ?? [];
1624
}
1725

1826
public function getLogger(?DriverInterface $driver = null): LoggerInterface
1927
{
20-
return $this->logger->getLogger();
28+
if (! isset($this->config['default'])) {
29+
return new NullLogger();
30+
}
31+
32+
$channel = $this->config['default'];
33+
34+
if ($driver instanceof NamedInterface) {
35+
$driverName = $driver->getName();
36+
37+
if (isset($this->config['drivers'][$driverName])) {
38+
$channel = $this->config['drivers'][$driverName];
39+
}
40+
}
41+
42+
return $this->manager->channel($channel);
2143
}
2244
}

src/Bridge/Laravel/Providers/Registrators/RegisterDatabase.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use Cycle\Database\DatabaseProviderInterface;
1111
use Cycle\Database\LoggerFactoryInterface;
1212
use Illuminate\Contracts\Foundation\Application;
13-
use Illuminate\Log\Logger;
13+
use Illuminate\Log\LogManager;
1414
use WayOfDev\Cycle\Bridge\Laravel\LoggerFactory;
1515

1616
/**
@@ -22,7 +22,8 @@ public function __invoke(Application $app): void
2222
{
2323
$app->singleton(LoggerFactoryInterface::class, static function (Application $app): LoggerFactoryInterface {
2424
return new LoggerFactory(
25-
logger: $app->get(Logger::class)
25+
manager: $app->get(LogManager::class),
26+
databaseConfig: $app->get(DatabaseConfig::class),
2627
);
2728
});
2829

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WayOfDev\Tests\Bridge\Laravel;
6+
7+
use Cycle\Database\Config\DatabaseConfig;
8+
use Cycle\Database\Driver\DriverInterface;
9+
use Cycle\Database\NamedInterface;
10+
use Illuminate\Log\LogManager;
11+
use Mockery as m;
12+
use Psr\Container\ContainerExceptionInterface;
13+
use Psr\Container\NotFoundExceptionInterface;
14+
use Psr\Log\NullLogger;
15+
use WayOfDev\Cycle\Bridge\Laravel\LoggerFactory;
16+
use WayOfDev\Tests\TestCase;
17+
18+
use function file_get_contents;
19+
20+
class LoggerFactoryTest extends TestCase
21+
{
22+
protected function tearDown(): void
23+
{
24+
m::close();
25+
parent::tearDown();
26+
}
27+
28+
/**
29+
* @test
30+
*
31+
* @throws ContainerExceptionInterface
32+
* @throws NotFoundExceptionInterface
33+
*/
34+
public function it_should_return_custom_logger_from_factory(): void
35+
{
36+
$mockDriver = m::mock(DriverInterface::class, NamedInterface::class);
37+
$mockDriver->shouldReceive('getName')->andReturn('custom');
38+
39+
$loggerFactory = new LoggerFactory(
40+
$this->app->get(LogManager::class),
41+
new DatabaseConfig(config('cycle.database'))
42+
);
43+
44+
// @phpstan-ignore-next-line
45+
$logger = $loggerFactory->getLogger($mockDriver);
46+
$logger->info('Test log entry');
47+
48+
$logContent = file_get_contents(storage_path('logs/logger-factory-test.log'));
49+
$this::assertStringContainsString('Test log entry', $logContent);
50+
}
51+
52+
/**
53+
* @test
54+
*
55+
* @throws ContainerExceptionInterface
56+
* @throws NotFoundExceptionInterface
57+
*/
58+
public function it_should_return_null_logger_from_factory(): void
59+
{
60+
config()->set('cycle.database.logger', [
61+
'default' => null,
62+
'drivers' => [
63+
'sqlite' => null,
64+
'pgsql' => null,
65+
'mysql' => null,
66+
'sqlserver' => null,
67+
],
68+
]);
69+
70+
$loggerFactory = new LoggerFactory(
71+
$this->app->get(LogManager::class),
72+
new DatabaseConfig(config('database'))
73+
);
74+
$logger = $loggerFactory->getLogger();
75+
76+
$this::assertInstanceOf(NullLogger::class, $logger);
77+
}
78+
79+
protected function getEnvironmentSetUp($app): void
80+
{
81+
parent::getEnvironmentSetUp($app);
82+
83+
// Add custom logging channel configuration
84+
$app['config']->set('logging.channels.custom_channel', [
85+
'driver' => 'single',
86+
'path' => storage_path('logs/logger-factory-test.log'),
87+
'level' => 'debug',
88+
]);
89+
90+
// Set the database logger configuration
91+
$app['config']->set('cycle.database.logger', [
92+
'default' => 'stack',
93+
'drivers' => [
94+
'sqlite' => 'stack',
95+
'pgsql' => 'stack',
96+
'mysql' => 'stack',
97+
'sqlserver' => 'stack',
98+
'custom' => 'custom_channel',
99+
],
100+
]);
101+
}
102+
}

0 commit comments

Comments
 (0)