Zum Hauptinhalt springen

Was ist Logging?

Das Logging von Laravel ist rund um das Konzept Channels aufgebaut. Ein Channel definiert, wohin und wie Logs geschrieben werden. Dateien, Slack, Syslog und viele weitere Ausgabeziele lassen sich kombinieren. Unter der Haube kommt Monolog zum Einsatz – mit einer Vielzahl an Handlern und Formattern.
Standardmäßig kommt der Channel stack zum Einsatz. stack ist ein übergeordneter Channel, der mehrere Channels bündelt.

Konfiguration

Die Logging-Konfiguration liegt zentral in config/logging.php. Den Standard-Channel wechseln Sie über die Umgebungsvariable LOG_CHANNEL.
// config/logging.php
'default' => env('LOG_CHANNEL', 'stack'),

Verfügbare Channel-Treiber

TreiberBeschreibung
singleSchreibt alle Logs in eine einzige Datei
dailyRotiert pro Tag in separate Dateien
slackSendet Nachrichten an einen Slack-Incoming-Webhook
stackElternteil, der mehrere Channels bündelt
syslogSchreibt in das System-Syslog
errorlogSchreibt in das PHP-Error-Log
monologVerwendet direkt einen Monolog-Handler
customVollständig anpassbarer Channel über eine Factory-Klasse

Log-Level

Laravel unterstützt die acht Log-Level aus RFC 5424. Nach absteigender Schwere sortiert:
LevelBeispielverwendung
emergencyDas gesamte System ist nicht mehr verwendbar; sofortiges Eingreifen erforderlich
alertSofortiges Eingreifen nötig (z. B. Datenbank nicht erreichbar)
criticalKritische Störung, bei der zentrale Funktionen ausfallen
errorLaufzeitfehler; Handlung erforderlich, oft aber nicht sofort
warningPotenzielles Problem, veraltete APIs, unerwartete Daten
noticeNormalbetrieb, aber bemerkenswert
infoReguläre Aktionen wie Login oder Bestellabschluss
debugDetaillierte Debug-Informationen während der Entwicklung
Die Option level eines Channels beschreibt den Mindest-Log-Level. Bei level = error werden nur error und höher (critical, alert, emergency) geschrieben.

Grundlegende Verwendung

Die Log-Facade

Verwenden Sie die Facade Illuminate\Support\Facades\Log, um pro Level zu loggen.
use Illuminate\Support\Facades\Log;

Log::emergency('Das System ist ausgefallen.');
Log::alert('Die Datenbankverbindung wurde unterbrochen.');
Log::critical('Der Zahlungsdienst antwortet nicht.');
Log::error('Die Aktualisierung der Nutzerdaten ist fehlgeschlagen.');
Log::warning('Eine veraltete Methode wurde aufgerufen.');
Log::notice('Die Konfigurationsdatei wurde neu geladen.');
Log::info('Ein Nutzer hat sich angemeldet.');
Log::debug('Ausführungszeit der Query: 42 ms');
Beispiel in einem Controller:
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;

class UserController extends Controller
{
    public function show(string $id): View
    {
        Log::info('Nutzerprofil wird angezeigt.', ['user_id' => $id]);

        return view('user.profile', [
            'user' => User::findOrFail($id),
        ]);
    }
}

Helper log()

Der Helper log() funktioniert ohne den Import der Facade.
log('Log-Eintrag über den Helper.');

// Auch Level und Kontext können angegeben werden
log('Nutzer wurde angelegt.', 'info', ['user_id' => $user->id]);

Kontextinformationen hinzufügen

Übergeben Sie zusätzlich zu Nachricht ein Kontext-Array, um zusammengehörige Informationen zu erfassen.
Log::info('Login fehlgeschlagen.', [
    'user_id' => $user->id,
    'ip'      => $request->ip(),
    'reason'  => 'Passwort stimmt nicht überein',
]);

withContext() – gemeinsamen Kontext für einen Channel

Wenn Sie für einen bestimmten Channel jeden folgenden Log-Eintrag mit gemeinsamen Informationen versehen möchten, verwenden Sie withContext(). Gut geeignet für z. B. eine Request-ID.
Log::withContext(['request-id' => (string) Str::uuid()]);

// Alle folgenden Logs enthalten automatisch request-id
Log::info('Verarbeitung beginnt.');
Log::error('Es ist ein Fehler aufgetreten.');

shareContext() – gemeinsamen Kontext für alle Channels

withContext() wirkt nur auf einen Channel. shareContext() verteilt den Kontext auf alle Channels.
Log::shareContext(['app-version' => config('app.version')]);

Channels konfigurieren

Der stack-Channel – gleichzeitig in mehrere Ziele schreiben

Mit stack schreibt ein einziger Log-Aufruf in mehrere Channels.
// config/logging.php
'channels' => [
    'stack' => [
        'driver'   => 'stack',
        'channels' => ['daily', 'slack'],
    ],

    'daily' => [
        'driver' => 'daily',
        'path'   => storage_path('logs/laravel.log'),
        'level'  => env('LOG_LEVEL', 'debug'),
        'days'   => 14,
    ],

    'slack' => [
        'driver'   => 'slack',
        'url'      => env('LOG_SLACK_WEBHOOK_URL'),
        'username' => env('LOG_SLACK_USERNAME', 'Laravel Log'),
        'emoji'    => env('LOG_SLACK_EMOJI', ':boom:'),
        'level'    => 'critical',
    ],
],
Mit dieser Konfiguration landen alle Logs ab debug in daily, und nur critical oder schlimmer geht zusätzlich an slack.
In der Produktion empfiehlt sich für den slack-Channel das Level error oder critical. Werden zu triviale Meldungen nach Slack gesendet, verschwinden wichtige Alarme in der Nachrichtenflut.

daily – Log-Rotation

Der daily-Channel rotiert Logs pro Tag und löscht ältere Dateien automatisch.
'daily' => [
    'driver' => 'daily',
    'path'   => storage_path('logs/laravel.log'),
    'level'  => env('LOG_LEVEL', 'debug'),
    'days'   => env('LOG_DAILY_DAYS', 14), // 14 Tage vorhalten
],
Ein kleiner Wert bei days lässt Logs früh verschwinden. Sorgen Sie in der Produktion für eine ausreichende Aufbewahrungszeit zur Fehleranalyse.

Fehlerbenachrichtigungen an Slack

Erstellen Sie eine Incoming Webhook URL in Slack und hinterlegen Sie sie in der .env.
LOG_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/xxx/yyy/zzz
// config/logging.php
'slack' => [
    'driver'   => 'slack',
    'url'      => env('LOG_SLACK_WEBHOOK_URL'),
    'username' => 'Laravel Error Bot',
    'emoji'    => ':fire:',
    'level'    => 'error',
],
Ergänzen Sie den slack-Channel im stack-Channel und setzen Sie LOG_CHANNEL=stack, um bei Fehlern automatische Benachrichtigungen zu erhalten.

In einen bestimmten Channel schreiben

Mit Log::channel() wählen Sie den Ziel-Channel explizit aus.
// Nur an slack schreiben
Log::channel('slack')->error('Der Zahlungsdienst antwortet nicht.');

// Gleichzeitig an mehrere Channels
Log::stack(['daily', 'slack'])->critical('Verbindung zur Datenbank fehlgeschlagen.');

On-Demand-Channels

Mit Log::build() erzeugen Sie einen Channel spontan, ohne ihn in der Konfigurationsdatei zu definieren. Praktisch für Tests oder temporäre Log-Ziele.
use Illuminate\Support\Facades\Log;

$channel = Log::build([
    'driver' => 'single',
    'path'   => storage_path('logs/import-' . now()->format('Ymd') . '.log'),
]);

Log::stack([$channel])->info('CSV-Import beginnt.');

Praxisbeispiele

Middleware mit Request-ID

Wenn Sie allen Logs eine gemeinsame Request-ID hinzufügen, lässt sich der Verlauf einer einzelnen Anfrage leicht nachvollziehen.
1

Middleware erzeugen

php artisan make:middleware AssignRequestId
2

handle() implementieren

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;

class AssignRequestId
{
    public function handle(Request $request, Closure $next): Response
    {
        $requestId = (string) Str::uuid();

        Log::withContext(['request-id' => $requestId]);

        $response = $next($request);

        $response->headers->set('X-Request-Id', $requestId);

        return $response;
    }
}
3

Middleware registrieren

Als globale Middleware in bootstrap/app.php registrieren.
->withMiddleware(function (Middleware $middleware) {
    $middleware->append(\App\Http\Middleware\AssignRequestId::class);
})
Ab jetzt enthalten alle Log-Einträge automatisch die request-id.
[2026-03-01 12:00:00] local.INFO: Nutzer hat sich angemeldet. {"request-id":"550e8400-...","user_id":1}
[2026-03-01 12:00:00] local.INFO: Dashboard wird angezeigt. {"request-id":"550e8400-..."}

Deprecation-Warnungen loggen

Sie können Warnungen zu veralteten PHP- oder Laravel-Funktionen protokollieren.
// config/logging.php
'deprecations' => [
    'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),
    'trace'   => env('LOG_DEPRECATIONS_TRACE', false),
],
In der .env legen Sie den Channel fest.
LOG_DEPRECATIONS_CHANNEL=daily

Laravel Pail – Logs in Echtzeit anzeigen

Laravel Pail ist ein Entwicklungs-Tool, das Application-Logs live im Terminal darstellt.
Für Pail benötigen Sie die PHP-Erweiterung PCNTL.

Installation

composer require --dev laravel/pail

Grundlegende Nutzung

# Logs live verfolgen
php artisan pail

# Ausführliche Anzeige (ohne Kürzung)
php artisan pail -v

# Inklusive Stacktrace
php artisan pail -vv

Logs filtern

# Nach Stichwort filtern
php artisan pail --filter="QueryException"

# Nur nach Nachrichtentext filtern
php artisan pail --message="Login"

# Nach Log-Level filtern
php artisan pail --level=error

# Nur Logs eines bestimmten Nutzers
php artisan pail --user=1

Zusammenfassung

LevelWann verwenden?
emergencyKritischer Ausfall, das gesamte System ist unbrauchbar
alertEin Mensch muss sofort eingreifen
criticalZentrale Funktionen sind ausgefallen
errorUnerwarteter Laufzeitfehler, Reaktion erforderlich
warningVeraltete Nutzung oder unerwartete Daten – zu beachten
noticeNormal, aber protokollierenswert
infoNutzeraktionen und Business-Events
debugDetaillierte Debug-Infos (in der Produktion meist nicht nötig)
  • Entwicklungsumgebung: single oder daily in Dateien schreiben.
  • Produktion: stack mit daily (Dateipersistenz) und slack (Fehlermeldungen) kombinieren.
  • Spezielle Logs: Mit Log::build() einen On-Demand-Channel für eine separate Datei anlegen.
  • Echtzeit-Monitoring: php artisan pail im Terminal.
  • debug-Logs können sensible Informationen enthalten. In der Produktion empfiehlt sich LOG_LEVEL=error oder höher.
  • Rotieren Sie Log-Dateien regelmäßig, damit die Festplatte nicht volläuft (Option days des daily-Channels).
  • Achten Sie bei Slack o. Ä. auf Rate Limits. Legen Sie den Level so, dass nur wichtige Fehler benachrichtigen.
Zuletzt geändert am 13. Juli 2026