SlackLogger::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 3
1
<?php
2
3
namespace DominionEnterprises\Psr\Log;
4
5
use Chadicus\Psr\Log\LevelValidatorTrait;
6
use Chadicus\Psr\Log\MessageValidatorTrait;
7
use Chadicus\Psr\Log\MessageInterpolationTrait;
8
use GuzzleHttp\ClientInterface;
9
use Psr\Log\AbstractLogger;
10
use Psr\Log\LoggerInterface;
11
use Psr\Log\LogLevel;
12
13
/**
14
 * PSR-3 Logger implementation writing to a slack web hook.
15
 */
16
final class SlackLogger extends AbstractLogger implements LoggerInterface
17
{
18
    use LevelValidatorTrait;
19
    use MessageValidatorTrait;
20
    use MessageInterpolationTrait;
21
22
    /**
23
     * Guzzle HTTP client.
24
     *
25
     * @var ClientInterface
26
     */
27
    private $client;
28
29
    /**
30
     * Slack web hook url
31
     *
32
     * @var string
33
     */
34
    private $webHookUrl;
35
36
    /**
37
     * Array of log levels which should be reported to Slack.
38
     *
39
     * @var string[]
40
     */
41
    private $observedLevels;
42
43
    /**
44
     * Create a new instance of SlackLogger.
45
     *
46
     * @param ClientInterface $client         Guzzle HTTP client.
47
     * @param string          $webHookUrl     Slack web hook url.
48
     * @param array           $observedLevels Array of log levels which should be reported to Slack.
49
     */
50
    public function __construct(
51
        ClientInterface $client,
52
        string $webHookUrl,
53
        array $observedLevels = [LogLevel::EMERGENCY]
54
    ) {
55
        $this->client = $client;
56
        $this->webHookUrl = $webHookUrl;
57
        array_walk($observedLevels, [$this, 'validateLevel']);
58
        $this->observedLevels = $observedLevels;
59
    }
60
61
    /**
62
     * Logs with an arbitrary level.
63
     *
64
     * @param string $level   A valid RFC 5424 log level.
65
     * @param string $message The base log message.
66
     * @param array  $context Any extraneous information that does not fit well in a string.
67
     *
68
     * @return void
69
     */
70
    public function log($level, $message, array $context = [])//@codingStandardsIgnoreLine Interface does not define type-hints
71
    {
72
        if (!in_array($level, $this->observedLevels)) {
73
            return;
74
        }
75
76
        $this->validateLevel($level);
77
        $this->validateMessage($message);
78
79
        $exception = $this->getExceptionStringFromContext($context);
80
        unset($context['exception']);
81
82
        $payload = json_encode(
83
            ['text' => "*[{$level}]* {$this->interpolateMessage($message, $context)}{$exception}", 'mrkdwn' => true]
84
        );
85
86
        $this->client->post($this->webHookUrl, ['body' => ['payload' => $payload]]);
87
    }
88
89
    private function getExceptionStringFromContext(array $context) : string
90
    {
91
        $exception = $context['exception'] ?? null;
92
        if (!is_a($exception, '\\Throwable')) {
93
            return '';
94
        }
95
96
        return sprintf(
97
            "\n*Exception:* %s\n*Message:* %s\n*File:* %s\n*Line:* %d",
98
            get_class($context['exception']),
99
            $context['exception']->getMessage(),
100
            $context['exception']->getFile(),
101
            $context['exception']->getLine()
102
        );
103
    }
104
}
105