Completed
Push — master ( ec3aa9...7976db )
by Kris
02:07
created

src/LogParser.php (1 issue)

Labels
Severity
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.1
16
 * @copyright  2017-2020 Kristuff
17
 */
18
19
namespace Kristuff\Parselog;
20
21
use Kristuff\Parselog\Core\LogFormat;
0 ignored issues
show
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
}