Erläutert, wie Sie mit der Context-Funktion von Laravel Informationen über Requests, Jobs und Commands hinweg teilen und automatisch in Logs einbetten.
Die Context-Funktion von Laravel ist ein Mechanismus, mit dem Sie Informationen über HTTP-Requests, Queue-Jobs und Commands hinweg speichern und teilen können.
Wenn Sie über die Facade Illuminate\Support\Facades\Context Informationen hinzufügen, werden diese automatisch an alle Log-Einträge angehängt, die Ihre Anwendung schreibt.Dadurch lassen sich Informationen aus einzelnen Log-Aufrufen sauber von den geteilten Kontextdaten unterscheiden.
Besonders nützlich ist das für Tracing in verteilten Systemen oder in Architekturen mit Queues.
use Illuminate\Support\Facades\Context;Context::add('key', 'value');// Mehrere Werte auf einmal hinzufügenContext::add([ 'first_key' => 'value', 'second_key' => 'value',]);
add überschreibt vorhandene Schlüssel. Möchten Sie nur hinzufügen, wenn der Schlüssel noch nicht existiert, verwenden Sie addIf.
Context::add('key', 'first');Context::addIf('key', 'second');Context::get('key');// "first" – wird nicht überschrieben
use Illuminate\Support\Facades\Context;use Illuminate\Support\Facades\DB;// In der boot-Methode des AppServiceProvider registrierenDB::listen(function ($event) { Context::push('queries', [$event->time, $event->sql]);});
Context::add(['first_key' => 1, 'second_key' => 2]);Context::forget('first_key');Context::all();// ['second_key' => 2]// Mehrere auf einmal löschenContext::forget(['first_key', 'second_key']);
Mit der Methode scope können Sie den Kontext nur während der Ausführung einer Closure vorübergehend ändern und den ursprünglichen Zustand danach automatisch wiederherstellen.
Praktisch, wenn Sie in Tests oder lokalen Verarbeitungsschritten temporäre Zusatzinformationen ins Log aufnehmen möchten.
use Illuminate\Support\Facades\Context;use Illuminate\Support\Facades\Log;Context::add('trace_id', 'abc-999');Context::addHidden('user_id', 123);Context::scope( function () { Context::add('action', 'adding_friend'); $userId = Context::getHidden('user_id'); Log::debug("Adding user [{$userId}] to friends list."); // Adding user [987] to friends list. {"trace_id":"abc-999","user_name":"taylor_otwell","action":"adding_friend"} }, data: ['user_name' => 'taylor_otwell'], hidden: ['user_id' => 987],);// Nach Verlassen des Scopes gelten wieder die ursprünglichen WerteContext::all();// ['trace_id' => 'abc-999']Context::allHidden();// ['user_id' => 123]
Ändern Sie innerhalb des Scopes ein Objekt, wirken sich diese Änderungen auch außerhalb des Scopes aus. Bei primitiven Werten ist das nicht der Fall.
Daten, die nicht in Logs auftauchen sollen (Passwörter, API-Schlüssel, personenbezogene Daten), speichern Sie im Hidden Context.
Sie können nicht mit der regulären get-Methode gelesen werden, sondern nur über dedizierte Methoden wie getHidden.
use Illuminate\Support\Facades\Context;Context::addHidden('key', 'value');Context::getHidden('key');// 'value'Context::get('key');// null – nicht per regulärem get abrufbar
Für den Hidden Context stehen dieselben Methoden wie für den regulären Kontext zur Verfügung.
Beim Dispatchen eines Jobs wird der aktuelle Kontext automatisch serialisiert und in den Job-Payload eingebettet.
Beim Ausführen des Jobs wird der ursprüngliche Kontext wiederhergestellt, sodass zum Beispiel die trace_id aus dem Request auch in Logs des Queue-Jobs erhalten bleibt.
// In der Middleware setzenContext::add('trace_id', Str::uuid()->toString());// Im Controller den Job dispatchenProcessPodcast::dispatch($podcast);
class ProcessPodcast implements ShouldQueue{ use Queueable; public function handle(): void { Log::info('Processing podcast.', ['podcast_id' => $this->podcast->id]); }}
Dehydrating – Anpassungen beim Verschicken des Jobs
Mit Context::dehydrating können Sie den Kontext unmittelbar vor dem Versand des Jobs anpassen.
Zum Beispiel, um die durch den Header Accept-Language bestimmte Locale an die Queue zu übertragen.
Verwenden Sie in der dehydrating-Callback nicht die Context-Facade, sondern ausschließlich das an die Callback übergebene $context-Repository.
Andernfalls verändern Sie den Kontext des aktuellen Prozesses.
Hydrated – Wiederherstellung beim Ausführen des Jobs
Mit Context::hydrated können Sie unmittelbar nach dem Wiederherstellen des Kontexts vor der Job-Ausführung eingreifen.
Zum Beispiel, um die zuvor gespeicherte Locale in die Konfiguration zu übernehmen.
// AppServiceProvider.phpuse Illuminate\Log\Context\Repository;use Illuminate\Support\Facades\Config;use Illuminate\Support\Facades\Context;public function boot(): void{ Context::hydrated(function (Repository $context) { if ($context->hasHidden('locale')) { Config::set('app.locale', $context->getHidden('locale')); } });}
Auch in der hydrated-Callback dürfen Sie die Context-Facade nicht verwenden; nutzen Sie ausschließlich das übergebene $context-Repository.