{"id":17644429,"url":"https://github.com/kassner/log-parser","last_synced_at":"2025-05-14T15:11:00.594Z","repository":{"id":10566752,"uuid":"12770994","full_name":"kassner/log-parser","owner":"kassner","description":"PHP Web Server Log Parser Library","archived":false,"fork":false,"pushed_at":"2024-12-04T21:10:52.000Z","size":181,"stargazers_count":339,"open_issues_count":2,"forks_count":64,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-04-12T01:52:12.034Z","etag":null,"topics":["log-parser","php"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kassner.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-09-12T00:11:32.000Z","updated_at":"2024-11-18T03:20:50.000Z","dependencies_parsed_at":"2024-12-05T11:02:55.134Z","dependency_job_id":"b24aa24c-b51d-4085-bc58-880f97ef96c2","html_url":"https://github.com/kassner/log-parser","commit_stats":{"total_commits":154,"total_committers":16,"mean_commits":9.625,"dds":"0.16883116883116878","last_synced_commit":"2869685c00f230337df54efbcb13af5f21528791"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kassner%2Flog-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kassner%2Flog-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kassner%2Flog-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kassner%2Flog-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kassner","download_url":"https://codeload.github.com/kassner/log-parser/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248505873,"owners_count":21115354,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["log-parser","php"],"created_at":"2024-10-23T10:05:24.960Z","updated_at":"2025-04-12T01:52:16.597Z","avatar_url":"https://github.com/kassner.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Web server access Log Parser\n\nParse your Apache/Nginx/Varnish/HAProxy logs into PHP objects to programatically handle the data.\n\n## Install\n\n```\ncomposer require kassner/log-parser:~2.2\n```\n\n## Usage\n\n```php\n$parser = new \\Kassner\\LogParser\\LogParser();\n$lines = file('/var/log/apache2/access.log', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);\nforeach ($lines as $line) {\n    $entry = $parser-\u003eparse($line);\n}\n```\n\nThe `$entry` object will hold all data parsed. If the line does not match the defined format, a `\\Kassner\\LogParser\\FormatException` will be thrown.\n\n```php\nobject(Kassner\\LogParser\\SimpleLogEntry)#4 (8) {\n  [\"host\"]=\u003e\n  string(14) \"193.191.216.76\"\n  [\"logname\"]=\u003e\n  string(1) \"-\"\n  [\"user\"]=\u003e\n  string(8) \"www-data\"\n  [\"stamp\"]=\u003e\n  int(1390794676)\n  [\"time\"]=\u003e\n  string(26) \"27/Jan/2014:04:51:16 +0100\"\n  [\"request\"]=\u003e\n  string(53) \"GET /wp-content/uploads/2013/11/whatever.jpg HTTP/1.1\"\n  [\"status\"]=\u003e\n  string(3) \"200\"\n  [\"responseBytes\"]=\u003e\n  string(5) \"58678\"\n}\n```\n\n## Customizations\n\n### Log format\n\nYou may customize the log format (by default it matches the [Apache common log format](https://httpd.apache.org/docs/2.2/en/logs.html#common))\n\n```php\n# default Nginx format:\n$parser-\u003esetFormat('%h %l %u %t \"%r\" %\u003es %O \"%{Referer}i\" \\\"%{User-Agent}i\"');\n```\n\n#### Supported format strings\n\nHere is the full list of [log format strings](https://httpd.apache.org/docs/2.2/en/mod/mod_log_config.html#formats) supported by Apache, and whether they are supported by the library :\n\n| Supported? | Format String | Property name | Description |\n|:----------:|:-------------:|---------------|-------------|\n| Y | %% | percent |The percent sign |\n| Y | %\u003es | status |status |\n| Y | %A | localIp |Local IP-address |\n| Y | %a | remoteIp |Remote IP-address |\n| N | %B | - |Size of response in bytes, excluding HTTP headers. |\n| Y | %b | responseBytes |Size of response in bytes, excluding HTTP headers. In CLF format, i.e. a '-' rather than a 0 when no bytes are sent. |\n| Y | %D | timeServeRequest | The time taken to serve the request, in microseconds. |\n| N | %f | - | Filename |\n| Y | %h | host |Remote host |\n| X | %H | - |The request protocol (this is Apache specific) |\n| Y | %I | receivedBytes | Bytes received, including request and headers, cannot be zero. You need to enable mod_logio to use this. |\n| N | %k | - | Number of keepalive requests handled on this connection. Interesting if KeepAlive is being used, so that, for example, a '1' means the first keepalive request after the initial one, '2' the second, etc...; otherwise this is always 0 (Y indicating the initial request). Available in versions 2.2.11 and later. |\n| Y | %l | logname | Remote logname (from identd, if supplied). This will return a dash unless mod_ident is present and IdentityCheck is set On. |\n| Y | %m | requestMethod | The request method |\n| Y | %O | sentBytes | Bytes sent, including headers, cannot be zero. You need to enable mod_logio to use this. |\n| Y | %p | port | The canonical port of the server serving the request |\n| N | %P | - | The process ID of the child that serviced the request. |\n| N | %q | - | The query string (prepended with a ? if a query string exists, otherwise an empty string) |\n| Y | %r | request | First line of request |\n| N | %R | - | The handler generating the response (if any). |\n| X | %S | scheme | This is `nginx` specific: https://nginx.org/en/docs/http/ngx_http_core_module.html#var_scheme |\n| N | %s | - | Status. For requests that got internally redirected, this is the status of the *original* request --- %\u003es for the last. |\n| X | %T | requestTime | The time taken to serve the request, in seconds. This option is not consistent, Apache won't inform the milisecond part. |\n| Y | %t | time | Time the request was received (standard english format) |\n| Y | %u | user | Remote user (from auth; may be bogus if return status (%s) is 401) |\n| Y | %U | URL | The URL path requested, not including any query string. |\n| Y | %v | serverName | The canonical ServerName of the server serving the request. |\n| Y | %V | canonicalServerName | The server name according to the UseCanonicalName setting. |\n| N | %X | - | Connection status when response is completed: X = connection aborted before the response completed. + = connection may be kept alive after the response is sent. - = connection will be closed after the response is sent. |\n| N | %{Foobar}C | - | The contents of cookie Foobar in the request sent to the server. Only version 0 cookies are fully supported. |\n| N | %{Foobar}e | - | The contents of the environment variable FOOBAR |\n| Y | %{Foobar}i | *Header | The contents of Foobar: header line(s) in the request sent to the server. Changes made by other modules (e.g. mod_headers) affect this. If you're interested in what the request header was prior to when most modules would have modified it, use mod_setenvif to copy the header into an internal environment variable and log that value with the %{VARNAME}e described above. |\n| N | %{Foobar}n | - | The contents of note Foobar from another module. |\n| N | %{Foobar}o | - | The contents of Foobar: header line(s) in the reply. |\n| Y | %{format}p | *Port | The canonical port of the server serving the request or the server's actual port or the client's actual port. Valid formats are canonical, local, or remote. |\n| N | %{format}P | - | The process ID or thread id of the child that serviced the request. Valid formats are pid, tid, and hextid. hextid requires APR 1.2.0 or higher. |\n| N | %{format}t | - | The time, in the form given by format, which should be in strftime(3) format. (potentially localized) (This directive was %c in late versions of Apache 1.3, but this conflicted with the historical ssl %{var}c syntax.) |\n\n\u003e Beware: You should really read the notes when using a option that is marked with a `X` on the `Supported?` column.\n\n### Custom formats\n\nSee https://github.com/kassner/log-parser/issues/50#issuecomment-706707736\n\n### Entry object\n\nBefore `2.0.0` it was possible to overwrite the entry object returned by overwriting the `createEntry` method. With strict types, this is no longer possible, so instead you have to use the newly created interfaces.\n\nFirst, create two new classes, your entry object and a factory that is responsible of creating it:\n\n```php\nclass MyEntry implements \\Kassner\\LogParser\\LogEntryInterface\n{\n}\n\nclass MyEntryFactory implements \\Kassner\\LogParser\\LogEntryFactoryInterface\n{\n    public function create(array $data): \\Kassner\\LogParser\\LogEntryInterface\n    {\n        // @TODO implement your code here to return a instance of MyEntry\n    }\n}\n```\n\nAnd then provide the factory as the second argument to the `LogParser` constructor:\n\n```php\n$factory = new MyEntryFactory();\n$parser = new \\Kassner\\LogParser\\LogParser(null, $factory);\n$entry = $parser-\u003eparse('193.191.216.76 - www-data [27/Jan/2014:04:51:16 +0100] \"GET /wp-content/uploads/2013/11/whatever.jpg HTTP/1.1\" 200 58678');\n```\n\n`$entry` will be an instance of `MyEntry`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkassner%2Flog-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkassner%2Flog-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkassner%2Flog-parser/lists"}