Installation
composer require dmp/audit-request-bundle
Register the bundle in config/app.php under providers:
Dmp\AuditRequestBundle\AuditRequestBundle::class,
First Use Case Annotate a controller method to log audit requests:
use Dmp\AuditRequestBundle\Annotation\AuditableRequest;
class UserController extends Controller
{
#[AuditableRequest(referenceType: 'user', referenceIdentifier: 'user_id')]
public function update(Request $request, $user_id)
{
// Your logic here
}
}
Configuration
Check config/audit_request.php for default settings (e.g., storage driver, log format). Override as needed:
'storage' => [
'driver' => 'database', // or 'log', 'custom'
'table' => 'audit_requests',
],
Verify
Trigger the annotated endpoint and inspect the configured storage (e.g., audit_requests table or Laravel logs).
Use dynamic values for referenceIdentifier via closures:
#[AuditableRequest(
referenceType: 'order',
referenceIdentifier: fn(Request $request) => $request->route('order_id')
)]
public function processOrder(Request $request)
{
// ...
}
Skip auditing for specific cases (e.g., admin users):
#[AuditableRequest(referenceType: 'post', referenceIdentifier: 'post_id')]
public function delete(Request $request, $post_id)
{
if ($request->user()->isAdmin()) {
return response()->json(['message' => 'Skipped audit for admin']);
}
// Audit will run automatically
}
Extend the bundle to support custom storage (e.g., Elasticsearch):
// config/audit_request.php
'storage' => [
'driver' => 'custom',
'handler' => \App\Services\AuditHandler::class,
],
Implement Dmp\AuditRequestBundle\Contracts\AuditHandlerInterface.
Use the bundle’s middleware to audit requests globally:
// app/Http/Kernel.php
protected $middlewareGroups = [
'web' => [
// ...
\Dmp\AuditRequestBundle\Http\Middleware\AuditRequestMiddleware::class,
],
];
For bulk operations (e.g., API imports), audit at the start/end:
#[AuditableRequest(referenceType: 'import', referenceIdentifier: 'batch_123')]
public function import(Request $request)
{
// Process bulk data...
AuditRequest::log('import_completed', ['status' => 'success']);
}
event(new AuditLogged($auditData));
referenceIdentifier is valid before auditing.AuditHandler in tests:
$this->app->instance(
\Dmp\AuditRequestBundle\Contracts\AuditHandlerInterface::class,
Mockery::mock()
);
Annotation Caching
php artisan cache:clear
#[AuditableRequest] on classes (not just methods) if caching issues persist.Circular Dependencies
referenceIdentifier closures (e.g., calling the same method recursively).Database Schema Mismatch
database driver, ensure the audit_requests table exists. Run:
php artisan vendor:publish --provider="Dmp\AuditRequestBundle\AuditRequestBundle" --tag="migrations"
php artisan migrate
Performance Overhead
#[AuditableRequest(enabled: false)]
Reference Identifier Serialization
referenceIdentifier may not serialize well. Use strings or simple types.Log Output: Enable debug mode in config/audit_request.php:
'debug' => env('APP_DEBUG', false),
Logs will appear in storage/logs/laravel.log.
Middleware Debugging: Temporarily disable the middleware to isolate issues:
// app/Http/Kernel.php
'web' => [
// \Dmp\AuditRequestBundle\Http\Middleware\AuditRequestMiddleware::class,
],
Custom Attributes Extend the annotation to support additional fields:
#[AuditableRequest(
referenceType: 'user',
referenceIdentifier: '123',
metadata: ['action' => 'update', 'ip' => $request->ip()]
)]
Pre/Post Audit Hooks
Bind to the audit.request event in EventServiceProvider:
protected $listen = [
'Dmp\AuditRequestBundle\Events\AuditRequestEvent' => [
\App\Listeners\LogAuditToExternalService::class,
],
];
Dynamic Reference Types
Override the getReferenceType() method in a custom handler to compute types dynamically.
Rate Limiting Combine with Laravel’s rate limiting to prevent audit log spam:
Route::middleware(['throttle:60,1'])->group(function () {
// Auditable routes
});
How can I help you explore Laravel packages today?