PHPackages                             kassner/log-parser - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. kassner/log-parser

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

kassner/log-parser
==================

PHP Log Parser Library

2.2.0(1y ago)342432.5k↓12.3%65[1 issues](https://github.com/kassner/log-parser/issues)[1 PRs](https://github.com/kassner/log-parser/pulls)6Apache-2.0PHPPHP &gt;=7.4.0CI failing

Since Nov 6Pushed 1y ago15 watchersCompare

[ Source](https://github.com/kassner/log-parser)[ Packagist](https://packagist.org/packages/kassner/log-parser)[ Docs](http://github.com/kassner/log-parser)[ RSS](/packages/kassner-log-parser/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (4)DependenciesVersions (16)Used By (6)

Web server access Log Parser
============================

[](#web-server-access-log-parser)

Parse your Apache/Nginx/Varnish/HAProxy logs into PHP objects to programatically handle the data.

Install
-------

[](#install)

```
composer require kassner/log-parser:~2.2

```

Usage
-----

[](#usage)

```
$parser = new \Kassner\LogParser\LogParser();
$lines = file('/var/log/apache2/access.log', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
    $entry = $parser->parse($line);
}
```

The `$entry` object will hold all data parsed. If the line does not match the defined format, a `\Kassner\LogParser\FormatException` will be thrown.

```
object(Kassner\LogParser\SimpleLogEntry)#4 (8) {
  ["host"]=>
  string(14) "193.191.216.76"
  ["logname"]=>
  string(1) "-"
  ["user"]=>
  string(8) "www-data"
  ["stamp"]=>
  int(1390794676)
  ["time"]=>
  string(26) "27/Jan/2014:04:51:16 +0100"
  ["request"]=>
  string(53) "GET /wp-content/uploads/2013/11/whatever.jpg HTTP/1.1"
  ["status"]=>
  string(3) "200"
  ["responseBytes"]=>
  string(5) "58678"
}
```

Customizations
--------------

[](#customizations)

### Log format

[](#log-format)

You 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))

```
# default Nginx format:
$parser->setFormat('%h %l %u %t "%r" %>s %O "%{Referer}i" \"%{User-Agent}i"');
```

#### Supported format strings

[](#supported-format-strings)

Here 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 :

Supported?Format StringProperty nameDescriptionY%%percentThe percent signY%&gt;sstatusstatusY%AlocalIpLocal IP-addressY%aremoteIpRemote IP-addressN%B-Size of response in bytes, excluding HTTP headers.Y%bresponseBytesSize of response in bytes, excluding HTTP headers. In CLF format, i.e. a '-' rather than a 0 when no bytes are sent.Y%DtimeServeRequestThe time taken to serve the request, in microseconds.N%f-FilenameY%hhostRemote hostX%H-The request protocol (this is Apache specific)Y%IreceivedBytesBytes received, including request and headers, cannot be zero. You need to enable mod\_logio to use this.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.Y%llognameRemote logname (from identd, if supplied). This will return a dash unless mod\_ident is present and IdentityCheck is set On.Y%mrequestMethodThe request methodY%OsentBytesBytes sent, including headers, cannot be zero. You need to enable mod\_logio to use this.Y%pportThe canonical port of the server serving the requestN%P-The process ID of the child that serviced the request.N%q-The query string (prepended with a ? if a query string exists, otherwise an empty string)Y%rrequestFirst line of requestN%R-The handler generating the response (if any).X%SschemeThis is `nginx` specific: [https://nginx.org/en/docs/http/ngx\_http\_core\_module.html#var\_scheme](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_scheme)N%s-Status. For requests that got internally redirected, this is the status of the *original* request --- %&gt;s for the last.X%TrequestTimeThe time taken to serve the request, in seconds. This option is not consistent, Apache won't inform the milisecond part.Y%ttimeTime the request was received (standard english format)Y%uuserRemote user (from auth; may be bogus if return status (%s) is 401)Y%UURLThe URL path requested, not including any query string.Y%vserverNameThe canonical ServerName of the server serving the request.Y%VcanonicalServerNameThe server name according to the UseCanonicalName setting.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%{Foobar}C-The contents of cookie Foobar in the request sent to the server. Only version 0 cookies are fully supported.N%{Foobar}e-The contents of the environment variable FOOBARY%{Foobar}i\*HeaderThe 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%{Foobar}n-The contents of note Foobar from another module.N%{Foobar}o-The contents of Foobar: header line(s) in the reply.Y%{format}p\*PortThe 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%{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%{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.)> Beware: You should really read the notes when using a option that is marked with a `X` on the `Supported?` column.

### Custom formats

[](#custom-formats)

See [\#50 (comment)](https://github.com/kassner/log-parser/issues/50#issuecomment-706707736)

### Entry object

[](#entry-object)

Before `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.

First, create two new classes, your entry object and a factory that is responsible of creating it:

```
class MyEntry implements \Kassner\LogParser\LogEntryInterface
{
}

class MyEntryFactory implements \Kassner\LogParser\LogEntryFactoryInterface
{
    public function create(array $data): \Kassner\LogParser\LogEntryInterface
    {
        // @TODO implement your code here to return a instance of MyEntry
    }
}
```

And then provide the factory as the second argument to the `LogParser` constructor:

```
$factory = new MyEntryFactory();
$parser = new \Kassner\LogParser\LogParser(null, $factory);
$entry = $parser->parse('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');
```

`$entry` will be an instance of `MyEntry`.

###  Health Score

52

—

FairBetter than 96% of packages

Maintenance37

Infrequent updates — may be unmaintained

Popularity56

Moderate usage in the ecosystem

Community34

Small or concentrated contributor base

Maturity71

Established project with proven stability

 Bus Factor1

Top contributor holds 86.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~275 days

Recently: every ~506 days

Total

14

Last Release

636d ago

Major Versions

1.5.0 → 2.0.02020-01-05

PHP version history (3 changes)1.0.0PHP &gt;=5.3.4

2.0.0PHP &gt;=7.2.0

2.1.1PHP &gt;=7.4.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/d071b7495c9770a37796831ab34834c720db15ef1a1c6b9a881caeb961b87338?d=identicon)[kassner](/maintainers/kassner)

---

Top Contributors

[![kassner](https://avatars.githubusercontent.com/u/301255?v=4)](https://github.com/kassner "kassner (137 commits)")[![MrSecure](https://avatars.githubusercontent.com/u/1155636?v=4)](https://github.com/MrSecure "MrSecure (7 commits)")[![kbsali](https://avatars.githubusercontent.com/u/53676?v=4)](https://github.com/kbsali "kbsali (3 commits)")[![Sophist-UK](https://avatars.githubusercontent.com/u/3001893?v=4)](https://github.com/Sophist-UK "Sophist-UK (2 commits)")[![tarjei](https://avatars.githubusercontent.com/u/211263?v=4)](https://github.com/tarjei "tarjei (2 commits)")[![jpwhite4](https://avatars.githubusercontent.com/u/5342179?v=4)](https://github.com/jpwhite4 "jpwhite4 (1 commits)")[![onnimonni](https://avatars.githubusercontent.com/u/5691777?v=4)](https://github.com/onnimonni "onnimonni (1 commits)")[![aaronweeden](https://avatars.githubusercontent.com/u/31246768?v=4)](https://github.com/aaronweeden "aaronweeden (1 commits)")[![Timandes](https://avatars.githubusercontent.com/u/305486?v=4)](https://github.com/Timandes "Timandes (1 commits)")[![drzippie](https://avatars.githubusercontent.com/u/239421?v=4)](https://github.com/drzippie "drzippie (1 commits)")[![fiasco](https://avatars.githubusercontent.com/u/108160?v=4)](https://github.com/fiasco "fiasco (1 commits)")[![Gemorroj](https://avatars.githubusercontent.com/u/885731?v=4)](https://github.com/Gemorroj "Gemorroj (1 commits)")[![jonasraoni](https://avatars.githubusercontent.com/u/361921?v=4)](https://github.com/jonasraoni "jonasraoni (1 commits)")

---

Tags

log-parserphplogparserformatnginxapachelog-format

### Embed Badge

![Health badge](/badges/kassner-log-parser/health.svg)

```
[![Health](https://phpackages.com/badges/kassner-log-parser/health.svg)](https://phpackages.com/packages/kassner-log-parser)
```

###  Alternatives

[monolog/monolog

Sends your logs to files, sockets, inboxes, databases and various web services

21.4k964.9M7.0k](/packages/monolog-monolog)[psr/log

Common interface for logging libraries

10.4k1.2B9.2k](/packages/psr-log)[symfony/monolog-bundle

Symfony MonologBundle

2.9k249.1M1.6k](/packages/symfony-monolog-bundle)[spatie/laravel-activitylog

A very simple activity logger to monitor the users of your website or application

5.8k45.4M309](/packages/spatie-laravel-activitylog)[sentry/sentry

PHP SDK for Sentry (http://sentry.io)

1.9k227.1M273](/packages/sentry-sentry)[sentry/sentry-laravel

Laravel SDK for Sentry (https://sentry.io)

1.3k114.3M154](/packages/sentry-sentry-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
