rap2hpoutre/laravel-log-viewer
Lightweight Laravel log viewer for Laravel 12/13. Install via Composer and add a single route to LogViewerController to browse app logs in the browser. No public assets or vendor routes; works with or without log rotation. View and config are publishable.
composer require rap2hpoutre/laravel-log-viewer
config/app.php if needed):
Rap2hpoutre\LaravelLogViewer\LaravelLogViewerServiceProvider::class,
routes/web.php):
Route::get('logs', [\Rap2hpoutre\LaravelLogViewer\LogViewerController::class, 'index'])->middleware('auth');
/logs in your browser.laravel.log, daily rotated logs) without CLI access.tail -f storage/logs/laravel.log with a searchable UI./resources/views/vendor/laravel-log-viewer/log.blade.php (published via vendor:publish)./config/logviewer.php (customize log paths, UI settings).\Rap2hpoutre\LaravelLogViewer\LogViewerController (extend for custom logic).Basic Log Viewing:
/logs to see all Laravel log files (default: storage/logs/laravel.log and daily rotated logs).Searching Logs:
type:error or user:123).Custom Log Paths:
config/logviewer.php:
'log_files' => [
storage_path('logs/custom.log'),
storage_path('logs/app.log'),
],
Middleware Integration:
Route::get('logs', [LogViewerController::class, 'index'])->middleware(['auth', 'admin']);
barryvdh/laravel-debugbar for a unified debugging dashboard.if (app()->environment('local', 'staging')) {
Route::get('logs', [LogViewerController::class, 'index']);
}
public function index()
{
$logs = $this->getLogs();
$redactedLogs = collect($logs)->map(fn ($log) => preg_replace('/password=[^&]+/', 'password=****', $log));
return view('vendor.laravel-log-viewer.log', ['logs' => $redactedLogs]);
}
error, warning).'log_files' => config('logging.custom_paths'),
Route::get('logs/export', [LogViewerController::class, 'export']);
public function export()
{
return response()->json($this->getLogs());
}
Permission Errors:
storage/logs/ is writable:
chmod -R 755 storage/logs/
InvalidArgumentException in logs; verify file paths in config/logviewer.php.Config Cache Issues:
InvalidArgumentException in FileViewFinder.php after publishing views.php artisan config:clear
Log Rotation Gaps:
laravel-2024-05-10.log) may not appear if the package isn’t updated to v2.0.0+.Sensitive Data Exposure:
auth, admin middleware).Large Log Files:
tail to show only recent logs by default.config/logviewer.php points to the correct log files. Default:
'log_files' => [
storage_path('logs/laravel.log'),
storage_path('logs/laravel-*.log'),
],
public function index()
{
dd($this->getLogs()); // Debug log contents
}
php artisan view:clear
Custom Log Levels:
Extend the LogViewerController to filter logs by level (e.g., error, debug):
public function index()
{
$logs = $this->getLogs()->filter(fn ($log) => str_contains($log, '[ERROR]'));
return view('...', ['logs' => $logs]);
}
Database-Backed Logs:
Override the controller to fetch logs from a database (e.g., log_entries table):
public function getLogs()
{
return DB::table('log_entries')->get()->pluck('message');
}
Real-Time Updates: Use Laravel Echo/Pusher to stream new logs in real-time (requires custom implementation).
Multi-Tenant Logs: Dynamically set log paths based on the current tenant:
'log_files' => [storage_path("logs/tenant-{$tenantId}.log")],
laravel-*.log). Avoid wildcards in non-standard paths.ERROR vs error) may require normalization.memory_limit. Increase if needed:
ini_set('memory_limit', '512M');
find storage/logs/ -name "laravel-*.log" -mtime +30 -exec gzip {} \;
How can I help you explore Laravel packages today?