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

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

graftak/monolog-loki
====================

Monolog handler for Grafana Loki (BC fork!)

1.4.0(9mo ago)08BSD-3-ClausePHPPHP &gt;=7.4

Since Jun 15Pushed 9mo agoCompare

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

READMEChangelogDependencies (7)Versions (11)Used By (0)

Itspire - Monolog Loki (BC FORK!!)
==================================

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

**! ! ! PLEASE NOTE ! ! !**

*This is a **fork** from [itspire/monolog-loki](https://github.com/itspire/monolog-loki) for older projects still using PHP &gt;=7.4 and Monolog 2, but with the bugfixes/improvements since version 2.0.0 applied to it. Please use  or use this with care!*

---

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)

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

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

If you're testing from containerized php, 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:{your_host_ip}
```

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:3100/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\":\"[object] (stdClass: {})\",\"ctxt_foo\":\"34\"}"
        ]
    ]
}
```

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance58

Moderate activity, may be stable

Popularity4

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity61

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

Recently: every ~431 days

Total

10

Last Release

280d ago

PHP version history (2 changes)1.0.0PHP ~7.4

1.1.0PHP &gt;=7.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/68bd67c5485f7a1066394ea1420a5bb1f9b015d7927bd6ec67936448d0c4beec?d=identicon)[graftak](/maintainers/graftak)

---

Top Contributors

[![rrajkomar](https://avatars.githubusercontent.com/u/2751269?v=4)](https://github.com/rrajkomar "rrajkomar (22 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)")[![graftak](https://avatars.githubusercontent.com/u/30551282?v=4)](https://github.com/graftak "graftak (2 commits)")[![KevinBeckers](https://avatars.githubusercontent.com/u/4037137?v=4)](https://github.com/KevinBeckers "KevinBeckers (2 commits)")[![Qonstrukt](https://avatars.githubusercontent.com/u/1132953?v=4)](https://github.com/Qonstrukt "Qonstrukt (2 commits)")[![barryvdh](https://avatars.githubusercontent.com/u/973269?v=4)](https://github.com/barryvdh "barryvdh (2 commits)")[![publiux](https://avatars.githubusercontent.com/u/2847188?v=4)](https://github.com/publiux "publiux (1 commits)")

###  Code Quality

Code StylePHP\_CodeSniffer

### Embed Badge

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

```
[![Health](https://phpackages.com/badges/graftak-monolog-loki/health.svg)](https://phpackages.com/packages/graftak-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)
