-
Notifications
You must be signed in to change notification settings - Fork 0
/
LogParser.php
83 lines (75 loc) · 2.95 KB
/
LogParser.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?php
/**
* Created by PhpStorm.
* User: kharr
* Date: 22/02/2017
* Time: 21:09
*/
class LogParser
{
protected static $defaultFormat = '%h %l %u %t "%r" %>s %b';
protected $pcreFormat;
protected $patterns = array(
'%%' => '(?P<percent>\%)',
'%a' => '(?P<remoteIp>)',
'%A' => '(?P<localIp>)',
'%h' => '(?P<host>[a-zA-Z0-9\-\._:]+)',
'%l' => '(?P<logname>(?:-|[\w-]+))',
'%m' => '(?P<requestMethod>OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH|PROPFIND)',
'%p' => '(?P<port>\d+)',
'%r' => '(?P<request>(?:(?:[A-Z]+) .+? HTTP/1.(?:0|1))|-|)',
'%t' => '\[(?P<time>\d{2}/(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/\d{4}:\d{2}:\d{2}:\d{2} (?:-|\+)\d{4})\]',
'%u' => '(?P<user>(?:-|[\w-]+))',
'%U' => '(?P<URL>.+?)',
'%v' => '(?P<serverName>([a-zA-Z0-9]+)([a-z0-9.-]*))',
'%V' => '(?P<canonicalServerName>([a-zA-Z0-9]+)([a-z0-9.-]*))',
'%>s' => '(?P<status>\d{3}|-)',
'%b' => '(?P<responseBytes>(\d+|-))',
'%T' => '(?P<requestTime>(\d+\.?\d*))',
'%O' => '(?P<sentBytes>[0-9]+)',
'%I' => '(?P<receivedBytes>[0-9]+)',
'\%\{(?P<name>[a-zA-Z]+)(?P<name2>[-]?)(?P<name3>[a-zA-Z]+)\}i' => '(?P<Header\\1\\3>.*?)',
'%D' => '(?P<timeServeRequest>[0-9]+)',
);
public static function getDefaultFormat()
{
return self::$defaultFormat;
}
public function __construct($format = null)
{
// Set IPv4 & IPv6 recognition patterns
$ipPatterns = implode('|', array(
'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]))',
'ipv6full' => '([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){7})', // 1:1:1:1:1:1:1:1
'ipv6null' => '(::)',
'ipv6leading' => '(:(:[0-9A-Fa-f]{1,4}){1,7})', // ::1:1:1:1:1:1:1
'ipv6mid' => '(([0-9A-Fa-f]{1,4}:){1,6}(:[0-9A-Fa-f]{1,4}){1,6})', // 1:1:1::1:1:1
'ipv6trailing' => '(([0-9A-Fa-f]{1,4}:){1,7}:)', // 1:1:1:1:1:1:1::
));
$this->patterns['%a'] = '(?P<remoteIp>' . $ipPatterns . ')';
$this->patterns['%A'] = '(?P<localIp>' . $ipPatterns . ')';
$this->setFormat($format ?: self::getDefaultFormat());
}
public function parse($line)
{
if (!preg_match($this->pcreFormat, $line, $matches)) {
echo "No match\n";
}
$entry = new \stdClass();
foreach (array_filter(array_keys($matches), 'is_string') as $key) {
if ('time' === $key && true !== $stamp = strtotime($matches[$key])) {
$entry->stamp = $stamp;
}
$entry->{$key} = $matches[$key];
}
return $entry;
}
public function setFormat($format)
{
$expr = "#^{$format}$#";
foreach ($this->patterns as $pattern => $replace) {
$expr = preg_replace("/{$pattern}/", $replace, $expr);
}
$this->pcreFormat = $expr;
}
}