Skip to content

Commit c036366

Browse files
committed
feat(logging): Implement optional context parameters with thresholds
- Enhanced LoggerManager to support optional context parameters. - Added logic to apply thresholds only if context parameters are passed. - Updated LoggerFactory to configure performance and query loggers with thresholds. - Ensured loggers function normally when context parameters are not provided.
1 parent 3b9fd2f commit c036366

File tree

9 files changed

+133
-32
lines changed

9 files changed

+133
-32
lines changed

.env.example

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ KARIRICODE_PHP_VERSION=8.3
33
KARIRICODE_PHP_PORT=9303
44

55
# Canal de log padrão
6-
LOG_CHANNEL=single
6+
LOG_CHANNEL=file
77

88
# Nível de log padrão
99
LOG_LEVEL=debug
@@ -30,7 +30,7 @@ QUERY_LOG_CHANNEL=file
3030
QUERY_LOG_THRESHOLD=100
3131

3232
# Habilitar logs de desempenho
33-
PERFORMANCE_LOG_ENABLED=false
33+
PERFORMANCE_LOG_ENABLED=true
3434
PERFORMANCE_LOG_CHANNEL=file
3535
PERFORMANCE_LOG_THRESHOLD=1000
3636

@@ -41,3 +41,13 @@ ERROR_LOG_CHANNEL=file
4141
# Configurações do limpador de logs
4242
LOG_CLEANER_ENABLED=true
4343
LOG_CLEANER_KEEP_DAYS=30
44+
45+
# Configurações do CircuitBreaker
46+
CIRCUIT_BREAKER_FAILURE_THRESHOLD=3
47+
CIRCUIT_BREAKER_RESET_TIMEOUT=60
48+
49+
# Configurações do Retry
50+
RETRY_MAX_ATTEMPTS=3
51+
RETRY_DELAY=1000
52+
RETRY_MULTIPLIER=2
53+
RETRY_JITTER=100

config/logging.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,17 @@
224224
'level' => ConfigHelper::env('LOG_LEVEL', 'debug'),
225225
'handlers' => ['syslog'],
226226
],
227+
'slack' => [
228+
'level' => ConfigHelper::env('LOG_LEVEL', 'critical'),
229+
'handlers' => ['slack'],
230+
'formatter' => [
231+
'json' => [
232+
'with' => [
233+
'includeStacktraces' => true,
234+
]
235+
]
236+
],
237+
],
227238
'custom' => [
228239
'handlers' => ['custom'],
229240
],
@@ -255,6 +266,9 @@
255266
'channel' => ConfigHelper::env('PERFORMANCE_LOG_CHANNEL', 'file'),
256267
'threshold' => ConfigHelper::env('PERFORMANCE_LOG_THRESHOLD', 1000), // in milliseconds
257268
'handlers' => [
269+
'console' => [
270+
'with' => ['useColors' => true],
271+
],
258272
'file' => [
259273
'with' => ['filePath' => ConfigHelper::storagePath('logs/performance.log')],
260274
],
@@ -301,6 +315,27 @@
301315
'port' => 0,
302316
],
303317
],
318+
'slack' => [
319+
'class' => \KaririCode\Logging\Handler\SlackHandler::class,
320+
'with' => [
321+
'slackClient' => \KaririCode\Logging\Util\SlackClient::create(
322+
ConfigHelper::env('LOG_SLACK_WEBHOOK_URL'),
323+
new \KaririCode\Logging\Resilience\CircuitBreaker(
324+
ConfigHelper::env('CIRCUIT_BREAKER_FAILURE_THRESHOLD', 3),
325+
ConfigHelper::env('CIRCUIT_BREAKER_RESET_TIMEOUT', 60)
326+
),
327+
new \KaririCode\Logging\Resilience\Retry(
328+
ConfigHelper::env('RETRY_MAX_ATTEMPTS', 3),
329+
ConfigHelper::env('RETRY_DELAY', 1000),
330+
ConfigHelper::env('RETRY_MULTIPLIER', 2),
331+
ConfigHelper::env('RETRY_JITTER', 100)
332+
),
333+
new \KaririCode\Logging\Resilience\Fallback(),
334+
new \KaririCode\Logging\Util\CurlClient()
335+
),
336+
'minLevel' => LogLevel::CRITICAL,
337+
],
338+
],
304339
'custom' => [
305340
'class' => \KaririCode\Logging\Handler\NullHandler::class,
306341
],

src/Handler/LoggerHandlerFactory.php

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ public function initializeFromConfiguration(LoggerConfiguration $config): void
3131
public function createHandlers(string $handlerName): array
3232
{
3333
$handlersConfig = $this->getHandlersConfig($handlerName);
34-
3534
$handlers = [];
3635
foreach ($handlersConfig as $key => $value) {
3736
[$handlerName, $handlerOptions] = $this->extractMergedConfig($key, $value);
@@ -41,30 +40,39 @@ public function createHandlers(string $handlerName): array
4140
return $handlers;
4241
}
4342

44-
private function getHandlersConfig(string $channelName): array
43+
private function getHandlersConfig(string $handlerName): array
4544
{
46-
$channelHandlerConfig = $this->getChannelHandlersConfig($channelName);
47-
$optionalHandlerConfig = $this->getOptionalHandlersConfig($channelName);
45+
$channelHandlerConfig = $this->getChannelHandlersConfig($handlerName);
46+
$optionalHandlerConfig = $this->getOptionalHandlersConfig($handlerName);
4847

4948
return $channelHandlerConfig ?? $optionalHandlerConfig ?? [];
5049
}
5150

52-
private function getChannelHandlersConfig(string $channelName): ?array
51+
private function getChannelHandlersConfig(string $handlerName): ?array
5352
{
5453
$channelConfigs = $this->config->get('channels', []);
5554

56-
return $channelConfigs[$channelName]['handlers'] ?? null;
55+
return $channelConfigs[$handlerName]['handlers'] ?? null;
5756
}
5857

59-
private function getOptionalHandlersConfig(string $channelName): ?array
58+
private function getOptionalHandlersConfig(string $handlerName): ?array
6059
{
61-
$optionalHandlerConfigs = $this->config->get($channelName, []);
60+
$optionalHandlerConfigs = $this->config->get($handlerName, []);
61+
62+
if (!self::isOptionalHandlerEnabled($optionalHandlerConfigs)) {
63+
return [];
64+
}
6265

6366
return $optionalHandlerConfigs['handlers'] ?? $this->getChannelHandlersConfig(
6467
$optionalHandlerConfigs['channel'] ?? 'file'
6568
);
6669
}
6770

71+
private static function isOptionalHandlerEnabled(array $optionalHandlerConfigs): bool
72+
{
73+
return isset($optionalHandlerConfigs['enabled']) && $optionalHandlerConfigs['enabled'];
74+
}
75+
6876
private function createHandler(string $handlerName, array $handlerOptions): LogHandler
6977
{
7078
$handlerClass = $this->getClassFromMap($this->handlerMap, $handlerName);

src/Handler/SlackHandler.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use KaririCode\Contract\ImmutableValue;
88
use KaririCode\Contract\Logging\LogFormatter;
99
use KaririCode\Contract\Logging\LogLevel as LoggingLogLevel;
10+
use KaririCode\Logging\Formatter\LineFormatter;
1011
use KaririCode\Logging\LogLevel;
1112
use KaririCode\Logging\Util\SlackClient;
1213

@@ -17,7 +18,7 @@ class SlackHandler extends AbstractHandler
1718
public function __construct(
1819
SlackClient $slackClient,
1920
LoggingLogLevel $minLevel = LogLevel::CRITICAL,
20-
?LogFormatter $formatter = null
21+
protected LogFormatter $formatter = new LineFormatter()
2122
) {
2223
parent::__construct($minLevel, $formatter);
2324
$this->slackClient = $slackClient;

src/LoggerFactory.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,24 @@ public function createLogger(string $name): Logger
3232
return new LoggerManager($name, $handlers, $processors, $formatter);
3333
}
3434

35-
public function createQueryLogger(): Logger
35+
public function createPerformanceLogger(): Logger
3636
{
37-
return $this->createLogger('query');
37+
/** @var LoggerManager $logger */
38+
$logger = $this->createLogger('performance');
39+
$threshold = $this->config->get('performance.threshold', 1000);
40+
$logger->setThreshold('execution_time', $threshold);
41+
42+
return $logger;
3843
}
3944

40-
public function createPerformanceLogger(): Logger
45+
public function createQueryLogger(): Logger
4146
{
42-
return $this->createLogger('performance');
47+
/** @var LoggerManager $logger */
48+
$logger = $this->createLogger('query');
49+
$threshold = $this->config->get('query.threshold', 100);
50+
$logger->setThreshold('time', $threshold);
51+
52+
return $logger;
4353
}
4454

4555
public function createErrorLogger(): Logger

src/LoggerManager.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class LoggerManager implements Logger
1616
{
1717
use LoggerTrait;
1818

19+
private array $thresholds = [];
20+
1921
public function __construct(
2022
private readonly string $name,
2123
private array $handlers = [],
@@ -24,8 +26,17 @@ public function __construct(
2426
) {
2527
}
2628

29+
public function setThreshold(string $key, int $value): void
30+
{
31+
$this->thresholds[$key] = $value;
32+
}
33+
2734
public function log(LogLevel $level, string|\Stringable $message, array $context = []): void
2835
{
36+
if (!$this->passesThreshold($context)) {
37+
return;
38+
}
39+
2940
$record = new LogRecord($level, $message, $context);
3041

3142
foreach ($this->processors as $processor) {
@@ -37,6 +48,17 @@ public function log(LogLevel $level, string|\Stringable $message, array $context
3748
}
3849
}
3950

51+
private function passesThreshold(array $context): bool
52+
{
53+
foreach ($this->thresholds as $key => $threshold) {
54+
if (isset($context[$key]) && $context[$key] < $threshold) {
55+
return false;
56+
}
57+
}
58+
59+
return true;
60+
}
61+
4062
public function addHandler(HandlerAware $handler): self
4163
{
4264
$this->handlers[] = $handler;

src/Processor/Metric/ExecutionTimeProcessor.php

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,29 @@
1010

1111
class ExecutionTimeProcessor extends AbstractProcessor
1212
{
13-
/**
13+
public function __construct(private float $threshold = 1000)
14+
{
15+
}
16+
17+
/**falta cibnfi
1418
* @param LogRecord $record
1519
*/
1620
public function process(ImmutableValue $record): ImmutableValue
1721
{
18-
$executionTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
19-
$context = array_merge($record->context, ['execution_time' => $executionTime]);
20-
21-
return new LogRecord(
22-
$record->level,
23-
$record->message,
24-
$context,
25-
$record->datetime,
26-
$record->extra
27-
);
22+
$executionTime = (microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']) * 1000; // Convert to milliseconds
23+
24+
if ($executionTime > $this->threshold) {
25+
$context = array_merge($record->context, ['execution_time' => $executionTime]);
26+
27+
return new LogRecord(
28+
$record->level,
29+
$record->message,
30+
$context,
31+
$record->datetime,
32+
$record->extra
33+
);
34+
}
35+
36+
return $record;
2837
}
2938
}

src/Util/ReflectionFactoryTrait.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ protected function getReflectionClass(string $class): \ReflectionClass
6565
*
6666
* @return array the filtered parameters
6767
*/
68-
protected function filterConstructorParameters(\ReflectionClass $reflectionClass, array $parameters): array
68+
private function filterConstructorParameters(\ReflectionClass $reflectionClass, array $parameters): array
6969
{
7070
$constructor = $reflectionClass->getConstructor();
7171
if (!$constructor) {
@@ -107,7 +107,7 @@ protected function getClassFromMap(array $map, string $key): string
107107
throw new InvalidConfigurationException("Configuration not found for key: $key");
108108
}
109109

110-
return $this->validateAndExtractClass($map[$key], $key);
110+
return self::validateAndExtractClass($map[$key], $key);
111111
}
112112

113113
/**
@@ -120,7 +120,7 @@ protected function getClassFromMap(array $map, string $key): string
120120
*
121121
* @return string the validated class name
122122
*/
123-
protected function validateAndExtractClass($config, string $key): string
123+
protected static function validateAndExtractClass(mixed $config, string $key): string
124124
{
125125
$class = is_string($config) ? $config : ($config['class'] ?? null);
126126

tests/application.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,16 @@
4444
}
4545

4646
$queryLogger = $loggerRegistry->getLogger('query');
47-
$queryLogger->info('Executing a query', ['query' => 'SELECT * FROM users', 'bindings' => [], 'time' => 150]);
47+
$queryLogger->info('Executing a query', ['time' => 90, 'query' => 'SELECT * FROM users', 'bindings' => []]);
4848

49-
// $performanceLogger = $loggerRegistry->getLogger('performance');
50-
// $performanceLogger->debug('Performance logging', ['additional_context' => 'example']);
49+
$queryLogger = $loggerRegistry->getLogger('query');
50+
$queryLogger->info('Executing a query', ['query' => 'SELECT * FROM users', 'bindings' => []]);
51+
52+
$performanceLogger = $loggerRegistry->getLogger('performance');
53+
$performanceLogger->debug('Performance logging', ['execution_time' => 100, 'additional_context' => 'example']);
54+
55+
$performanceLogger = $loggerRegistry->getLogger('performance');
56+
$performanceLogger->debug('Performance logging', ['additional_context' => 'example']);
5157

5258
// // // Testa o error logger
5359
// // if (LoggerRegistry::getLogger('error')) {

0 commit comments

Comments
 (0)