Completed
Push — master ( fd3f7a...5ba35e )
by Kris
02:21
created

src/LogParser.php (1 issue)

1
<?php declare(strict_types=1);
2
3
/** 
4
 *  ___                      _
5
 * | _ \ __ _  _ _  ___ ___ | | ___  __ _
6
 * |  _// _` || '_|(_-</ -_)| |/ _ \/ _` |
7
 * |_|  \__,_||_|  /__/\___||_|\___/\__, |
8
 *                                  |___/
9
 * 
10
 * (c) Kristuff <[email protected]>
11
 *
12
 * For the full copyright and license information, please view the LICENSE
13
 * file that was distributed with this source code.
14
 *
15
 * @version    0.1.0
16
 * @copyright  2017-2020 Kristuff
17
 */
18
19
namespace Kristuff\Parselog;
20
21
use Kristuff\Parselog\Core\LogFormat;
22
use Kristuff\Parselog\Core\LogEntryInterface;
23
use Kristuff\Parselog\Core\LogEntryFactory;
24
use Kristuff\Parselog\Core\LogEntryFactoryInterface;
25
26
/** 
27
 * LogParser
28
 */
29
class LogParser
30
{
31
    /** 
32
     * @var string 
33
     */
34
    private $pcreFormat;
35
36
    /** 
37
     * @var LogFormat
38
     */
39
    private $logFormat = '';
40
41
     /** 
42
     * @var array 
43
     */
44
    public $patterns = [];
45
46
    /** 
47
     * @var string
48
     */
49
    public $defaultFormat = '';
50
51
    /**
52
     *  @var LogEntryFactoryInterface 
53
     */
54
    private $factory;
55
56
57
    public function __construct(string $format = null, LogEntryFactoryInterface $factory = null)
58
    {
59
        $this->logFormat = $format ?? $this->defaultFormat;
0 ignored issues
show
Documentation Bug introduced by
It seems like $format ?? $this->defaultFormat of type string is incompatible with the declared type Kristuff\Parselog\Core\LogFormat of property $logFormat.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
60
        $this->updateIpPatterns();
61
        $this->setFormat($this->logFormat);
62
        $this->factory = $factory ?: new LogEntryFactory();
63
    }
64
65
    /**
66
     * Sets/Adds pattern 
67
     * 
68
     * @access public
69
     * @param string    $placeholder    
70
     * @param string    $pattern        
71
     * 
72
     * @return void
73
     */
74
    public function addPattern(string $placeholder, string $pattern): void
75
    {
76
        $this->patterns[$placeholder] = $pattern;
77
        $this->updateIpPatterns();
78
    }
79
80
    /**
81
     * Sets the log format  
82
     * 
83
     * @access public
84
     * @param string    $format
85
     * 
86
     * @return void
87
     */
88
    public function setFormat(string $format): void
89
    {
90
        // strtr won't work for "complex" header patterns
91
        // $this->pcreFormat = strtr("#^{$format}$#", $this->patterns);
92
        $expr = "#^{$format}$#";
93
94
        foreach ($this->patterns as $pattern => $replace) {
95
            $expr = preg_replace("/{$pattern}/", $replace, $expr);
96
        }
97
98
        $this->pcreFormat = $expr;
99
    }
100
101
    /**
102
     * Parses one single log line.
103
     * 
104
     * @access public
105
     * @param string    $line
106
     * 
107
     * @return LogEntryInterface
108
     * @throws FormatException
109
     */
110
    public function parse(string $line): LogEntryInterface
111
    {
112
        if (!preg_match($this->getPCRE(), $line, $matches)) {
113
            throw new FormatException($line);
114
        }
115
116
        return $this->factory->create($matches);
117
    }
118
119
    /**
120
     * Gets the PCRE filter.
121
     * 
122
     * @access public
123
     * @return string
124
     */
125
    public function getPCRE(): string
126
    {
127
        return (string) $this->pcreFormat;
128
    }
129
130
    /**
131
     * Replaces {{PATTERN_IP_ALL}} with the IPV4/6 patterns.
132
     * 
133
     * @access public
134
     * @return void
135
     */
136
    private function updateIpPatterns(): void
137
    {
138
        // Set IPv4 & IPv6 recognition patterns
139
        $ipPatterns = implode('|', [
140
            'ipv4' => '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9]))',
141
            'ipv6full' => '([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){7})', // 1:1:1:1:1:1:1:1
142
            'ipv6null' => '(::)',
143
            'ipv6leading' => '(:(:[0-9A-Fa-f]{1,4}){1,7})', // ::1:1:1:1:1:1:1
144
            'ipv6mid' => '(([0-9A-Fa-f]{1,4}:){1,6}(:[0-9A-Fa-f]{1,4}){1,6})', // 1:1:1::1:1:1
145
            'ipv6trailing' => '(([0-9A-Fa-f]{1,4}:){1,7}:)', // 1:1:1:1:1:1:1::
146
        ]);
147
148
        foreach ($this->patterns as &$value) {
149
            $value = str_replace('{{PATTERN_IP_ALL}}', $ipPatterns, $value);
150
        }
151
    }
152
}