GithubHelp home page GithubHelp logo

monolog-loki's Introduction

Itspire - Monolog Loki

This library follows the PSR-12 convention.

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

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

The following options are not customizable in the configuration:

  • CURLOPT_CUSTOMREQUEST
  • CURLOPT_RETURNTRANSFER
  • CURLOPT_POSTFIELDS
  • CURLOPT_HTTPHEADER

Symfony App

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

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

Add Loki to config/logging.php

'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

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

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:

'loki' => [
    'driver'    => 'custom',
    'level'     => env('LOG_LEVEL', 'debug'),
    'via'       => \App\Logging\LokiNoFailureHandler::class,
    'formatter_with' => [
        'labels' => env('LOKI_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

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 :

<env name="LOKI_ENTRYPOINT" value="http://172.17.0.1:7000/" />

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\"}"
        ]
    ]
}

monolog-loki's People

Contributors

achetronic avatar barryvdh avatar bassim avatar cstuder avatar kevinbeckers avatar korridor avatar publiux avatar qonstrukt avatar rrajkomar avatar zawwz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

monolog-loki's Issues

Handling unreachable Loki server

Hi, thank you for this lib!

I need some guidance regards handeling an unreachable Loki server.
We are using this library with Laravel which works great, it is used as the last of a few handlers.
If for some reason the Loki server is not available, a RuntimeException is thrown. This results in exception down the line which is understandable but not convenient.

What would be the best way of handeling this? Perhaps it would be useful to create a Loki exception and replace the RuntimeException, which I could add to the Laravel ignore properties?

Compatibility with monolog v2.X?

I see the current requirement for monolog-loki is locked to monolog ~1.25, should it be compatible with monolog v2.0?
I do not know about monolog internals or migration needed but this might be related: Seldaek/monolog#903
Thanks!

CURLOPT_RETURNTRANSFER is set to `false`

I'm trying out Loki and am using your library to log to it. When experimenting with an incorrect Loki URL, monolog-loki appended the 404 error message to the server output instead of swallowing it. I traced this back to this line:

curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);

I suggest setting CURLOPT_RETURNTRANSFER to true.

Is there a particular reason this is set to false?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.