PHPackages                             jonshawpzbp/monolog-loki - 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. jonshawpzbp/monolog-loki

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

jonshawpzbp/monolog-loki
========================

Monolog handler for Grafana Loki (with log level detection fix)

2.3.0(1y ago)018BSD-3-ClausePHPPHP ~8.1

Since Jun 15Pushed 1y agoCompare

[ Source](https://github.com/JonShawPZBP/monolog-loki)[ Packagist](https://packagist.org/packages/jonshawpzbp/monolog-loki)[ RSS](/packages/jonshawpzbp-monolog-loki/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (4)Versions (16)Used By (0)

Itspire - Monolog Loki
======================

[](#itspire---monolog-loki)

This library follows the PSR-12 convention.

Usage
=====

[](#usage)

Recommended Usage
-----------------

[](#recommended-usage)

Since Loki log handling uses a remote server, logging is prone to be subject of timeout, network shortage and so on. To avoid your application being broken in such a case, we recommend wrapping the handler in a WhatFailureGroupHandler

Native
------

[](#native)

```
use Itspire\MonologLoki\Handler\LokiHandler;
use Monolog\Handler\WhatFailureGroupHandler;

$handler = new WhatFailureGroupHandler(
    [
        new LokiHandler(
            [
                'entrypoint' => 'https://loki:3100',
                'context' => [
                    // Set here your globally applicable context variables
                ],
                'labels' => [
                    // Set here your globally applicable labels
                ],
                'client_name' => 'your_host_name', // Here set a unique identifier for the client host
                // Optional: Sets tenant id (HTTP header X-Scope-OrgID), if null or missing -> no header
                'tenant_id' => 'some-tenant',
                // Optional : if you're using basic auth to authentify
                'auth' => [
                    'basic' => ['user', 'password'],
                ],
                // Optional : Override the default curl options with custom values
                'curl_options' => [
                    CURLOPT_CONNECTTIMEOUT_MS => 500,
                    CURLOPT_TIMEOUT_MS => 600
                ]
            ]
        )
    ]
);
```

### Non-customizable curl options

[](#non-customizable-curl-options)

The following options are not customizable in the configuration:

- `CURLOPT_CUSTOMREQUEST`
- `CURLOPT_RETURNTRANSFER`
- `CURLOPT_POSTFIELDS`
- `CURLOPT_HTTPHEADER`

Symfony App
-----------

[](#symfony-app)

### Configure LokiHandler Service

[](#configure-lokihandler-service)

```
  Itspire\MonologLoki\Handler\LokiHandler:
    arguments:
      $apiConfig:
        entrypoint: 'http://loki:3100'
        context:
          app: My-app
        labels:
          env: '%env(APP_ENV)%'
        client_name: my_app_server
        auth:
          basic:
            user: username
            password: password
        curl_options:
          !php/const CURLOPT_CONNECTTIMEOUT_MS: 500,
          !php/const CURLOPT_TIMEOUT_MS: 600
```

Note : We're currently working on a possible bundle based implementation for Symfony but at the moment, this is the way.

### Configure Monolog to use Loki Handler

[](#configure-monolog-to-use-loki-handler)

```
monolog:
  handlers:
    loki:
      type: service
      id: Itspire\MonologLoki\Handler\LokiHandler

    my_loki_handler:
      type:   whatfailuregroup
      members: [loki]
      level: debug
      process_psr_3_messages: true # optional but we find it rather useful (Note : native handler required to use)
```

Laravel App
-----------

[](#laravel-app)

### Add Loki to config/logging.php

[](#add-loki-to-configloggingphp)

```
'loki' => [
    'driver'         => 'monolog',
    'level'          => env('LOG_LEVEL', 'debug'),
    'handler'        => \Itspire\MonologLoki\Handler\LokiHandler::class,
    'formatter'      => \Itspire\MonologLoki\Formatter\LokiFormatter::class,
    'formatter_with' => [
        'labels' => [],
        'context' => [],
        'systemName' => env('LOKI_SYSTEM_NAME', null),
        'extraPrefix' => env('LOKI_EXTRA_PREFIX', ''),
        'contextPrefix' => env('LOKI_CONTEXT_PREFIX', '')
    ],
    'handler_with'   => [
        'apiConfig'  => [
            'entrypoint'  => env('LOKI_ENTRYPOINT', "http://localhost:3100"),
            'context'     => [],
            'labels'      => [],
            'client_name' => '',
            'auth' => [
                'basic' => [
                    env('LOKI_AUTH_BASIC_USER', ''),
                    env('LOKI_AUTH_BASIC_PASSWORD', '')
                ],
            ],
        ],
    ],
],
```

### Set env vars

[](#set-env-vars)

```
LOKI_ENTRYPOINT="http://loki:3100"
LOKI_AUTH_BASIC_USER=
LOKI_AUTH_BASIC_PASSWORD=
LOKI_SYSTEM_NAME=null
LOKI_CONTEXT_PREFIX="context_"
LOKI_EXTRA_PREFIX=

```

These vars can be injected by Kubernetes, Docker or simply by setting them on the .env file

### Laravel with WhatFailureGroupHandler

[](#laravel-with-whatfailuregrouphandler)

Since Loki log handling uses a remote server, logging is prone to be subject of timeout, network shortage and so on. To avoid your application being broken in such a case, we recommend wrapping the handler in a WhatFailureGroupHandler.

Create a custom Log handler and wrap the `LokiHandler` with a `WhatFailureGroupHandler`.

```
namespace App\Logging;

use Itspire\MonologLoki\Formatter\LokiFormatter;
use Itspire\MonologLoki\Handler\LokiHandler;
use Monolog\Handler\WhatFailureGroupHandler;
use Monolog\Logger;

class LokiNoFailureHandler
{
    public function __invoke(array $config)
    {
        return new Logger('loki-no-failure', [
            new WhatFailureGroupHandler([
                (new LokiHandler($config['handler_with']['apiConfig'], $config['level']))
                    ->setFormatter(new LokiFormatter(...array_values($config['formatter_with'])))
            ])
        ]);
    }
}
```

Update the config accordingly:

```
parse_str(env('LOKI_LABELS', ''), $loki_formatter_labels);

'loki' => [
    'driver'    => 'custom',
    'level'     => env('LOG_LEVEL', 'debug'),
    'via'       => \App\Logging\LokiNoFailureHandler::class,
    'formatter_with' => [
        // LOKI_LABELS: app=laravel&env=prod
        'labels' => $loki_formatter_labels,
        'context' => [],
        'systemName' => env('LOKI_SYSTEM_NAME', ''),
        'extraPrefix' => env('LOKI_EXTRA_PREFIX', ''),
        'contextPrefix' => env('LOKI_CONTEXT_PREFIX', '')
    ],
    'handler_with'   => [
        'apiConfig'  => [
            'entrypoint'  => env('LOKI_ENTRYPOINT', "http://localhost:3100"),
            'context'     => [],
            'labels'      => [],
            'client_name' => '',
            'auth' => [
                'basic' => [
                    env('LOKI_AUTH_BASIC_USER', ''),
                    env('LOKI_AUTH_BASIC_PASSWORD', '')
                ],
            ]
        ],
    ],
],
```

Testing
=======

[](#testing)

In order to test using the provided docker-compose file, you'll need an up-to-date docker/docker-compose installation You can start the Loki container by navigating to src/main/test/docker and running

```
docker-compose up -d
```

If you're testing from a local php installation, you'll need to retrieve the Loki container ip with :

```
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' itspire-monolog-loki_loki_1
```

and replace the ip in the LOKI\_ENTRYPOINT definition in phpunit.xml :

```

```

If you're testing from containerized php not in the default docker bridge network, you'll need to start the container with an extra host named Loki mapped to your current host ip, using the following option :

```
--add-host loki:{the_ip_of_your_host_in_your_network}
```

Run the test using phpunit and you can verify that posting to Loki works by running the following from your host terminal :

```
curl -G -s  "http://localhost:7000/loki/api/v1/query" --data-urlencode 'query={channel="test"}' | jq
```

For each time you ran the tests, you should see a log entry looking like the following :

```
{
    "stream": {
        "channel": "test",
        "host": "f2bbe48b0204",
        "level_name": "WARNING"
    },
    "values": [
        [
        "1591627127000000000",
        "{\"message\":\"test\",\"level\":300,\"level_name\":\"WARNING\",\"channel\":\"test\",\"datetime\":\"2020-06-08 14:38:47\",\"ctxt_data\":\"{\\\"stdClass\\\":[]}\",\"ctxt_foo\":\"34\"}"
        ]
    ]
}
```

###  Health Score

35

—

LowBetter than 80% of packages

Maintenance39

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity72

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

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 ~116 days

Recently: every ~93 days

Total

15

Last Release

523d ago

Major Versions

1.3.0 → 2.0.02022-05-29

PHP version history (3 changes)1.0.0PHP ~7.4

1.1.0PHP &gt;=7.4

2.0.0PHP ~8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/0bed66ebf1cccb6fc78be2dea6406f2d6c8decef88800df02acebede46d70d09?d=identicon)[jonshawpzbp](/maintainers/jonshawpzbp)

---

Top Contributors

[![rrajkomar](https://avatars.githubusercontent.com/u/2751269?v=4)](https://github.com/rrajkomar "rrajkomar (28 commits)")[![cstuder](https://avatars.githubusercontent.com/u/288493?v=4)](https://github.com/cstuder "cstuder (9 commits)")[![achetronic](https://avatars.githubusercontent.com/u/61636487?v=4)](https://github.com/achetronic "achetronic (8 commits)")[![korridor](https://avatars.githubusercontent.com/u/26689068?v=4)](https://github.com/korridor "korridor (3 commits)")[![JonShawPZBP](https://avatars.githubusercontent.com/u/62744696?v=4)](https://github.com/JonShawPZBP "JonShawPZBP (3 commits)")[![Qonstrukt](https://avatars.githubusercontent.com/u/1132953?v=4)](https://github.com/Qonstrukt "Qonstrukt (2 commits)")[![bassim](https://avatars.githubusercontent.com/u/748403?v=4)](https://github.com/bassim "bassim (2 commits)")[![barryvdh](https://avatars.githubusercontent.com/u/973269?v=4)](https://github.com/barryvdh "barryvdh (2 commits)")[![victor-keltio](https://avatars.githubusercontent.com/u/100953003?v=4)](https://github.com/victor-keltio "victor-keltio (2 commits)")[![KevinBeckers](https://avatars.githubusercontent.com/u/4037137?v=4)](https://github.com/KevinBeckers "KevinBeckers (2 commits)")[![publiux](https://avatars.githubusercontent.com/u/2847188?v=4)](https://github.com/publiux "publiux (1 commits)")[![zawwz](https://avatars.githubusercontent.com/u/34189424?v=4)](https://github.com/zawwz "zawwz (1 commits)")

###  Code Quality

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/jonshawpzbp-monolog-loki/health.svg)

```
[![Health](https://phpackages.com/badges/jonshawpzbp-monolog-loki/health.svg)](https://phpackages.com/packages/jonshawpzbp-monolog-loki)
```

###  Alternatives

[symfony/monolog-bridge

Provides integration for Monolog with various Symfony components

2.6k189.7M258](/packages/symfony-monolog-bridge)[rollbar/rollbar

Monitors errors and exceptions and reports them to Rollbar

33723.7M82](/packages/rollbar-rollbar)[illuminate/log

The Illuminate Log package.

6224.3M518](/packages/illuminate-log)[honeybadger-io/honeybadger-php

Honeybadger PHP library

381.5M4](/packages/honeybadger-io-honeybadger-php)[graycore/magento2-stdlogging

A Magento 2 module that changes all logging handlers to stdout

2382.6k](/packages/graycore-magento2-stdlogging)

PHPackages © 2026

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