Skip to content

Commit 0da0615

Browse files
committed
refactor: Migrate Slack logger implementation to use chat.postMessage
- Update SlackHandler configuration to use bot token - Modify SlackClient to utilize Slack's chat.postMessage API - Update SlackHandler to work with the new SlackClient implementation - Adjust CurlClient to support authorization headers - Add environment variables for SLACK_BOT_TOKEN and SLACK_CHANNEL - Improve error handling and Slack API response processing
1 parent c6ba35b commit 0da0615

File tree

7 files changed

+67
-74
lines changed

7 files changed

+67
-74
lines changed

.env.example

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ LOG_CHANNEL=file
99
LOG_LEVEL=debug
1010
LOG_ENCRYPTION_KEY=83302e6472acda6a8aeadf78409ceda3959994991393cdafbe23d2a46a148ba4
1111

12-
# URL do Webhook do Slack para logs
13-
LOG_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
12+
# Slack para logs
13+
SLACK_BOT_TOKEN=xoxb-your-bot-token-here
14+
SLACK_CHANNEL=#your-channel-name
1415

1516
# URL e Porta do Papertrail
1617
PAPERTRAIL_URL=logs.papertrailapp.com

config/logging.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@
140140
'class' => \KaririCode\Logging\Handler\SlackHandler::class,
141141
'with' => [
142142
'slackClient' => \KaririCode\Logging\Util\SlackClient::create(
143-
Config::env('LOG_SLACK_WEBHOOK_URL'),
143+
Config::env('SLACK_BOT_TOKEN'),
144+
Config::env('SLACK_CHANNEL', '#logs'),
144145
new \KaririCode\Logging\Resilience\CircuitBreaker(
145146
Config::env('CIRCUIT_BREAKER_FAILURE_THRESHOLD', 3),
146147
Config::env('CIRCUIT_BREAKER_RESET_TIMEOUT', 60)

src/Handler/SlackHandler.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,12 @@
1313

1414
class SlackHandler extends AbstractHandler
1515
{
16-
private SlackClient $slackClient;
17-
1816
public function __construct(
19-
SlackClient $slackClient,
20-
LoggingLogLevel $minLevel = LogLevel::CRITICAL,
21-
protected LogFormatter $formatter = new LineFormatter()
17+
private SlackClient $slackClient,
18+
protected LoggingLogLevel $minLevel = LogLevel::CRITICAL,
19+
protected LogFormatter $formatter = new LineFormatter(),
2220
) {
2321
parent::__construct($minLevel, $formatter);
24-
$this->slackClient = $slackClient;
2522
}
2623

2724
public function handle(ImmutableValue $record): void

src/Util/CurlClient.php

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,6 @@ public function post(string $url, array $data, array $headers = []): array
2525
];
2626
}
2727

28-
/**
29-
* Initialize a new cURL session.
30-
*
31-
* @param string $url the URL to initialize the cURL session with
32-
*
33-
* @throws \RuntimeException if cURL initialization fails
34-
*
35-
* @return \CurlHandle the cURL handle
36-
*/
37-
private function initializeCurl(string $url): \CurlHandle
38-
{
39-
$ch = curl_init($url);
40-
if (false === $ch) {
41-
throw new \RuntimeException('Failed to initialize cURL');
42-
}
43-
44-
return $ch;
45-
}
46-
4728
/**
4829
* Set POST options for the cURL session.
4930
*
@@ -64,12 +45,31 @@ private function setPostOptions(\CurlHandle $ch, array $data, array $headers): v
6445
curl_setopt_array($ch, [
6546
CURLOPT_POST => true,
6647
CURLOPT_POSTFIELDS => $payload,
67-
CURLOPT_HTTPHEADER => array_merge(self::DEFAULT_HEADERS, $headers),
48+
CURLOPT_HTTPHEADER => $headers,
6849
CURLOPT_RETURNTRANSFER => true,
6950
CURLOPT_TIMEOUT => self::TIMEOUT,
7051
]);
7152
}
7253

54+
/**
55+
* Initialize a new cURL session.
56+
*
57+
* @param string $url the URL to initialize the cURL session with
58+
*
59+
* @throws \RuntimeException if cURL initialization fails
60+
*
61+
* @return \CurlHandle the cURL handle
62+
*/
63+
private function initializeCurl(string $url): \CurlHandle
64+
{
65+
$ch = curl_init($url);
66+
if (false === $ch) {
67+
throw new \RuntimeException('Failed to initialize cURL');
68+
}
69+
70+
return $ch;
71+
}
72+
7373
/**
7474
* Execute the cURL request.
7575
*

src/Util/SlackClient.php

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,29 @@
1111

1212
class SlackClient
1313
{
14-
private readonly string $webhookUrl;
15-
private readonly CircuitBreaker $circuitBreaker;
16-
private readonly Retry $retry;
17-
private readonly Fallback $fallback;
18-
private readonly CurlClient $curlClient;
14+
private const SLACK_API_URL = 'https://slack.com/api/chat.postMessage';
1915

2016
public function __construct(
21-
string $webhookUrl,
22-
CircuitBreaker $circuitBreaker,
23-
Retry $retry,
24-
Fallback $fallback,
25-
CurlClient $curlClient
17+
private string $botToken,
18+
private string $channel,
19+
private CircuitBreaker $circuitBreaker,
20+
private Retry $retry,
21+
private Fallback $fallback,
22+
private CurlClient $curlClient
2623
) {
27-
$this->setWebhookUrl($webhookUrl);
28-
$this->circuitBreaker = $circuitBreaker;
29-
$this->retry = $retry;
30-
$this->fallback = $fallback;
31-
$this->curlClient = $curlClient;
3224
}
3325

3426
public static function create(
35-
string $webhookUrl,
27+
string $botToken,
28+
string $channel,
3629
?CircuitBreaker $circuitBreaker = null,
3730
?Retry $retry = null,
3831
?Fallback $fallback = null,
3932
?CurlClient $curlClient = null
4033
): self {
4134
return new self(
42-
$webhookUrl,
35+
$botToken,
36+
$channel,
4337
$circuitBreaker ?? new CircuitBreaker(3, 60),
4438
$retry ?? new Retry(3, 1000, 2, 100),
4539
$fallback ?? new Fallback(),
@@ -75,13 +69,21 @@ private function doSendMessage(string $message): void
7569

7670
private function createPayload(string $message): array
7771
{
78-
return ['text' => $message];
72+
return [
73+
'channel' => $this->channel,
74+
'text' => $message,
75+
];
7976
}
8077

8178
private function sendRequest(array $payload): array
8279
{
80+
$headers = [
81+
'Content-Type: application/json; charset=utf-8',
82+
'Authorization: Bearer ' . $this->botToken,
83+
];
84+
8385
try {
84-
return $this->curlClient->post($this->webhookUrl, $payload);
86+
return $this->curlClient->post(self::SLACK_API_URL, $payload, $headers);
8587
} catch (\JsonException $e) {
8688
$this->circuitBreaker->recordFailure();
8789
throw new LoggingException('Failed to encode message for Slack: ' . $e->getMessage(), 0, $e);
@@ -94,26 +96,14 @@ private function sendRequest(array $payload): array
9496
private function handleResponse(array $response): void
9597
{
9698
$httpCode = $response['status'];
97-
$responseBody = $response['body'];
99+
$responseBody = json_decode($response['body'], true);
98100

99-
if ($httpCode < 200 || $httpCode >= 300) {
101+
if ($httpCode < 200 || $httpCode >= 300 || !$responseBody['ok']) {
100102
$this->circuitBreaker->recordFailure();
101-
throw new LoggingException('Slack API responded with HTTP code ' . $httpCode . ': ' . $responseBody);
103+
$errorMessage = $responseBody['error'] ?? 'Unknown error';
104+
throw new LoggingException('Slack API responded with error: ' . $errorMessage);
102105
}
103106

104107
$this->circuitBreaker->recordSuccess();
105108
}
106-
107-
private function setWebhookUrl(string $webhookUrl): void
108-
{
109-
if (false === filter_var($webhookUrl, FILTER_VALIDATE_URL)) {
110-
throw new \InvalidArgumentException('Invalid webhook URL');
111-
}
112-
$this->webhookUrl = $webhookUrl;
113-
}
114-
115-
public function getWebhookUrl(): string
116-
{
117-
return $this->webhookUrl;
118-
}
119109
}

tests/Logger/test_config.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<?php return ['key' => 'value'];
1+
<?php return ['key' => 'value'];

tests/application.php

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
// application.php
34
require_once __DIR__ . '/../vendor/autoload.php';
45

56
use KaririCode\Logging\LoggerConfiguration;
@@ -26,16 +27,16 @@
2627

2728
$serviceProvider->register();
2829

29-
$defaultLogger = $loggerRegistry->getLogger('console');
30+
// $defaultLogger = $loggerRegistry->getLogger('console');
3031

31-
$defaultLogger->debug('User email is john.doe@example.com');
32-
$defaultLogger->info('User IP is 192.168.1.1');
33-
$defaultLogger->notice('User credit card number is 1234-5678-1234-5678', ['context' => 'credit card']);
34-
$defaultLogger->warning('User phone number is (11) 91234-7890', ['context' => 'phone']);
35-
$defaultLogger->error('This is an error message with email john.doe@example.com', ['context' => 'error']);
36-
$defaultLogger->critical('This is a critical message with IP 192.168.1.1', ['context' => 'critical']);
37-
$defaultLogger->alert('This is an alert message with credit card 1234-5678-1234-5678', ['context' => 'alert']);
38-
$defaultLogger->emergency('This is an emergency message with phone number 123-456-7890', ['context' => 'emergency']);
32+
// $defaultLogger->debug('User email is john.doe@example.com');
33+
// $defaultLogger->info('User IP is 192.168.1.1');
34+
// $defaultLogger->notice('User credit card number is 1234-5678-1234-5678', ['context' => 'credit card']);
35+
// $defaultLogger->warning('User phone number is (11) 91234-7890', ['context' => 'phone']);
36+
// $defaultLogger->error('This is an error message with email john.doe@example.com', ['context' => 'error']);
37+
// $defaultLogger->critical('This is a critical message with IP 192.168.1.1', ['context' => 'critical']);
38+
// $defaultLogger->alert('This is an alert message with credit card 1234-5678-1234-5678', ['context' => 'alert']);
39+
// $defaultLogger->emergency('This is an emergency message with phone number 123-456-7890', ['context' => 'emergency']);
3940

4041
// $asyncLogger = $loggerRegistry->getLogger('async');
4142
// if ($asyncLogger) {
@@ -58,3 +59,6 @@
5859

5960
// $errorLogger = $loggerRegistry->getLogger('error');
6061
// $errorLogger->error('This is a critical error.', ['context' => 'Testing error logger']);
62+
63+
$slackLogger = $loggerRegistry->getLogger('slack');
64+
$slackLogger->critical('Este é um teste de mensagem crítica enviada para o Slack');

0 commit comments

Comments
 (0)