A comprehensive change logs tracking package for Laravel 11+ that automatically tracks all model changes (create, update, delete, restore) with detailed audit trails
imamsudarajat04/laravel-change-logs is a Laravel package for a comprehensive change logs tracking package for laravel 11+ that automatically tracks all model changes (create, update, delete, restore) with detailed audit trails.
It currently has 2 GitHub stars and 21 downloads on Packagist (latest version v1.2.2).
Install it with composer require imamsudarajat04/laravel-change-logs.
Discover more Laravel packages by imamsudarajat04
or browse all Laravel packages to compare alternatives.
Last updated
A comprehensive change logs tracking package for Laravel 11+ that automatically tracks all model changes (create, update, delete, restore) with detailed audit trails.
β¨ Automatic Tracking - Zero configuration needed, just add a trait π Detailed Logging - Track field-level changes with old/new values π Flexible Querying - Built-in scopes and filters π€ User Context - Automatically captures user, IP, and user agent π·οΈ Tagging Support - Categorize logs with custom tags β‘ Queue Support - Async logging for better performance π§Ή Auto Cleanup - Scheduled cleanup of old logs π― Polymorphic - Works with any Eloquent model π Security - Excludes sensitive fields (passwords, tokens) π Statistics - Built-in analytics and reporting
composer require imamsudarajat04/laravel-change-logs
php artisan vendor:publish --provider="Imamsudarajat04\\ChangeLogs\\ChangeLogsServiceProvider"
This will publish:
config/change-logs.phpdatabase/migrations/xxx_create_change_logs_table.phpphp artisan migrate
use Imamsudarajat04\ChangeLogs\Traits\HasChangeLogs;
class User extends Authenticatable
{
use HasChangeLogs;
}
That's it! Now all changes to User model will be automatically tracked.
// Get all change logs for a model
$user = User::find(1);
$logs = $user->changeLogs; // Returns collection of ChangeLog
// Get recent logs
$recentLogs = $user->recentChangeLogs(5);
// Get logs by action
$updateLogs = $user->changeLogsByAction('UPDATE');
// Get logs for specific field
$emailChanges = $user->fieldChangeLogs('email');
// Check if model has logs
if ($user->hasChangeLogs()) {
// ...
}
// Get last change
$lastChange = $user->lastChangeLog();
use Imamsudarajat04\ChangeLogs\Models\ChangeLog;
// Using scopes
$logs = ChangeLog::action('UPDATE')->get();
$logs = ChangeLog::forModel(User::class)->byUser(1)->get();
$logs = ChangeLog::dateRange('2024-01-01', '2024-12-31')->get();
$logs = ChangeLog::withTag('important')->get();
// Chain multiple scopes
$logs = ChangeLog::action('UPDATE')
->byUser(1)
->dateRange('2024-01-01', '2024-12-31')
->limit(10)
->get();
use Imamsudarajat04\ChangeLogs\Facades\ChangeLog;
// Query with filters
$logs = ChangeLog::query([
'action' => 'UPDATE',
'user_id' => 1,
'start_date' => '2024-01-01',
'end_date' => '2024-12-31',
])->paginate(20);
// Get statistics
$stats = ChangeLog::getStatistics();
// Returns: ['total' => 100, 'by_action' => [...], 'by_user' => [...], 'recent' => [...]]
// Cleanup old logs
ChangeLog::cleanup(365); // Delete logs older than 365 days
class User extends Authenticatable
{
use HasChangeLogs;
public function getChangeLogExcludedFields(): array
{
return ['password', 'remember_token', 'api_token'];
}
}
class User extends Authenticatable
{
use HasChangeLogs;
public function getChangeLogDescription(string $action): ?string
{
return match($action) {
'CREATE' => "User {$this->name} was registered",
'UPDATE' => "User {$this->name} updated their profile",
'DELETE' => "User {$this->name} was deleted",
default => null,
};
}
}
class Order extends Model
{
use HasChangeLogs;
public function getChangeLogTags(string $action): array
{
return match($action) {
'CREATE' => ['order', 'new', 'customer-action'],
'UPDATE' => ['order', 'modified'],
default => ['order'],
};
}
}
class User extends Authenticatable
{
use HasChangeLogs;
public function shouldLogChanges(string $action): bool
{
// Don't log test users
if (str_contains($this->email, '@test.com')) {
return false;
}
return parent::shouldLogChanges($action);
}
}
// For single model
User::withoutChangeLogs(function() {
User::where('active', 0)->update(['status' => 'inactive']);
});
// For specific operations
config(['change-logs.enabled' => false]);
// Your operations here
config(['change-logs.enabled' => true]);
php artisan change-logs:install
# Options:
--migrations # Only publish migrations
--config # Only publish config
--force # Overwrite existing files
php artisan change-logs:stats
# With filters:
php artisan change-logs:stats --user=1
php artisan change-logs:stats --action=UPDATE
php artisan change-logs:stats --model="App\Models\User"
php artisan change-logs:stats --days=7
php artisan change-logs:cleanup
# Options:
--days=90 # Custom retention days
--force # Skip confirmation
php artisan change-logs:prune
# Options:
--model="App\Models\User" # Prune specific model
--action=DELETE # Prune specific action
--pretend # Dry run
Publish and edit config/change-logs.php:
return [
// Enable/disable globally
'enabled' => env('CHANGE_LOGS_ENABLED', true),
// Logging strategy
'log_per_field' => false, // true = separate log per field, false = bulk
// Track additional context
'track_ip' => true,
'track_user_agent' => true,
// Exclude fields
'hidden_fields' => ['password', 'remember_token'],
'exclude_timestamps' => true,
// Queue configuration
'queue' => [
'enabled' => false,
'connection' => null,
'queue' => 'default',
],
// Auto cleanup
'cleanup' => [
'enabled' => false,
'days' => 365,
],
];
Add to app/Console/Kernel.php:
protected function schedule(Schedule $schedule)
{
// Cleanup logs monthly
$schedule->command('change-logs:cleanup --force')->monthly();
// Or use prune
$schedule->command('change-logs:prune')->monthly();
}
composer test
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
If you discover any security-related issues, please email [email protected] instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.