redis, logstash, elasticsearch, kibana를 이용해서 실시간 로그 모니터링 하기

Submitted by river - 등록 5 years ago - 수정 3 years ago

웹서비스를 운영하다 보면 장애 탐지나 버그 수정 등 많은 경우 로그 정보에 의존해서 문제를 해결하게 된다.

redis, logstash, elasticsearch, kibana의 조합을 사용하면 Laravel에서 남기는 로그의 내용을 실시간으로 모니터링 가능하고, 키워드 검색, 날짜별 검색등 다양한 기능을 사용할 수 있다.

Laravel 4.*

Laravel에서는 로깅용 패키지로 Monolog를 사용하는 데, 이 패키지에는 logstash 포맷 출력을 지원한다. 그래서 Laravel 어플 측에서는 Monolog에게 로깅시 logstash 포맷으로 redis에 저장하도록 App::before에 설정을 하면 된다.

app\filters.php

App::before(function ($request) {
    $monolog = Log::getMonolog();
    $redis = new \Monolog\Handler\RedisHandler(Redis::connection(), 'logstash', \Monolog\Logger::INFO);
    $formatter = new \Monolog\Formatter\LogstashFormatter('example.com');
    $redis->setFormatter($formatter);
    $monolog->pushHandler($redis);
});

Laravel 5.*

app/Http/Middleware/AttachLogstash.php

<?php namespace App\Http\Middleware;

use App;
use Closure;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Monolog\Handler\RedisHandler;
use Monolog\Logger;

class AttachLogstash
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (App::environment() !== 'testing') {
            $monolog = Log::getMonolog();
            $redis = new RedisHandler(
                Redis::connection(),
                config('logstash'),
                Logger::INFO
            );
            $formatter = new \Monolog\Formatter\LogstashFormatter('example.com');
            $redis->setFormatter($formatter);
            $monolog->pushHandler($redis);
        }

        return $next($request);
    }
}

app/Http/Kernel.php

protected $middleware = [
    \App\Http\Middleware\AttachLogstash::class,
     ...

Lumen

composer.json

"require": {
    ...
    "predis/predis": "^1.0",
    "illuminate/redis": "~5.1"
},

app/Http/Middleware/AttachLogstash.php

<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Redis;
use Monolog\Handler\RedisHandler;
use Monolog\Logger;

class AttachLogstash
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        dd(config('env.log.app_name'));
        if (app()->environment() !== 'testing') {
            $monolog = app('Psr\Log\LoggerInterface');
            $redis = new RedisHandler(
                Redis::connection(),
                'logstash',
                Logger::INFO
            );
            $formatter = new \Monolog\Formatter\LogstashFormatter('example.com');
            $redis->setFormatter($formatter);
            $monolog->pushHandler($redis);
        }

        return $next($request);
    }
}

bootstrap\app.php

$app->middleware([
    App\Http\Middleware\AttachLogstash::class
    ]);

redis에 저장되 로그는 logstash가 이를 elasticsearch에 넘겨주게 되고, kibana는 elasticsearch를 검색해서 웹페이지로 실시간 로깅 정보를 보여준다.

관련글

comments powered by Disqus