laithalenooz / activity-log
A flexible activity log package for Laravel.
Installs: 11
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/laithalenooz/activity-log
Requires
- php: >=8.2
- illuminate/support: ^11.30
README
A flexible and customizable activity log package for Laravel 11, supporting multiple databases like MySQL and MongoDB. It provides middleware for logging HTTP requests, customizable log levels, Eloquent relationships to retrieve the causer and subject of activities, and a data retention feature to manage log storage.
Table of Contents
- Features
- Requirements
- Installation
- Configuration
- Running Migrations
- Usage
- Data Retention
- Advanced Usage
- Testing
- Contributing
- License
Features
- Database Flexibility: Supports both MySQL and MongoDB.
- Middleware for HTTP Request Logging: Logs HTTP requests and responses.
- Customizable Log Levels: Supports
info,warning,error, and custom log levels. - Eloquent Relationships: Retrieve
causerandsubjectmodels via Eloquent relationships. - Automatic Model Event Logging: Automatically logs model
created,updated, anddeletedevents. - Data Retention: Configurable data retention period with automatic pruning of old logs.
- Configurable: Offers extensive configuration options.
- Extensible: Easily extendable to fit custom needs.
Requirements
- PHP >= 8.2
- Laravel 11
- For MongoDB support: jenssegers/mongodb package
Installation
You can install the package via Composer:
composer require laithalenooz/activity-log
Configuration
After installing the package, publish the configuration file and middleware:
php artisan vendor:publish --provider="LaithAlEnooz\ActivityLog\ActivityLogServiceProvider" --tag="config" php artisan vendor:publish --provider="LaithAlEnooz\ActivityLog\ActivityLogServiceProvider" --tag="middleware" php artisan vendor:publish --provider="LaithAlEnooz\ActivityLog\ActivityLogServiceProvider" --tag="resources" php artisan vendor:publish --provider="LaithAlEnooz\ActivityLog\ActivityLogServiceProvider" --tag="controller"
This will create an activitylog.php file in your config directory and copy the LogHttpRequests middleware to your app/Http/Middleware directory.
Configuration Options
config/activitylog.php
return [ /* |-------------------------------------------------------------------------- | Default Connection |-------------------------------------------------------------------------- | | The database connection that will be used to store the activity logs. | You may set this to any of the connections defined in your database | configuration file. | */ 'connection' => env('ACTIVITY_LOG_CONNECTION', 'mysql'), /* |-------------------------------------------------------------------------- | Default Log Level |-------------------------------------------------------------------------- | | The default log level to use when logging activities. You can override | this level when logging specific activities. | */ 'default_log_level' => 'info', /* |-------------------------------------------------------------------------- | Log HTTP Requests |-------------------------------------------------------------------------- | | Determines whether HTTP requests should be automatically logged using | the provided middleware. Set to true to enable request logging. | */ 'log_http_requests' => false, /* |-------------------------------------------------------------------------- | HTTP Request Log Level |-------------------------------------------------------------------------- | | The log level for HTTP request logs. | */ 'http_request_log_level' => 'info', /* |-------------------------------------------------------------------------- | Data Retention Period |-------------------------------------------------------------------------- | | This value determines how long (in days) the activity logs should be | retained before they are deleted. Set it to null if you don't want | to delete old logs automatically. | */ 'data_retention_days' => env('ACTIVITY_LOG_RETENTION_DAYS', 365), /* |-------------------------------------------------------------------------- | Log Viewer |-------------------------------------------------------------------------- | | The log viewer configuration allows you to customize the behavior of the | activity log viewer. You can specify the route prefix, the middleware | to use, and the controller to handle the activity log requests. | */ 'log_viewer' => [ 'prefix' => 'activity-logs', 'middleware' => ['web', 'auth'], 'controller' => App\Http\Controllers\ActivityLogController::class, 'view_enabled' => true, ], ];
Environment Variables
Set the following in your .env file if you need to customize the database connection and data retention period:
ACTIVITY_LOG_CONNECTION=mysql ACTIVITY_LOG_RETENTION_DAYS=365
Running Migrations
Run the migrations to create the necessary tables in your database:
php artisan migrate
This will create an activity_logs table or collection in the specified database connection.
Usage
Logging Activities
To log an activity, use the ActivityLog facade:
use LaithAlEnooz\ActivityLog\Facades\ActivityLog; // Basic log ActivityLog::log('user_login', 'User logged in', $user, $user); // Log with properties ActivityLog::log('user_profile_update', 'User updated profile', $user, $user, [ 'changed_fields' => ['name', 'email'], ]); // Log without subject or causer ActivityLog::log('system_maintenance', 'System maintenance scheduled');
- Parameters:
logName(string): A name for the log entry.description(string): A description of the activity.subject(Model|null): The subject model of the activity.causer(Model|null): The causer (usually the user) of the activity.properties(array): Additional data to store with the log.logLevel(string|null): The log level (overrides default if provided).
Using Custom Log Levels
You can specify custom log levels when logging activities:
// Using the 'warning' log level ActivityLog::log('low_disk_space', 'Disk space is running low', null, null, [], 'warning'); // Using convenience methods ActivityLog::info('cache_cleared', 'Application cache cleared'); ActivityLog::warning('high_memory_usage', 'Memory usage is above threshold'); ActivityLog::error('system_failure', 'Critical system failure occurred');
Logging HTTP Requests
To enable HTTP request logging:
-
Register the Middleware
Add the
LogHttpRequestsmiddleware to yourapp/Http/Kernel.php:protected $middlewareGroups = [ 'web' => [ // Other middleware... \App\Http\Middleware\LogHttpRequests::class, ], 'api' => [ // Other middleware... \App\Http\Middleware\LogHttpRequests::class, ], ];
-
Enable Request Logging in Configuration
Set
log_http_requeststotrueinconfig/activitylog.php:'log_http_requests' => true,Optionally, set the log level for HTTP requests:
'http_request_log_level' => 'info',
Note: The middleware captures the request and response, excluding sensitive data like passwords.
Automatic Model Event Logging
You can automatically log model events (created, updated, deleted) by using the LogsActivity trait in your models.
1. Use the Trait in Your Model
use Illuminate\Database\Eloquent\Model; use LaithAlEnooz\ActivityLog\Traits\LogsActivity; class Post extends Model { use LogsActivity; // Your model code... }
2. Customize Events and Log Levels (Optional)
By default, the trait logs created, updated, and deleted events with default log levels. To customize, override the methods in your model:
class Post extends Model { use LogsActivity; protected static function getModelEventsToLog() { return ['created', 'deleted']; // Only log created and deleted events } protected static function getLogLevelForEvent($event) { $levels = [ 'created' => 'info', 'deleted' => 'warning', ]; return $levels[$event] ?? 'info'; } }
Retrieving Logs
You can retrieve logs using the ActivityLog model:
use LaithAlEnooz\ActivityLog\Models\ActivityLog; $logs = ActivityLog::where('log_level', 'error')->get(); foreach ($logs as $log) { echo $log->description; // Retrieve the causer and subject $causer = $log->causer; // Eloquent model or null $subject = $log->subject; // Eloquent model or null }
You can also use Eloquent relationships to get activities related to a specific model:
// In your User model use Illuminate\Database\Eloquent\Relations\MorphMany; class User extends Authenticatable { // ... public function activities(): MorphMany { return $this->morphMany(ActivityLog::class, 'causer'); } } // Usage $user = User::find(1); $activities = $user->activities;
Data Retention
Configuring Data Retention
You can configure how long activity logs should be retained before being pruned. This is set in the config/activitylog.php configuration file:
'data_retention_days' => env('ACTIVITY_LOG_RETENTION_DAYS', 365),
- Default: 365 days.
- Disable Automatic Pruning: Set
'data_retention_days' => null.
Pruning Old Logs
The package provides an Artisan command to prune old activity logs:
php artisan activitylog:prune
Options:
--days=: Specify the number of days to retain logs. Overrides the configuration.
Example:
php artisan activitylog:prune --days=30
This command will delete all activity logs older than the specified number of days.
Scheduling Automatic Pruning
To automate the pruning process, schedule the command in your application's console kernel:
// app/Console/Kernel.php protected function schedule(Schedule $schedule) { // Prune activity logs daily $schedule->command('activitylog:prune')->daily(); }
This will run the pruning command every day at midnight, deleting logs older than the retention period specified in your configuration.
Advanced Usage
Customizing the Activity Logger
You can customize the ActivityLogger by extending it or modifying the configuration.
Extending ActivityLogger:
namespace App\Services; use LaithAlEnooz\ActivityLog\Logger\ActivityLogger as BaseActivityLogger; class ActivityLogger extends BaseActivityLogger { public function customMethod() { // Your custom logic } }
Binding Custom Logger in Service Container:
// In a service provider $this->app->singleton(\LaithAlEnooz\ActivityLog\Logger\ActivityLogger::class, function ($app) { return new \App\Services\ActivityLogger( $app->make(\LaithAlEnooz\ActivityLog\Contracts\ActivityLogRepositoryInterface::class), config('activitylog.default_log_level', 'info') ); });
Extending the Package
You can extend the package by implementing custom repositories, adding new middleware, or creating new traits.
Implementing a Custom Repository:
-
Create a New Repository Class
namespace App\Repositories; use LaithAlEnooz\ActivityLog\Contracts\ActivityLogRepositoryInterface; class CustomActivityLogRepository implements ActivityLogRepositoryInterface { public function log(array $data) { // Your custom implementation } public function getLogs(array $criteria = []) { // Your custom implementation } public function prune($cutoffDate) { // Your custom implementation } }
-
Bind the Custom Repository
// In a service provider $this->app->bind( \LaithAlEnooz\ActivityLog\Contracts\ActivityLogRepositoryInterface::class, \App\Repositories\CustomActivityLogRepository::class );
Testing
To run tests, set up PHPUnit in your Laravel application and write test cases in the tests directory of your application.
Example Test Case:
namespace Tests\Feature; use Tests\TestCase; use LaithAlEnooz\ActivityLog\Facades\ActivityLog; use LaithAlEnooz\ActivityLog\Models\ActivityLog as ActivityLogModel; use Illuminate\Foundation\Testing\RefreshDatabase; class ActivityLogTest extends TestCase { use RefreshDatabase; public function test_activity_is_logged() { ActivityLog::log('test_log', 'This is a test log'); $this->assertDatabaseHas('activity_logs', [ 'log_name' => 'test_log', 'description' => 'This is a test log', ]); } public function test_prune_command_deletes_old_logs() { // Create logs with different timestamps ActivityLogModel::factory()->create(['created_at' => now()->subDays(10)]); ActivityLogModel::factory()->create(['created_at' => now()->subDays(5)]); ActivityLogModel::factory()->create(['created_at' => now()]); // Run the prune command with a retention period of 7 days $this->artisan('activitylog:prune', ['--days' => 7]); // Assert that logs older than 7 days are deleted $this->assertDatabaseCount('activity_logs', 2); } }
Contributing
Contributions are welcome! Please follow these steps:
-
Fork the repository.
-
Create a new branch for your feature or bug fix:
git checkout -b feature/your-feature-name
-
Make your changes and commit them:
git commit -m "Add your message here" -
Push to your forked repository:
git push origin feature/your-feature-name
-
Create a pull request against the
mainbranch.
Please ensure all tests pass and adhere to the PSR coding standards.
License
This package is open-sourced software licensed under the MIT license.
Maintained by Laith Al Enooz
If you encounter any issues or have suggestions for improvements, please open an issue on GitHub.
Happy logging!