mblsolutions/audit-logging
mblsolutions/audit-logging provides simple audit trails for Laravel apps, capturing model create, update, and delete events with changed values and user attribution. Helps teams review activity, debug issues, and support compliance.
The v2.1.0 release is an additive feature drop on top of v2.0.1 — a new cloudwatch audit driver (PR #16, first contribution from @HasanTechie). There are no breaking changes, so upgrading is a composer update mblsolutions/audit-logging away.
Start here:
composer require mblsolutions/audit-logging, then publish the config (php artisan vendor:publish --tag=...) and migrations if you intend to use the database driver. Run php artisan migrate.cloudwatch entry lives here alongside whatever drivers you already use.single/file or database so you can eyeball records. Production → cloudwatch if you already centralise logs in AWS, or database if auditors query in-app.Invoice, User, or Permission — and make a change. Confirm a record appears before wiring it across the codebase.First use case worth shipping: audit User and any model that touches money or permissions, and record who changed what, when, and from where. That single slice proves the plumbing end-to-end.
Trait-per-model for CRUD auditing. Apply the package's audit trait to models whose lifecycle matters and let it capture created/updated/deleted with before/after payloads. Keep the audited model set small and intentional — auditing everything is how you end up with a log store nobody reads and a bill nobody expected.
Explicit logging for domain events. For things that aren't a row change — "user exported the payroll report", "admin impersonated a customer", "API key rotated" — call the logger directly from the action/service class rather than the controller, so the audit entry sits next to the business rule that justified it.
CloudWatch as the production sink. With v2.1.0 you can point the package at CloudWatch Logs. Practically this means: configure AWS credentials/region via your normal Laravel AWS setup (env-driven, not hardcoded), set the log group and stream in the package config, and let your existing CloudWatch retention policies and alarms apply to audit data. The win is that audit records land next to your application logs and inherit your existing AWS access controls, IAM boundaries, and retention tooling — no separate audit database to back up.
Use the database driver when humans need to query it. Compliance reviewers, support staff, and "who changed this record?" investigations are far easier against a table with a UI than against CloudWatch Insights. A common split: database for recent, queryable, in-app history; cloudwatch (or an S3 export) for long-term retention and tamper-resistant archiving.
Enrich every entry with request context. User ID, tenant ID, IP, user agent, request/correlation ID, and the originating job or command name. Do this once in a shared resolver or middleware so entries are consistent and you never debug an audit row that says "system changed it".
Queue the writes. Audit logging should never be the reason a request fails or slows down. If the package supports queued persistence, enable it and run a dedicated queue worker — especially important for CloudWatch, where the write is a network call to AWS.
Test against a fake/in-memory driver. Assert in feature tests that POST /invoices/{id} produced exactly one audit entry with the expected actor and diff. Keep those assertions on the package's public API, not on raw DB rows, so driver swaps don't break your suite.
logs:CreateLogGroup, logs:CreateLogStream, and logs:PutLogEvents on the target group/stream. A missing permission typically surfaces as a swallowed or queued failure — check the failed-jobs table and storage/logs before assuming the package is broken.php artisan config:clear (and redeploy if cached in CI). A stale config cache is the classic "my new driver isn't being used" cause.How can I help you explore Laravel packages today?