jingyue/log-view-php
Laravel log viewer based on rap2hpoutre/laravel-log-viewer, with added navigation for logs stored in nested folders. Browse, search, and inspect Laravel/Lumen log files in your browser by routing to the controller—no public assets required.
Installation:
composer require jingyue/log-view-php
Ensure your composer.json includes the package under require.
Publish Configuration (optional):
php artisan vendor:publish --provider="Jingyue\LogViewer\LogViewerServiceProvider"
This generates a config/log-viewer.php file for customization.
Route Definition:
Add this to your routes/web.php (or routes/api.php for Lumen):
Route::get('/logs', 'Jingyue\LogViewer\LogViewerController@index');
For Lumen, use:
$router->get('/logs', 'Jingyue\LogViewer\LogViewerController@index');
First Use Case:
Visit /logs in your browser. The package will display a hierarchical view of Laravel’s log files (e.g., storage/logs/laravel.log, nested folders like storage/logs/debug/, etc.). Clicking a log file opens its contents with syntax highlighting.
Log Navigation:
laravel.log, debug/, job/) with collapsible folders.INFO, ERROR) color-coded.Integration with Laravel’s Logging:
Monolog setup. No changes to your config/logging.php are needed.laravel.log) and rotated logs (e.g., laravel-2023-10-01.log).Search Functionality:
type: Error, user: 123)./\d{3}-/) for advanced queries.Access Control:
Route::get('/logs', function () {
if (auth()->check() && auth()->user()->isAdmin()) {
return app('log-viewer')->show();
}
abort(403);
});
Customizing Log Paths:
Override the default log path in config/log-viewer.php:
'log_path' => storage_path('custom-logs'),
Extending the Viewer:
Add custom log files or directories by modifying the LogViewerServiceProvider:
public function register()
{
$this->app->bind('log-viewer.paths', function () {
return [
storage_path('logs/laravel.log'),
storage_path('custom-logs/'),
];
});
}
API Access:
For programmatic log inspection, use the LogViewerFacade:
use Jingyue\LogViewer\Facades\LogViewer;
$logs = LogViewer::getLogs(); // Returns array of log entries
Lumen-Specific: In Lumen, inject the controller directly:
$app->get('/logs', 'Jingyue\LogViewer\LogViewerController@index');
Permission Issues:
www-data, nginx) has read access to storage/logs/.chmod -R 755 storage/logs/
chown -R www-data:www-data storage/logs/
Large Log Files:
config/logging.php to rotate logs daily.max_lines filter in config/log-viewer.php:
'max_lines' => 5000,
Nested Folder Quirks:
config/log-viewer.php.Caching:
Cache::remember layer around LogViewer::getLogs().LogViewer::processLogs()).Lumen Compatibility:
$app->register(Jingyue\LogViewer\LogViewerServiceProvider::class);
Log Not Showing? Check if the route is registered and the controller is autoloaded. Run:
php artisan route:list
Ensure Jingyue\LogViewer\LogViewerController@index appears.
Blank Page?
Enable Laravel’s debug mode (APP_DEBUG=true in .env) and check for:
storage/logs/ directory (create it manually).storage/logs/laravel.log.Search Not Working? The search uses JavaScript (likely jQuery). Verify:
Custom Log Levels:
Extend the LogLevel class to support your app’s custom levels:
namespace App\Extensions;
use Jingyue\LogViewer\LogLevel;
class CustomLogLevel extends LogLevel
{
public static function getColors(): array
{
return array_merge(parent::getColors(), [
'CUSTOM' => '#800080', // Purple for "CUSTOM" level
]);
}
}
Then bind it in the service provider.
Add Context to Logs: Parse log entries to extract structured data (e.g., user IDs, request IDs) and display them as clickable links. Example:
// In a custom LogViewer extension
$logEntry->context['user_id'] = preg_match('/user_id: (\d+)/', $entry, $matches) ? $matches[1] : null;
Export Functionality: Add a download button to export logs as JSON/CSV:
// In LogViewerController
public function export()
{
$logs = LogViewer::getLogs();
return response()->json($logs)->header('Content-Type', 'application/json');
}
Real-Time Updates: Use Laravel Echo/Pusher to push new log entries to the client:
// Frontend JS
Echo.channel('logs')
.listen('LogUpdated', (e) => {
// Append new log entry to the DOM
});
How can I help you explore Laravel packages today?