PHP

Laravel Datadogのトレース用ロガー作成 APM

Laravel
Laravel上で

$ composer require datadog/dd-trace

 

datadog-php-tracerの導入

# wget https://github.com/DataDog/dd-trace-php/releases/download/0.64.1/datadog-php-tracer_0.64.1_amd64.deb
# dpkg -i datadog-php-tracer_0.64.1_amd64.deb

 

まず前提としてログはJSON化しておく

Laravel ログをJSON化させる

 

 

 

app/Http/Middleware/RequestLogger.php

<?php

namespace App\Http\Middleware;

use Closure;

class RequestLogger
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (env('IS_REQUEST_LOG_ENABLE', false)) {
            $this->_writeRequestLog($request);
        }
        return $next($request);
    }

    private function _writeRequestLog($request): void
    {
        \Log::channel('request')->debug(
            $request->method()
                . " : "
                . json_encode(
                    [
                        'url' => $request->fullUrl(),
                        'request' => $request->all(),
                        'header' => $request->headers->all(), '',
                        'message' => $this->_generateMessageForDatadog(),
                    ],
                    JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
                )
        );
    }

    /**
     * Datadog送信用messageを返却
     *
     * @return string
     */
    private function _generateMessageForDatadog(): string
    {
        $span = \DDTrace\GlobalTracer::get()->getActiveSpan();
        return sprintf(
            ' [dd.trace_id=%d dd.span_id=%d]',
            $span->getTraceId() ?? "",
            \dd_trace_peek_span_id() ?? ""
        );
    }
}

 

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use DDTrace\GlobalTracer;

class DatadogSetTag
{
    /**
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);

        $span = GlobalTracer::get()->getActiveSpan();
        if (is_null($span)) {
            return $response;
        }
        if (isset($request->company_id) && !empty($request->company_id)) {
            $span->setTag('company_id', $request->company_id ?? 0);
        }
        return $response;
    }
}

 

app/Http/kernel.php

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
・・・
        \App\Http\Middleware\Datadog::class,
    ];

app/logging/DatadogMessageApply.php

<?php

namespace App\Logging;

class DatadogMessageApply
{
    /**
     * 渡されたロガーインスタンスのカスタマイズ
     *
     * @param  \Illuminate\Log\Logger  $logger
     * @return void
     */
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            $handler->pushProcessor(function ($record) {
                $span = \DDTrace\GlobalTracer::get()->getActiveSpan();
                if (is_null($span)) {
                    return $record;
                }
                $record['message'] .= sprintf(
                    ' [dd.trace_id=%d dd.span_id=%d]',
                    $span->getTraceId(),
                    \dd_trace_peek_span_id()
                );
                return $record;
            });
        }
    }
}

 

config/logging.php


    'channels' => [
        'stack' => [
            'driver' => 'stack',
            'channels' => ['bugsnag', 'daily'],
            'tap' => [
                App\Logging\DatadogMessageApply::class,
                App\Logging\JsonFormatterApply::class,
            ],
        ],
・・・
        'request' => [
            'name' => 'request',
            'driver' => 'daily',
            'path' => storage_path('logs/request.log'),
            'level' => 'debug',
            'days' => 10,
            'tap' => [
                App\Logging\JsonFormatterApply::class,
            ],

関連

Ansible Datadog Agent Ubuntu

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)