简体   繁体   中英

How to use monolog ElasticSearchHandler for logging in a Laravel application

Monolog contains elastic search handler and formatter, but it's implementation to laravel as a custom channel is not as straightforward as described on Laravel documentation web site.

Here's a brief step by step instruction how to do that.

  1. Create a config file for your elastic search logging.
config/elastic_log.php

with the next content:

<?php

return [
    'host' => env('ELASTIC_HOST'),
    'index' => 'index_name',
    'prefix' => 'index_prefix',
    'type' => '_doc',
];

You can change your index name and prefix to any string values.

  1. In your.env file put your elastic host address:
ELASTIC_HOST=your_elastic_host:port
  1. Install elasticsearch/elasticsearch official package
composer require elasticsearch/elasticsearch
  1. Create ElasticLogging service provider
php artisan make:provider ElasticLogProvider

With the following content:

<?php

namespace App\Providers;

use Elasticsearch\Client;
use Elasticsearch\ClientBuilder;
use Illuminate\Support\ServiceProvider;
use Monolog\Formatter\ElasticsearchFormatter;
use Monolog\Handler\ElasticsearchHandler;

class ElasticLogProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        $index = rtrim(config('elastic_log.prefix'), '_') . '_' . config('elastic_log.index');
        $type = config('elastic_log.type');
        
        $this->app->bind(Client::class, function ($app) {
            return ClientBuilder::create()->setHosts([config('elastic_log.host')])->build();
        });

        $this->app->bind(ElasticsearchFormatter::class, function ($app) use ($index, $type) {
            return new ElasticsearchFormatter($index, $type);
        });

        $this->app->bind(ElasticsearchHandler::class, function ($app) use ($index, $type) {
            return new ElasticsearchHandler($app->make(Client::class), [
                'index'        => $index,
                'type'         => $type,
                'ignore_error' => false,
            ]);
        });
    }
}

Add this provider to your app.php config file to the providers array:

App\Providers\ElasticLogProvider::class,
  1. Create a command for elastic logging settings on the server. This command creates an index on the server if it doesn't exist yet. Now for the preparation of your server, just run elastic:log_setup;
php artisan make:command ElasticLogSetup

With the following content:

<?php

namespace App\Console\Commands;

use Elasticsearch\Client;
use Illuminate\Console\Command;

class ElasticLogSetup extends Command
{
    /**
     * @var Client
     */
    protected $client;

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'elastic:log_setup';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Setup elastic log index';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct(Client $client)
    {
        $this->client = $client;
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $index = rtrim(config('elastic_log.prefix'), '_') . '_' . config('elastic_log.index');

        if (!$this->client->indices()->exists(['index' => $index])) {
            $this->client->indices()->create([
                'index' => $index,
            ]);
        }
    }
}

  1. In the file config/logging.php add this element to 'channels' array and import the related classes:
use Monolog\Formatter\ElasticsearchFormatter;
use Monolog\Handler\ElasticsearchHandler;

'elastic' => [
    'driver' => 'monolog',
    'handler' => ElasticsearchHandler::class,
    'level' => 'debug',
    'formatter' => ElasticsearchFormatter::class,
];
  1. Now you can use the channel 'elastic' or change it in your.env settings as a default channel:
LOG_CHANNEL=elastic

From now on, you can use standard laravel Log facade to send the information to your ElasticSearch server

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM