Laravel Request Logger est un paquet Composer compatible avec Laravel, permettant de logger en base de données toutes les requêtes HTTP entrantes.
Le projet a débuté assez simplement lors du développement de mon ancien site internet. Je souhaitais implémenter un système de statistiques, mais pour cela, je devais être en mesure d’enregistrer le nombre de visites sur chaque page. C’est alors que m’est venue l’idée d’enregistrer toutes les requêtes HTTP entrantes. Cela m’a permis de déceler les divers bots et crawlers qui cherchaient des failles dans mon site, ce qui est assez pratique pour créer des honey pots.
L’idée d’en créer un paquet Composer m’est venue lorsque j’ai commencé à travailler sur d’autres projets Laravel. Plutôt que de recopier les fichiers pour chaque projet, j’ai décidé d’apprendre à créer un paquet avec la lib Orchestra.
Le paquet utilise une architecture en deux temps pour garantir des performances optimales :
terminate()
(après l’envoi de la réponse) et les stocke temporairement en cache Redis/MemcachedSaveRequestsJob
) traite les requêtes en lot toutes les minutes via le scheduler, réduisant les appels à la base de donnéesCette approche garantit un impact zéro sur les temps de réponse de votre application, car l’enregistrement se fait après l’envoi de la réponse au client.
Pour éviter la duplication des données et optimiser l’espace de stockage, le paquet utilise 5 tables normalisées :
logged_requests
: Table principale contenant les métadonnées de chaque requête
ip_addresses
: Stockage dédupliqué des adresses IP avec détection du pays d’origine
user_agents
: Stockage dédupliqué des chaînes User-Agent
urls
: Stockage dédupliqué des chemins d’URL
mime_types
: Stockage dédupliqué des types MIME
Chaque entité utilise un système de cache d’ID via la méthode getIdOrCreate()
pour minimiser les requêtes SELECT et optimiser les performances d’insertion.
Filtrage intelligent :
Traitement personnalisable :
SaveRequestsJob
pour ajouter des analyses spécifiquesRequestsProcessed
pour déclencher des actions personnaliséesAu-delà des statistiques de visite classiques, le paquet permet de nombreux cas d’usage avancés :
Détection d’intrusions :
Honeypots :
Analyse comportementale :
Monitoring API :
Conformité RGPD :
Debugging production :
Le paquet a été conçu pour fonctionner efficacement même sous forte charge :
composer require sl-projects/laravel-request-logger
php artisan migrate
php artisan vendor:publish --tag=request-logger-config
Dans bootstrap/app.php
:
use SlProjects\LaravelRequestLogger\app\Http\Middleware\SaveRequestMiddleware;
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(function (Middleware $middleware) {
// Enregistrement global (toutes les requêtes)
$middleware->append(SaveRequestMiddleware::class);
// OU pour des routes spécifiques
$middleware->alias([
'log.request' => SaveRequestMiddleware::class,
]);
})
->create();
Dans routes/console.php
:
use Illuminate\Support\Facades\Schedule;
Schedule::command('save:requests')->everyMinute();
use SlProjects\LaravelRequestLogger\app\Models\LoggedRequest;
// Récupérer toutes les requêtes d'une IP spécifique
$requests = LoggedRequest::with(['ipAddress', 'url', 'userAgent'])
->whereHas('ipAddress', function ($query) {
$query->where('ip', '192.168.1.1');
})
->get();
// Analyser les erreurs 4xx
$clientErrors = LoggedRequest::whereBetween('status_code', [400, 499])
->with('url')
->get();
// Top 10 des User-Agents
$topAgents = LoggedRequest::with('userAgent')
->select('user_agent_id', DB::raw('count(*) as total'))
->groupBy('user_agent_id')
->orderByDesc('total')
->limit(10)
->get();
// Détecter les tentatives de brute force
$suspiciousActivity = LoggedRequest::with(['ipAddress', 'url'])
->where('status_code', 401)
->whereHas('url', function ($query) {
$query->where('url', 'like', '%/login%');
})
->select('ip_address_id', DB::raw('count(*) as attempts'))
->groupBy('ip_address_id')
->having('attempts', '>', 5)
->get();
// Analyser les performances par endpoint
$performanceStats = LoggedRequest::with('url')
->select(
'url_id',
DB::raw('AVG(response_time) as avg_time'),
DB::raw('MAX(response_time) as max_time'),
DB::raw('MIN(response_time) as min_time'),
DB::raw('COUNT(*) as total_requests')
)
->groupBy('url_id')
->orderByDesc('avg_time')
->get();
Ce projet représente mon premier paquet Composer open-source, développé dans une démarche d’apprentissage et de contribution à la communauté Laravel. Toute contribution est la bienvenue !
git checkout -b feature/amazing-feature
)git commit -m 'Add amazing feature'
)git push origin feature/amazing-feature
)# Lancer les tests
composer test
# Analyse statique
vendor/bin/phpstan analyse
# Serveur de développement
composer serve
Pour toute question, suggestion ou rapport de bug, n’hésitez pas à ouvrir une issue sur GitHub.