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

LogParser::getFormat()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
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;
0 ignored issues
show
Bug introduced by kristuff
The type Kristuff\Parselog\Core\LogFormat was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

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