Pourquoi Logging et monitoring Laravel ?
Au quotidien, un développeur Laravel doit gérer des applications complexes qui ont souvent besoin de maintenir une haute disponibilité et une performance optimale. La logging et la monitoring sont essentielles pour atteindre ces objectifs :
Logging : Permet de suivre les activités de l'application, enregistrer les erreurs et les avertissements, et analyser le comportement de l'application.
Monitoring : Consiste à surveiller l'état de santé de l'application en temps réel pour détecter les problèmes avant qu'ils ne se manifèstent.
Un cas d'utilisation concret : Imaginez une application e-commerce. Si un utilisateur rencontre des erreurs pendant la commande, le logging peut aider à identifier le problème et le monitoring permettra de déterminer s'il s'agit d'un incident temporaire ou d'un bug plus grave qui nécessite une intervention.
Prerequis
Pour suivre ce tutoriel, vous aurez besoin des éléments suivants :
- PHP 8.1+
- Composer
- Laravel CLI 9.x
- Un environnement de développement local (MAMP, XAMPP, Docker, etc.)
- Un compte GitHub pour le dépôt du projet
- Postman pour tester les API
Concepts fondamentaux
Logging
Le logging en Laravel est géré par la classe Illuminate\Log\Logger. Voici les principales méthodes :
| Méthode | Description |
|---|---|
info($message) |
Enregistre un message d'information. |
error($message) |
Enregistre une erreur critique. |
warning($message) |
Enregistre un avertissement de sécurité. |
Schema mental :
+-------------------+
| Logger |
|-------------------|
| - info(message) |
| - error(message) |
| - warning(message)|
+-------------------+
Code fonctionnel :
// app/Services/UserService.php
namespace App\Services;
use Illuminate\Support\Facades\Log;
class UserService {
public function createUser($data) {
try {
// Code pour créer un utilisateur
Log::info('Utilisateur créé avec succès', $data);
} catch (\Exception $e) {
Log::error('Erreur lors de la création de l\'utilisateur', ['exception' => $e]);
}
}
}
Monitoring
Laravel offre diverses options pour le monitoring. Voici les principales :
- Laravel Scout : Intégration avec Elasticsearch pour des recherches en temps réel.
- Laravel Telemetry : Permet de suivre les performances de l'application.
Schema mental :
+-------------------+
| Monitoring |
|-------------------|
| - Laravel Scout |
| - Laravel Telemetry|
+-------------------+
Code fonctionnel :
// app/Providers/AppServiceProvider.php
namespace App\Providers;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Log;
class AppServiceProvider extends ServiceProvider {
public function boot() {
Queue::after(function ($job, $data) {
Log::info("Job {$job->getName()} a été traité avec succès", $data);
});
}
}
Mise en pratique : projet fil rouge
Nous allons créer un gestionnaire de tâches simple pour bien comprendre les concepts de logging et monitoring.
Étape 1 : Création du projet Laravel
composer create-project --prefer-dist laravel/laravel task-manager "9.*"
cd task-manager
Étape 2 : Configuration du logging
Modifier le fichier config/logging.php pour ajouter un canal personnalisé :
// config/logging.php
return [
'default' => env('LOG_CHANNEL', 'stack'),
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
'custom-channel' => [
'driver' => 'monolog',
'handler' => Monolog\Handler\StreamHandler::class,
'with' => ['stream' => storage_path('logs/custom.log')],
],
],
];
Étape 3 : Création d'un modèle et une migration
php artisan make:model Task -m
Migration :
// database/migrations/xxxx_xx_xx_xxxxxx_create_tasks_table.php
public function up() {
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description')->nullable();
$table->boolean('completed')->default(false);
$table->timestamps();
});
}
Model :
// app/Models/Task.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Task extends Model {
protected $fillable = ['title', 'description', 'completed'];
}
Étape 4 : Création d'un service pour gérer les tâches
php artisan make:service TaskService
Code du service :
// app/Services/TaskService.php
namespace App\Services;
use App\Models\Task;
use Illuminate\Support\Facades\Log;
class TaskService {
public function createTask($data) {
try {
$task = Task::create($data);
Log::info('Tâche créée avec succès', ['task' => $task]);
return $task;
} catch (\Exception $e) {
Log::error('Erreur lors de la création de la tâche', ['exception' => $e]);
throw $e;
}
}
public function updateTask($id, $data) {
try {
$task = Task::findOrFail($id);
$task->update($data);
Log::info('Tâche mise à jour avec succès', ['task' => $task]);
return $task;
} catch (\Exception $e) {
Log::error('Erreur lors de la mise à jour de la tâche', ['exception' => $e]);
throw $e;
}
}
public function deleteTask($id) {
try {
$task = Task::findOrFail($id);
$task->delete();
Log::info('Tâche supprimée avec succès', ['task' => $task]);
} catch (\Exception $e) {
Log::error('Erreur lors de la suppression de la tâche', ['exception' => $e]);
throw $e;
}
}
}
Étape 5 : Création d'un contrôleur pour les routes
php artisan make:controller TaskController --api
Code du contrôleur :
// app/Http/Controllers/TaskController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Task;
use App\Services\TaskService;
use Symfony\Component\HttpFoundation\Response as HttpResponse;
class TaskController extends Controller {
protected $taskService;
public function __construct(TaskService $taskService) {
$this->taskService = $taskService;
}
public function index() {
return response()->json(Task::all(), HttpResponse::HTTP_OK);
}
public function store(Request $request) {
try {
$task = $this->taskService->createTask($request->all());
return response()->json($task, HttpResponse::HTTP_CREATED);
} catch (\Exception $e) {
Log::error('Erreur lors de la création de la tâche', ['exception' => $e]);
return response()->json(['message' => 'Erreur interne'], HttpResponse::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function show($id) {
try {
$task = Task::findOrFail($id);
return response()->json($task, HttpResponse::HTTP_OK);
} catch (\Exception $e) {
Log::error('Erreur lors de la récupération de la tâche', ['exception' => $e]);
return response()->json(['message' => 'Tâche non trouvée'], HttpResponse::HTTP_NOT_FOUND);
}
}
public function update(Request $request, $id) {
try {
$task = $this->taskService->updateTask($id, $request->all());
return response()->json($task, HttpResponse::HTTP_OK);
} catch (\Exception $e) {
Log::error('Erreur lors de la mise à jour de la tâche', ['exception' => $e]);
return response()->json(['message' => 'Erreur interne'], HttpResponse::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function destroy($id) {
try {
$this->taskService->deleteTask($id);
return response()->json(null, HttpResponse::HTTP_NO_CONTENT);
} catch (\Exception $e) {
Log::error('Erreur lors de la suppression de la tâche', ['exception' => $e]);
return response()->json(['message' => 'Erreur interne'], HttpResponse::HTTP_INTERNAL_SERVER_ERROR);
}
}
}
Étape 6 : Définition des routes
Modifier le fichier routes/api.php :
// routes/api.php
use App\Http\Controllers\TaskController;
Route::apiResource('tasks', TaskController::class);
Étape 7 : Exécution des migrations et création du serveur
php artisan migrate
php artisan serve
Erreurs frequentes et debugging
Voici quelques erreurs courantes avec leur solution :
Erreur de syntaxe dans le code PHP
# ❌ Mauvais $user = User::find($id); # ✅ Correct $user = User::findOrFail($id);Avertissement lors du chargement des fichiers de configuration
# ❌ Mauvais config(['database.connections.mysql.host' => 'localhost']); # ✅ Correct config('database.connections.mysql.host', 'localhost');Erreur de connexion à la base de données
# ❌ Mauvais php artisan migrate # ✅ Correct DB_CONNECTION=mysql php artisan migrate
Pour aller plus loin
Utiliser Laravel Scout pour les recherches en temps réel :
Intégrer Laravel Telemetry pour le monitoring des performances :
Déployer l'application sur un serveur VPS avec Docker :
Défi pratique
Créez une application API de blog simple (posts, comments) en utilisant les concepts appris. Assurez-vous d'ajouter le logging et le monitoring pour chaque opération principale.