Completed
Push — master ( 3c2af6...aff089 )
by Chad
10s
created

MongoLogger   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 7
dl 0
loc 89
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A log() 0 13 1
A buildBasicDocument() 0 8 1
A getExceptionData() 0 9 2
A getNormalizeArray() 0 9 2
A getNormalizedValue() 0 12 5
1
<?php
2
3
namespace SubjectivePHP\Psr\Log;
4
5
use MongoDB\BSON\UTCDateTime;
6
use MongoDB\Collection;
7
use MongoDB\Driver\Exception\UnexpectedValueException;
8
use Psr\Log\AbstractLogger;
9
use Psr\Log\InvalidArgumentException;
10
use Psr\Log\LoggerInterface;
11
use SubjectivePHP\Util\Exception;
12
13
/**
14
 * PSR-3 Logger implementation writing to a MongoDB.
15
 */
16
final class MongoLogger extends AbstractLogger implements LoggerInterface
17
{
18
    use ExceptionExtractorTrait;
19
    use LevelValidatorTrait;
20
    use MessageInterpolationTrait;
21
    use MessageValidatorTrait;
22
23
    /**
24
     * Collection containing logs.
25
     *
26
     * @var Collection
27
     */
28
    private $collection;
29
30
    /**
31
     * Create a new instance of MongoLogger.
32
     *
33
     * @param Collection $collection Mongo collection to which the logs should be written.
34
     */
35
    public function __construct(Collection $collection)
36
    {
37
        $this->collection = $collection;
38
    }
39
40
    /**
41
     * Logs with an arbitrary level.
42
     *
43
     * @param string $level   A valid RFC 5424 log level.
44
     * @param string $message The base log message.
45
     * @param array  $context Any extraneous information that does not fit well in a string.
46
     *
47
     * @return void
48
     */
49
    public function log($level, $message, array $context = [])//@codingStandardsIgnoreLine Ignore missing type hints
50
    {
51
        $this->validateLevel($level);
52
        $this->validateMessage($message);
53
54
        $document = $this->buildBasicDocument($level, $message, $context);
55
56
        $document['exception'] = $this->getExceptionData($context);
57
        unset($context['exception']);
58
59
        $document['extra'] = $this->getNormalizeArray($context);
60
        $this->collection->insertOne($document, ['w' => 0]);
61
    }
62
63
    private function buildBasicDocument(string $level, string $message, array $context = [])
64
    {
65
        return [
66
            'timestamp' => new UTCDateTime((int)(microtime(true) * 1000)),
67
            'level' => $level,
68
            'message' => $this->interpolateMessage((string)$message, $context),
69
        ];
70
    }
71
72
    private function getExceptionData(array $context = [])
73
    {
74
        $exception = $this->getExceptionFromContext($context);
75
        if ($exception === null) {
76
            return null;
77
        }
78
79
        return Exception::toArray($exception, true);
80
    }
81
82
    private function getNormalizeArray(array $array = [])
83
    {
84
        $normalized = [];
85
        foreach ($array as $key => $value) {
86
            $normalized[$key] = $this->getNormalizedValue($value);
87
        }
88
89
        return $normalized;
90
    }
91
92
    private function getNormalizedValue($value)
93
    {
94
        if (is_array($value)) {
95
            return $this->getNormalizeArray($value);
96
        }
97
98
        if (is_object($value)) {
99
            return  method_exists($value, '__toString') ? "{$value}" : get_class($value);
100
        }
101
102
        return is_scalar($value) ? $value : gettype($value);
103
    }
104
}
105