目前,我正在嘗試將遙測庫(OpenTelemetry php lib)連接到 Laravel 事件模型。這個想法是將跟蹤轉發給第三方服務。請求的單個跟蹤一致以及在請求期間進行的所有資料庫呼叫。我創建了三個中間件組件:
- BeforeRequest:開始跟蹤
- OnRequest:呼叫監聽資料庫查詢的事件監聽器(見下面的片段)并結束跟蹤,以便將其發送到第三方服務
我的 OnRequest 中間件組件如下所示:
<?php
namespace App\Http\Middleware;
use App\Helpers\Otel\TraceProviderFactory;
use Closure;
use Illuminate\Database\Events\QueryExecuted;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class OnRequest
{
public function handle(Request $request, Closure $next)
{
$provider = TraceProviderFactory::getTraceProvider($request->get('context_uuid'));
DB::listen(function (QueryExecuted $query) use ($provider){
$provider->startDbSpan($query);
});
$provider->endSpans();
return $next($request);
}
}
在這種情況下,DB 監聽呼叫被跳過,因為它是異步的。如何確保每個資料庫查詢都已注冊?執行順序很重要。一切都需要按正確的順序排列,否則無法正確記錄跟蹤。
uj5u.com熱心網友回復:
我將在可終止的中間件中完成此操作(在將回應發送到客戶端之后),以允許您記錄從開始偵聽到發送回應的所有查詢。這也不會阻止將回應回傳給客戶端。
...
class OnRequest
{
protected $provider;
public function handle(Request $request, Closure $next)
{
$this->provider = TraceProviderFactory::getTraceProvider($request->input('context_uuid'));
DB::listen(function (QueryExecuted $query) {
$this->provider->startDbSpan($query);
});
return $next($request);
}
public function terminate($request, $response)
{
$this->provider->endSpans();
}
}
您應該將此中間件設為單例,這樣它就不會為可終止部分使用新實體。(我們希望$provider分配相同的實體)。在服務提供者中注冊單例:
public function register()
{
$this->app->singleton(OnRequest::class);
}
您只需要一個中間件即可完成所有作業。
Laravel 8.x 檔案 - 中間件 - 可終止的中間件
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/411078.html
標籤:
