Ontwikkel geavanceerde PHP-foutafhandeling en logging
description
Met deze prompt leer je hoe je een effectief foutafhandelingssysteem opzet dat helpt bij het snel opsporen en oplossen van problemen in je PHP-project. Hierdoor verhoog je de stabiliteit en onderhoudbaarheid van je applicatie en voorkom je onverwachte downtime. Het systeem onderscheidt zich door uitgebreide foutclassificatie en geautomatiseerde notificaties, wat beter is dan simpele foutmeldingen of statische logging.
prompt
Help me een robuust foutafhandelingssysteem in PHP te ontwerpen en implementeren dat uitzonderingen efficiënt opvangt en valide logging uitvoert. Vertel me hoe ik foutmeldingen ka ...
try_prompt
generate_helper
disclaimerOnPageApi
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een stapsgewijze aanpak om een robuust foutafhandelingssysteem in PHP, specifiek binnen Laravel, te ontwerpen en te implementeren:
1. Gebruik het ingebouwde Laravel foutafhandelingssysteem:
- Laravel heeft een `Handler` klasse (`app/Exceptions/Handler.php`) die je kunt aanpassen om fouten op te vangen en te loggen.
2. Categoriseer foutmeldingen:
- Maak gebruik van Exception-klassen om verschillende foutcategorieën te definiëren, bijvoorbeeld:
```php
class ValidationException extends \Exception {}
class DatabaseException extends \Exception {}
class ExternalApiException extends \Exception {}
```
- Of gebruik bestaande Laravel exceptions en voeg eigen labels toe via custom properties.
3. Valideer en categoriseer binnen `Handler`:
- In `render()` of `report()` methodes kun je exceptions inspecteren en categoriseren:
```php
public function report(Exception $exception)
{
if ($exception instanceof ValidationException) {
// Specifieke logging of notificaties
} elseif ($exception instanceof DatabaseException) {
// Andere acties
}
parent::report($exception);
}
```
4. Logbestanden structureren:
- Laravel gebruikt standaard Monolog, dat je kunt configureren in `config/logging.php`.
- Voor gestructureerde logs (bijvoorbeeld JSON formaat):
```php
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily'],
'ignore_exceptions' => false,
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'tap' => [App\Logging\CustomFormatter::class],
],
],
```
- Implementeer een custom formatter voor JSON-logs:
```php
namespace App\Logging;
use Monolog\Formatter\JsonFormatter;
class CustomFormatter
{
public function __invoke($logger)
{
foreach ($logger->getHandlers() as $handler) {
$handler->setFormatter(new JsonFormatter());
}
}
}
```
5. Log prioriteit en metadata:
- Voeg context toe bij logging:
```php
Log::error('Database fout', [
'error_code' => $exception->getCode(),
'user_id' => auth()->id(),
'endpoint' => request()->path(),
]);
```
6. Notificaties op basis van foutprioriteit:
- Gebruik Laravel notificaties en queues:
- Definieer verschillende notificatiestemplates voor waarschuwingen, kritieke fouten, etc.
- Stel prioriteitsregels in, bijvoorbeeld:
```php
if ($exception instanceof DatabaseException && $exception->getCode() >= 500) {
Notification::route('mail', 'admin@voorbeeld.nl')->notify(new CriticalErrorNotification($exception));
}
```
- Je kunt ook Slack, SMS of andere kanalen gebruiken.
7. Automatisering en monitoring:
- Overweeg integratie met monitoring tools zoals Sentry, Bugsnag of Laravel Telescope voor realtime foutbewaking.
8. Best practices:
- Zorg dat gevoelige gegevens niet in logs terechtkomen.
- Implementeer fallback logging voor als de primaire logserver niet bereikbaar is.
- Test je foutafhandelingsmechanismen regelmatig.
Door deze aanpak te volgen, creëer je een flexibel, schaalbaar en inzichtelijk foutafhandelingssysteem dat je Laravel-applicatie robuust maakt.
provider: deepseek
model: deepseek-chat
Zeker, ik help je graag een robuust foutafhandelingssysteem te bouwen in Laravel. Hier is een complete implementatiegids:
## 1. Exception Handling Basisconfiguratie
Laravel heeft al een krachtig exception handling systeem via `App\Exceptions\Handler`:
```php
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Auth\AuthenticationException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Validation\ValidationException;
use App\Notifications\CriticalErrorNotification;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
class Handler extends ExceptionHandler
{
protected $dontReport = [
AuthenticationException::class,
ValidationException::class,
HttpException::class,
];
public function register(): void
{
$this->reportable(function (Throwable $e) {
$this->categorizeAndLogException($e);
});
}
protected function categorizeAndLogException(Throwable $e): void
{
$context = $this->getExceptionContext($e);
$severity = $this->determineSeverity($e);
match($severity) {
'CRITICAL' => $this->handleCriticalError($e, $context),
'ERROR' => Log::error($e->getMessage(), $context),
'WARNING' => Log::warning($e->getMessage(), $context),
'INFO' => Log::info($e->getMessage(), $context),
default => Log::debug($e->getMessage(), $context)
};
}
}
```
## 2. Foutcategorisatie en Severity Bepaling
```php
protected function determineSeverity(Throwable $e): string
{
return match(true) {
$e instanceof \PDOException,
$e instanceof \RedisException,
$e instanceof \ErrorException => 'CRITICAL',
$e instanceof ModelNotFoundException,
$e instanceof HttpException && $e->getStatusCode() >= 500 => 'ERROR',
$e instanceof ValidationException,
$e instanceof HttpException && $e->getStatusCode() >= 400 => 'WARNING',
default => 'INFO'
};
}
protected function getExceptionContext(Throwable $e): array
{
return [
'exception' => get_class($e),
'file' => $e->getFile(),
'line' => $e->getLine(),
'code' => $e->getCode(),
'trace' => $e->getTraceAsString(),
'url' => request()->fullUrl(),
'method' => request()->method(),
'ip' => request()->ip(),
'user_id' => auth()->id() ?? 'guest',
'user_agent' => request()->userAgent()
];
}
```
## 3. Gestructureerde Logging Configuratie
Pas je `config/logging.php` aan:
```php
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily', 'slack'],
'ignore_exceptions' => false,
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 14,
'formatter' => Monolog\Formatter\JsonFormatter::class,
'formatter_with' => [
'includeStacktraces' => true,
],
],
'critical' => [
'driver' => 'daily',
'path' => storage_path('logs/critical.log'),
'level' => 'critical',
'days' => 30,
'formatter' => Monolog\Formatter\JsonFormatter::class,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Error Bot',
'emoji' => ':boom:',
'level' => 'critical',
],
]
```
## 4. Notificatiesysteem voor Kritieke Fouten
Maak een notification class:
```php
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Messages\SlackAttachment;
class CriticalErrorNotification extends Notification
{
use Queueable;
protected $exception;
protected $context;
public function __construct(\Throwable $exception, array $context)
{
$this->exception = $exception;
$this->context = $context;
}
public function via($notifiable): array
{
return ['mail', 'slack'];
}
public function toMail($notifiable): MailMessage
{
return (new MailMessage)
->subject('🚨 Kritieke Fout Opgetreden: ' . get_class($this->exception))
->markdown('emails.errors.critical', [
'exception' => $this->exception,
'context' => $this->context
]);
}
public function toSlack($notifiable): SlackMessage
{
return (new SlackMessage)
->error()
->content('Kritieke applicatiefout opgetreden!')
->attachment(function (SlackAttachment $attachment) {
$attachment->fields([
'Exception' => get_class($this->exception),
'Message' => $this->exception->getMessage(),
'File' => $this->exception->getFile() . ':' . $this->exception->getLine(),
'URL' => $this->context['url'] ?? 'N/A',
'User' => $this->context['user_id'] ?? 'guest',
]);
});
}
}
```
## 5. Kritieke Fouten Afhandeling
```php
protected function handleCriticalError(Throwable $e, array $context): void
{
// Log naar critical channel
Log::channel('critical')->emergency($e->getMessage(), $context);
// Stuur notificaties
if (config('app.env') === 'production') {
$this->sendCriticalNotifications($e, $context);
}
}
protected function sendCriticalNotifications(Throwable $e, array $context): void
{
$notifiables = config('logging.notifiables', [
'admin@example.com',
'dev-team@example.com'
]);
Notification::route('mail', $notifiables)
->route('slack', config('services.slack.webhook_url'))
->notify(new CriticalErrorNotification($e, $context));
}
```
## 6. Custom Exception Classes
Maak gespecialiseerde exception classes:
```php
<?php
namespace App\Exceptions;
use Exception;
class DatabaseConnectionException extends Exception
{
protected $severity = 'CRITICAL';
public function __construct($message = "Database connection failed", $code = 0, Exception $previous = null)
{
parent::__construct($message, $code, $previous);
}
}
class ApiRateLimitException extends Exception
{
protected $severity = 'WARNING';
public function __construct($message = "API rate limit exceeded", $code = 429, Exception $previous = null)
{
parent::__construct($message, $code, $previous);
}
}
```
## 7. Gebruik in Controllers
```php
<?php
namespace App\Http\Controllers;
use App\Exceptions\DatabaseConnectionException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class UserController extends Controller
{
public function index()
{
try {
$users = DB::connection()->getPdo()->query('SELECT * FROM users');
return response()->json($users);
} catch (\PDOException $e) {
throw new DatabaseConnectionException("Database query failed: " . $e->getMessage());
}
}
}
```
## 8. Environment Configuratie
In je `.env` file:
```env
APP_ENV=production
APP_DEBUG=false
LOG_CHANNEL=stack
LOG_LEVEL=error
LOG_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/your-webhook
LOGGING_NOTIFIABLES=admin@example.com,dev@example.com
```
## 9. Monitoring en Alerting
Voeg Health Checks toe:
```php
// routes/web.php
Route::get('/health', function() {
try {
DB::connection()->getPdo();
Redis::connection()->ping();
return response()->json(['status' => 'healthy']);
} catch (\Exception $e) {
Log::critical('Health check failed', ['error' => $e->getMessage()]);
return response()->json(['status' => 'unhealthy'], 500);
}
});
```
Dit systeem biedt:
- Gestructureerde logging met JSON-formattering
- Automatische severity classificatie
- Multi-channel notificaties (email, Slack)
- Environment-aware error handling
- Uitbreidbare exception hierarchy
- Gedetailleerde context informatie
Het is belangrijk om regelmatig je logbestanden te reviewen en je alerting drempels aan te passen op basis van je specifieke gebruikspatroon.
error: Generation failed [deepseek] prompt_id=1406 locale=fr err=DeepSeek connection/timeout