opcodesio/log-viewer
A fast, beautiful Laravel log viewer for browsing and managing logs in storage/logs and beyond. Search and filter entries by level, share links, download/delete files, preview logged mails, support multiple hosts, dark mode, mobile UI, and API access.
Installation:
composer require opcodesio/log-viewer
php artisan log-viewer:publish
resources/views/vendor/log-viewer and config/log-viewer.php.Access:
/log-viewer in your browser (default route).storage/logs/laravel.log).First Use Case:
error) or searching for a specific exception class (e.g., QueryException).Log Exploration:
debug, info, warning, error, critical).failed, timeout).Advanced Features:
// Enable in config/log-viewer.php:
'stack_trace' => [
'enabled' => true,
]
Log::channel('mail').API Integration:
/api/log-viewer):
$logs = Http::get('/api/log-viewer/folders');
$entries = Http::get('/api/log-viewer/folders/{folder}/files/{file}/entries');
Custom Log Parsers:
// config/log-viewer.php
'log_types' => [
'custom_json' => [
'parser' => \Opcodes\LogViewer\Parsers\CustomJsonParser::class,
'path' => storage_path('logs/custom/*.json'),
],
],
Opcodes\LogViewer\Parsers\ParserInterface.Multi-Host Support:
config/log-viewer.php:
'remote_logs' => [
'ssh://user@remote-server:/var/log/myapp' => [
'driver' => 'ssh',
'username' => env('REMOTE_LOG_USER'),
'password' => env('REMOTE_LOG_PASSWORD'),
],
],
/log-viewer route in routes/web.php:
Route::middleware(['auth'])->group(function () {
Route::get('/log-viewer', [\Opcodes\LogViewer\Http\Controllers\LogViewerController::class, 'index']);
});
php artisan vendor:publish --tag=log-viewer-assets
resources/views/vendor/log-viewer/assets/js/app.js for custom UI behavior.// config/log-viewer.php
'octane' => [
'scoped_bindings' => true,
],
Permission Issues:
www-data, nginx) has read access to log directories:
chmod -R 755 storage/logs/
chown -R www-data:www-data storage/logs/
Log Format Mismatches:
API Authentication Failures:
401 Unauthorized even with valid tokens.APP_URL is set in .env and the API route is properly authenticated:
// routes/api.php
Route::middleware('auth:sanctum')->group(function () {
Route::prefix('log-viewer')->group(\Opcodes\LogViewer\Routes\Api::routes());
});
Horizon Log Gaps:
single or database). Update the parser in config/log-viewer.php:
'log_types' => [
'horizon' => [
'parser' => \Opcodes\LogViewer\Parsers\HorizonParser::class,
'path' => storage_path('logs/horizon/*.log'),
],
],
Asset Caching:
php artisan cache:clear
php artisan config:clear
bootstrap/cache and reload.Log Parser Debugging:
config/log-viewer.php:
'debug' => true,
storage/logs/laravel.log) for parser errors.API Debugging:
Http::debug(true) to inspect API responses:
Http::debug(true);
$response = Http::get('/api/log-viewer/folders');
Performance:
// config/log-viewer.php
'pagination' => [
'items_per_page' => 50, // Default: 100
],
Custom UI Components:
// resources/js/log-viewer/app.js
import DefaultApp from '@opcodes/log-viewer/dist/js/app';
export default {
extends: DefaultApp,
methods: {
customMethod() {
// Add custom logic
}
}
};
Log Annotations:
LogEntry model or using middleware:
// app/Http/Middleware/AnnotateLogs.php
public function handle($request, Closure $next) {
Log::withContext(['user_id' => auth()->id()]);
return $next($request);
}
Webhook Notifications:
Log::listen:
Log::listen(function ($level, $message, array $context) {
if ($level === 'error' && str_contains($message, 'Database')) {
Http::post('https://your-webhook-url', ['log' => $message]);
}
});
Dark Mode Toggle:
/* resources/css/log-viewer/app.css */
.log-viewer-dark .log-entry {
background-color: #1a1a1a;
}
Assets Path:
// config/log-viewer.php
'assets' => [
'path' => public_path('custom-log-viewer-assets'),
],
null to serve assets directly from the vendor directory (no publishing needed).Local IP in Hashes:
// config/log-viewer.php
'hashing' => [
'use_local_ip' => false,
],
Mail Parser:
// config/log-viewer.php
'mail' => [
'enabled' => true,
'path' => storage_path('logs/mail.log'),
],
How can I help you explore Laravel packages today?