Logo of the project
Réalisé en
2025
Laravel Request Logger
Bibliothèque
Laravel Request Logger est un paquet composer compatible avec Laravel, permettant de logger en base de données toutes les requêtes HTTP entrantes.
Période
Décembre 2024 - Mai 2025

Description

Introduction

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.

Détails techniques

Architecture et optimisation des performances

Le paquet utilise une architecture en deux temps pour garantir des performances optimales :

  1. Capture asynchrone : Un middleware intercepte les requêtes dans la méthode terminate() (après l’envoi de la réponse) et les stocke temporairement en cache Redis/Memcached
  2. Traitement par batch : Un job Laravel (SaveRequestsJob) traite les requêtes en lot toutes les minutes via le scheduler, réduisant les appels à la base de données

Cette 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.

Structure de base de données normalisée

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

    • Méthode HTTP (GET, POST, PUT, DELETE, etc.)
    • Code de statut HTTP (200, 404, 500, etc.)
    • Temps de réponse en millisecondes
    • Timestamps de création
    • Clés étrangères vers les tables normalisées
  • 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.

Technologies et standards

  • PHP 8.2+ avec typage strict et propriétés promues pour un code moderne et maintenable
  • Laravel 11/12 compatible avec la nouvelle structure simplifiée introduite dans Laravel 11
  • Orchestra Testbench pour les tests unitaires avec base de données SQLite en mémoire
  • PHPStan niveau 8 pour l’analyse statique du code et la détection d’erreurs
  • Couverture de tests à 100% avec factories complètes pour tous les modèles
  • Cache locking pour éviter les conditions de course en environnement haute charge
  • PSR-4 pour l’autoloading et respect des standards PHP-FIG

Fonctionnalités avancées

Détection et enrichissement des données
  • Détection GeoIP : Identification automatique du pays d’origine des requêtes via l’adresse IP
  • Analyse des User-Agents : Possibilité d’identifier les navigateurs, systèmes d’exploitation et bots
  • Mesure des performances : Temps de réponse précis pour chaque requête
Configuration flexible
  • Filtrage intelligent :

    • Exclusion configurable de champs sensibles (mots de passe, tokens, cartes bancaires)
    • Exclusion d’URLs système (Telescope, Horizon, Debugbar)
    • Possibilité de définir des patterns d’exclusion personnalisés
  • Traitement personnalisable :

    • Extension de SaveRequestsJob pour ajouter des analyses spécifiques
    • Batch size configurable pour optimiser les performances selon votre infrastructure
    • TTL du cache ajustable selon vos besoins
Intégration Laravel native
  • Events Laravel : Dispatch d’événements RequestsProcessed pour déclencher des actions personnalisées
  • Queues Laravel : Support natif pour le traitement asynchrone via Redis, Beanstalkd, SQS, etc.
  • Scheduler Laravel : Intégration simple avec le cron via une seule commande
  • Middleware Laravel : Utilisation du système de middleware standard pour une intégration transparente

Cas d’usage concrets

Au-delà des statistiques de visite classiques, le paquet permet de nombreux cas d’usage avancés :

Sécurité et monitoring
  • Détection d’intrusions :

    • Identification de patterns d’attaque (brute force, injection SQL, XSS)
    • Détection de scans de vulnérabilités
    • Alertes en temps réel sur comportements suspects
  • Honeypots :

    • Création de pièges pour identifier les bots malveillants
    • Routes factices pour détecter les scanners automatiques
    • Collecte d’informations sur les techniques d’attaque
Analyse et optimisation
  • Analyse comportementale :

    • Suivi des parcours utilisateurs
    • Détection d’anomalies dans les patterns de navigation
    • Identification des points de friction dans l’UX
  • Monitoring API :

    • Surveillance des temps de réponse par endpoint
    • Détection des erreurs récurrentes
    • Analyse de la charge par client/application
Conformité et audit
  • Conformité RGPD :

    • Traçabilité complète des accès aux données sensibles
    • Historique des actions utilisateurs
    • Preuves d’audit pour les régulateurs
  • Debugging production :

    • Reproduction de bugs avec contexte complet
    • Analyse post-mortem d’incidents
    • Correlation avec les logs applicatifs

Optimisations pour la production

Le paquet a été conçu pour fonctionner efficacement même sous forte charge :

Performance
  • Batch inserts : Insertion groupée configurable pour réduire la charge base de données
  • Indexes optimisés : Tous les champs fréquemment requêtés sont indexés
  • Cache multiniveau : Utilisation du cache Laravel pour les entités fréquentes
  • Requêtes optimisées : Utilisation d’Eloquent avec eager loading pour éviter le problème N+1
Scalabilité
  • Architecture horizontale : Compatible avec les déploiements multi-serveurs
  • Queue distribution : Répartition de charge via les workers Laravel
  • Cache distribué : Support Redis Cluster et Memcached pour le cache partagé
Maintenance
  • Pruning automatique : Commande Artisan pour nettoyer les anciennes données
  • Rotation des logs : Stratégies de rétention configurables
  • Monitoring intégré : Métriques exposées pour Prometheus/Grafana

Installation et configuration

Installation via Composer
composer require sl-projects/laravel-request-logger
Migration de la base de données
php artisan migrate
Publication de la configuration (optionnel)
php artisan vendor:publish --tag=request-logger-config
Configuration pour Laravel 11+

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();

Exemples d’utilisation

Requêtes de base
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();
Analyses avancées
// 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();

Contribution et développement

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 !

Comment contribuer
  1. Fork le repository
  2. Créer une branche pour votre fonctionnalité (git checkout -b feature/amazing-feature)
  3. Commiter vos changements (git commit -m 'Add amazing feature')
  4. Pusher vers la branche (git push origin feature/amazing-feature)
  5. Ouvrir une Pull Request
Tests et qualité
# Lancer les tests
composer test

# Analyse statique
vendor/bin/phpstan analyse

# Serveur de développement
composer serve

Licence et contact

Pour toute question, suggestion ou rapport de bug, n’hésitez pas à ouvrir une issue sur GitHub.

Technologies utilisées

Laravel icon
Laravel
Framework PHP pour construire des applications web
PHP icon
PHP
PHP: Hypertext Preprocessor
2025 - Sofiane Lasri-Trienpont, développé sur Laravel.