Main Log Files
- Laravel Log:
storage/logs/laravel-*.log- General application logs - Security Log:
storage/logs/security-*.log- Authentication and security-related events - Admin Log:
storage/logs/admin-*.log- Admin panel activities
This guide explains how to effectively use logs and handle errors in InspireCMS to diagnose and resolve issues.
InspireCMS uses Laravel's logging system with some additional specialized logs.
storage/logs/laravel-*.log - General application logsstorage/logs/security-*.log - Authentication and security-related eventsstorage/logs/admin-*.log - Admin panel activities# View the latest logs
tail -f storage/logs/laravel-*.log
# Search logs for specific errors
grep -i "error" storage/logs/laravel-*.log
# Count occurrences of errors
grep -i "error" storage/logs/laravel-*.log | wc -l
For a more user-friendly experience, consider installing a log viewer:
composer require opcodesio/log-viewer
Then access your logs at /log-viewer (you should secure this route in production).
You can customize InspireCMS logging in config/logging.php:
'channels' => [
// Default Laravel logs
'stack' => [
'driver' => 'stack',
'channels' => ['single', 'slack'],
'ignore_exceptions' => false,
],
// Custom InspireCMS security logs
'security' => [
'driver' => 'daily',
'path' => storage_path('logs/security.log'),
'level' => 'notice',
'days' => 14,
],
// Custom admin activity logs
'admin' => [
'driver' => 'daily',
'path' => storage_path('logs/admin.log'),
'level' => 'info',
'days' => 30,
],
],
InspireCMS uses standard PSR-3 log levels:
use Illuminate\Support\Facades\Log;
// Basic logging
Log::info('Content was created', ['content_id' => $content->id]);
// Error logging
try {
// Some operation
} catch (\Exception $e) {
Log::error('Failed to create content', [
'exception' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString(),
]);
}
// Log to security channel
Log::channel('security')->warning('Failed login attempt', [
'ip' => request()->ip(),
'email' => $request->email,
]);
// Log to admin channel
Log::channel('admin')->info('Content published', [
'user' => auth()->user()->email,
'content_id' => $content->id,
]);
You can create a custom logger that automatically adds context:
// app/Support/Logger.php
namespace App\Support;
use Illuminate\Support\Facades\Log;
class Logger
{
public static function adminAction($message, $data = [])
{
$user = auth()->user();
Log::channel('admin')->info($message, array_merge([
'user_id' => $user ? $user->id : null,
'user_email' => $user ? $user->email : null,
'ip' => request()->ip(),
'user_agent' => request()->userAgent(),
], $data));
}
}
// Usage
\App\Support\Logger::adminAction('Updated template settings', [
'template' => $template->name,
]);
InspireCMS uses Laravel's exception handler located at app/Exceptions/Handler.php. You can extend this to customize error handling.
To customize how specific exceptions are handled:
// app/Exceptions/Handler.php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use SolutionForest\InspireCms\Exceptions\ContentNotFoundException;
use SolutionForest\InspireCms\Exceptions\TemplateNotFoundException;
use Throwable;
class Handler extends ExceptionHandler
{
public function register(): void
{
$this->reportable(function (Throwable $e) {
// Add custom reporting logic
});
$this->renderable(function (ContentNotFoundException $e, $request) {
if ($request->expectsJson()) {
return response()->json(['message' => 'Content not found'], 404);
}
return response()->view('errors.content-not-found', [], 404);
});
$this->renderable(function (TemplateNotFoundException $e, $request) {
if ($request->expectsJson()) {
return response()->json(['message' => 'Template not found'], 404);
}
return response()->view('errors.template-not-found', [
'template' => $e->getTemplateName(),
], 404);
});
}
}
Create custom error pages for common HTTP errors:
# Create error views directory if it doesn't exist
mkdir -p resources/views/errors
Example 404 error page:
// resources/views/errors/404.blade.php
@extends('layouts.error')
@section('title', 'Page Not Found')
@section('content')
<div class="error-page">
<h1>404</h1>
<h2>Page Not Found</h2>
<p>We couldn't find the page you're looking for.</p>
<a href="{{ url('/') }}" class="btn btn-primary">Return Home</a>
</div>
@endsection
When content can't be found, InspireCMS throws ContentNotFoundException.
try {
$content = inspirecms_content()->findByIds($id)->firstOrFail();
} catch (\SolutionForest\InspireCms\Exceptions\ContentNotFoundException $e) {
Log::warning('Content not found', ['id' => $id, 'url' => request()->url()]);
abort(404);
}
For production environments, consider using an external error monitoring service.
composer require sentry/sentry-laravel
Configure in .env:
SENTRY_LARAVEL_DSN=your-sentry-dsn
Initialize in app/Exceptions/Handler.php:
public function register(): void
{
$this->reportable(function (Throwable $e) {
if (app()->bound('sentry')) {
app('sentry')->captureException($e);
}
});
}
Create a command to generate error reports:
// app/Console/Commands/GenerateErrorReport.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\File;
class GenerateErrorReport extends Command
{
protected $signature = 'inspirecms:error-report {--days=7}';
protected $description = 'Generate a report of errors from logs';
public function handle()
{
$days = $this->option('days');
$this->info("Generating error report for the last {$days} days");
$logFiles = File::glob(storage_path('logs/laravel-*.log'));
// Implementation to parse logs and generate report
// ...
$this->info("Report generated: " . storage_path('logs/reports/error-report.html'));
}
}
InspireCMS uses Laravel's daily log channel by default which handles log rotation.
Custom configuration:
// config/logging.php
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 14, // Keep logs for 14 days
],
You can create a scheduled command to clean up old logs:
// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
// Clean logs older than 30 days
$schedule->command('inspirecms:clean-logs --days=30')->weekly();
}
// app/Console/Commands/CleanLogs.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Carbon\Carbon;
class CleanLogs extends Command
{
protected $signature = 'inspirecms:clean-logs {--days=30}';
protected $description = 'Clean up old log files';
public function handle()
{
$days = $this->option('days');
$this->info("Cleaning logs older than {$days} days");
$cutoffDate = Carbon::now()->subDays($days);
collect(File::glob(storage_path('logs/*.log')))
->filter(function ($file) use ($cutoffDate) {
return Carbon::createFromTimestamp(File::lastModified($file))->lt($cutoffDate);
})
->each(function ($file) {
$this->info("Removing: " . basename($file));
File::delete($file);
});
$this->info('Log cleanup complete');
}
}
If you encounter errors that you can't resolve: