|
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.2.0 |
|
16
|
|
|
* @copyright 2017-2020 Kristuff |
|
17
|
|
|
*/ |
|
18
|
|
|
|
|
19
|
|
|
namespace Kristuff\Parselog\Software; |
|
20
|
|
|
|
|
21
|
|
|
use Kristuff\Parselog\Core\LogEntryFactoryInterface; |
|
22
|
|
|
|
|
23
|
|
|
class ApacheAccessLogParser extends SoftwareLogParser |
|
24
|
|
|
{ |
|
25
|
|
|
/** |
|
26
|
|
|
* Constructor |
|
27
|
|
|
* |
|
28
|
|
|
* @access public |
|
29
|
|
|
* @param string $format |
|
30
|
|
|
* @param LogEntryFactoryInterface $factory |
|
31
|
|
|
* |
|
32
|
|
|
* @return void |
|
33
|
|
|
*/ |
|
34
|
|
|
public function __construct(string $format = null, LogEntryFactoryInterface $factory = null) |
|
35
|
|
|
{ |
|
36
|
|
|
$this->software = 'Apache'; |
|
37
|
|
|
$this->prettyName = 'Apache Access'; |
|
38
|
|
|
$this->defaultFormat = "%h %l %u %t \"%r\" %>s %b"; |
|
39
|
|
|
|
|
40
|
|
|
$this->addPath("/var/log/"); |
|
41
|
|
|
$this->addPath("/var/log/apache/"); |
|
42
|
|
|
$this->addPath("/var/log/apache2/"); |
|
43
|
|
|
$this->addPath("/var/log/httpd/"); |
|
44
|
|
|
$this->addPath("/usr/local/var/log/apache/"); |
|
45
|
|
|
$this->addPath("/usr/local/var/log/apache2/"); |
|
46
|
|
|
$this->addPath("/usr/local/var/log/httpd/"); |
|
47
|
|
|
$this->addPath("/opt/local/apache/logs/"); |
|
48
|
|
|
$this->addPath("/opt/local/apache2/logs/"); |
|
49
|
|
|
$this->addPath("/opt/local/httpd/logs/"); |
|
50
|
|
|
$this->addPath("C:/wamp/logs/"); |
|
51
|
|
|
|
|
52
|
|
|
$this->addFile('access.log'); |
|
53
|
|
|
$this->addFile('access_log'); |
|
54
|
|
|
$this->addFile('apache.log'); |
|
55
|
|
|
$this->addFile('apache_access.log'); |
|
56
|
|
|
|
|
57
|
|
|
$this->addFormat('apache_common', '%h %l %u %t \"%r\" %>s %O"'); |
|
58
|
|
|
$this->addFormat('apache_combined_vhost', '%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"'); |
|
59
|
|
|
$this->addFormat('apache_combined', '%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"'); |
|
60
|
|
|
|
|
61
|
|
|
$this->addColumn('%%' , 'percent', '', '(?P<percent>\%)'); |
|
62
|
|
|
$this->addColumn('%t' , 'time', 'Date', '\[(?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})\]'); |
|
63
|
|
|
$this->addColumn('%v' , 'serverName', 'ServerName', '(?P<serverName>([a-zA-Z0-9]+)([a-z0-9.-]*))'); |
|
64
|
|
|
$this->addColumn('%V' , 'canonicalServerName', 'Canonical ServerName', '(?P<canonicalServerName>([a-zA-Z0-9]+)([a-z0-9.-]*))'); |
|
65
|
|
|
$this->addColumn('%p' , 'port', 'Port', '(?P<port>\d+)'); |
|
66
|
|
|
|
|
67
|
|
|
// Client IP address of the request |
|
68
|
|
|
$this->addColumn('%a', 'remoteIp', 'IP', '(?P<remoteIp>{{PATTERN_IP_ALL}})'); |
|
69
|
|
|
|
|
70
|
|
|
// Remote hostname |
|
71
|
|
|
$this->addColumn('%h' , 'host', 'Remote Host', '(?P<host>[a-zA-Z0-9\-\._:]+)'); |
|
72
|
|
|
|
|
73
|
|
|
// Local IP-address |
|
74
|
|
|
$this->addColumn('%A', 'localIp', 'Local IP', '(?P<localIp>{{PATTERN_IP_ALL}})'); |
|
75
|
|
|
|
|
76
|
|
|
// Remote user if the request was authenticated. May be bogus if return status (%s) is 401 (unauthorized). |
|
77
|
|
|
$this->addColumn('%u', 'user', 'User', '(?P<user>(?:-|[\w\-\.]+))'); |
|
78
|
|
|
|
|
79
|
|
|
$this->addColumn('%l', 'logname', 'Log Name', '(?P<logname>(?:-|[\w-]+))'); |
|
80
|
|
|
$this->addColumn('%m', 'requestMethod', 'Method', '(?P<requestMethod>OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH|PROPFIND)'); |
|
81
|
|
|
$this->addColumn('%U', 'URL', 'URL', '(?P<URL>.+?)'); |
|
82
|
|
|
$this->addColumn('%H', 'requestProtocol', 'Protocol', '(?P<requestProtocol>HTTP/(1\.0|1\.1|2\.0))'); |
|
83
|
|
|
$this->addColumn('%r', 'request', 'Request', '(?P<request>(?:(?:[A-Z]+) .+? HTTP/(1\.0|1\.1|2\.0))|-|)'); |
|
84
|
|
|
$this->addColumn('%>s','statuts', 'Status', '(?P<status>\d{3}|-)'); |
|
85
|
|
|
$this->addColumn('%O', 'sentBytes', 'Size', '(?P<sentBytes>[0-9]+)'); |
|
86
|
|
|
|
|
87
|
|
|
// Size of response in bytes, excluding HTTP headers. In CLF format, i.e. a '-' rather than a 0 when no bytes are sent. |
|
88
|
|
|
$this->addColumn('%b', 'responseBytes', 'Response Size', '(?P<responseBytes>(\d+|-))'); |
|
89
|
|
|
|
|
90
|
|
|
//The time taken to serve the request, in seconds. |
|
91
|
|
|
$this->addColumn('%T', 'requestTime', 'Request Time', '(?P<requestTime>(\d+\.?\d*))'); |
|
92
|
|
|
$this->addColumn('%D', 'timeServeRequest', 'Time Server Request', '(?P<timeServeRequest>[0-9]+)'); |
|
93
|
|
|
$this->addColumn('%I', 'receivedBytes', 'Received Bytes', '(?P<receivedBytes>[0-9]+)'); |
|
94
|
|
|
|
|
95
|
|
|
// common named columns (no pattern, use generic pattern bellow) |
|
96
|
|
|
$this->addColumn('%{Referer}i', 'headerReferer', 'Referer', ''); |
|
97
|
|
|
$this->addColumn('%{User-Agent}i', 'headerUserAgent', 'User Agent', ''); |
|
98
|
|
|
|
|
99
|
|
|
// dymanic named columns |
|
100
|
|
|
$this->addPattern('\%\{(?P<name>[a-zA-Z]+)(?P<name2>[-]?)(?P<name3>[a-zA-Z]+)\}i', '(?P<header\\1\\3>.*?)'); |
|
101
|
|
|
|
|
102
|
|
|
|
|
103
|
|
|
parent::__construct($format, $factory); |
|
104
|
|
|
} |
|
105
|
|
|
|
|
106
|
|
|
} |