Comment utiliser la fonctionnalité Context de Laravel pour partager des informations entre requêtes, jobs et commandes, et les injecter automatiquement dans les logs.
Context est le mécanisme de Laravel pour enregistrer et partager des informations entre les requêtes, les jobs de file d’attente et les commandes.
Les informations ajoutées via la façade Illuminate\Support\Facades\Context sont automatiquement ajoutées à chaque entrée de log écrite par l’application.Cela permet de distinguer clairement les informations passées à un appel de log spécifique et celles partagées via Context.
Particulièrement utile pour le tracing dans les systèmes distribués ou basés sur des files d’attente.
Exemple : enregistrer l’historique des requêtes SQL dans une pile.
use Illuminate\Support\Facades\Context;use Illuminate\Support\Facades\DB;// Dans la méthode boot de AppServiceProvider.phpDB::listen(function ($event) { Context::push('queries', [$event->time, $event->sql]);});
scope modifie temporairement le contexte pour la durée d’une closure, puis restaure l’état initial.
Pratique pour joindre des informations locales à vos logs.
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],);// Après le scope, l'état d'origine est restauréContext::all();// ['trace_id' => 'abc-999']Context::allHidden();// ['user_id' => 123]
Si vous modifiez un objet dans le scope, la modification persiste au-delà du scope. Ce n’est pas un problème pour les valeurs primitives.
Les données à ne pas exposer dans les logs (mots de passe, clés d’API, données personnelles) doivent être placées dans le Hidden Context.
get normal ne les retourne pas ; utilisez les méthodes dédiées getHidden.
use Illuminate\Support\Facades\Context;Context::addHidden('key', 'value');Context::getHidden('key');// 'value'Context::get('key');// null — invisible via get normal
Le Hidden Context propose les mêmes méthodes que le contexte standard.
Quand un job est dispatché, le contexte est automatiquement sérialisé dans le payload.
Il est restauré à l’exécution du job, ce qui permet au trace_id défini pendant la requête d’être présent dans les logs de la queue.
// Définition dans le middlewareContext::add('trace_id', Str::uuid()->toString());// Dispatch dans le contrôleurProcessPodcast::dispatch($podcast);
class ProcessPodcast implements ShouldQueue{ use Queueable; public function handle(): void { Log::info('Processing podcast.', ['podcast_id' => $this->podcast->id]); }}
Context::dehydrating permet de modifier le contexte juste avant l’envoi du job.
Par exemple, pour transmettre la locale déterminée par l’en-tête Accept-Language.
Dans un callback dehydrating, n’utilisez pas la façade Context. Manipulez uniquement le $context passé en argument.
L’utilisation de la façade modifierait le contexte du processus courant.
Hydrated — Restauration lors de l’exécution du job
Context::hydrated s’exécute juste avant que le job ne démarre, une fois le contexte restauré.
Par exemple, pour réappliquer la locale stockée dans la configuration.
// 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')); } });}
Dans un callback hydrated aussi, n’utilisez pas la façade Context : manipulez uniquement le $context fourni.