Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Activity Log Laravel Package

givanov95/laravel-activity-log

Laravel package for recording activity logs and audit trails. Track user actions and model changes to see who did what and when, with a simple, configurable logging layer for your application.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. This is an in-application audit/activity log that writes into the same relational database as the host app, on the caller's connection and inside the caller's transaction. That is the right default for a Laravel monolith or modular monolith: entries commit or roll back with the business change, no message broker, no outbox, no second datastore to operate. The ActivityLog::record() builder is expressive enough to represent the audit cases most TPMs actually get asked for by compliance and support: who did it (Actor::user/model/guest/system, with role and a stored label), what it was done to (subject with stored label), what else was touched (related models), what changed (Changes), and free-form properties. The stored-label design is the important detail — entries stay readable after the subject is renamed or deleted, which is exactly where naive subject_id-only audit tables fail in production.

Integration feasibility. Low-to-moderate. There is no migration/ETL: it is a new table plus a handful of call sites. The Changes::fromModel() helper removes the tedious part of writing entries by hand (attribute diffing), so instrumenting a first workflow is hours, not weeks. The friction is not technical but organisational: someone must decide which actions are auditable and enforce it in code review, otherwise coverage drifts and the log becomes untrustworthy precisely where it matters (permissions, billing, exports, deletions).

Technical risk. Three items deserve attention before sign-off:

  1. Laravel 11 is a second-class citizen. Changes::fromModel() throws LogicException on Laravel 11 because it needs Model::getPrevious() from Laravel 12; the documented fallback is snapshot()->diff(). This is a runtime failure, not a compile-time one, so it will surface as a 500 in whichever flow first exercises it. If the fleet is mixed 11/12, this must be a written rule with a lint/test guard, not tribal knowledge.
  2. Synchronous in-transaction writes couple audit durability to business rollback. Correct for consistency, but it means a failed business transaction produces no audit trail — including for attempts compliance may want recorded — and a long-running transaction carries the audit insert with it. Conversely, audit write failures can now abort the business operation. That trade-off must be an explicit decision, not an accident.
  3. PII and retention are now code concerns. scrub(), the hidden/encrypted-attribute masking, and activity-log:prune are genuinely useful, but retention_days is off by default and masking only covers attributes you remembered to configure. An unmasked or unpruned log is a GDPR liability sitting in your primary database. This is the package's largest organisational risk and it has a default that fails open.

Key questions.

  • Which Laravel versions are in production, and who owns the Laravel 11 fallback rule?
  • What is the retention period per data class, and who signs it off — legal, security, or the data owner?
  • Is properties allowed to hold PII at all, or is it contractually free of it?
  • Where do entries go if the host transaction rolls back — is "no trail on failure" acceptable for the flows we are instrumenting?
  • Who reads this table? If it is support and compliance, we need query patterns and access control, not just rows.
  • Is scrub() an erasure mechanism we are willing to defend as satisfying a data-subject request?

Integration Approach

Stack fit. Assumes Laravel with Eloquent and a relational database; the append-only ActivityLogEntry model and the scope set (inScope, forSubject, involving, byActor, byRole, action, between) map cleanly onto the questions support and compliance ask ("what happened to this account", "what did this admin do last week"). Batch UUID per request or job gives free correlation across entries produced by one operation — valuable for reconstructing a multi-step workflow in an incident review. No queue, no cache dependency, no external service: it fits an existing Laravel deployment without new infrastructure, which is the main reason to prefer it over an event-stream or warehouse-based audit approach at this stage.

Migration path. Greenfield table — generate and run the migration, no backfill. Historical auditability is not provided; the log starts at deployment. If prior history exists in application tables (updated_at, status columns, existing log tables), plan a one-off export as a separate exercise rather than trying to synthesise entries. Do not pretend the new log covers the pre-deployment period in any compliance statement.

Compatibility. Target Laravel 12 as the primary path so Changes::fromModel() is available. On Laravel 11, standardise on snapshot()->diff() and add a static check or test that fails if fromModel() appears in code — the exception is only raised at runtime in the affected flow, which is the worst time to find it. Verify the encrypted-cast masking behaviour against the actual casts in use before relying on it. Confirm the database supports the indexing the scopes need at expected volume.

Sequencing.

  1. Ship migration and model, with no call sites, to validate schema and indexes in staging.
  2. Enable retention (retention_days) and the prune schedule before the first entry is written — the default is off, and turning it on later means retrofitting a policy onto accumulated data.
  3. Define and document the masking configuration (hidden and configured attributes) and the properties PII rule up front, not after the first incident.
  4. Instrument one high-value, low-blast-radius flow end to end, including actor resolution — do not rely on the default resolver implicitly; confirm ->by() is used wherever the signed-in user is not the true actor (jobs, console commands, impersonation, webhooks).
  5. Add the access-control and query story for readers before widening coverage.
  6. Roll out to remaining flows in tiers, with a code-review checklist item for new write paths.

Operational Impact

Maintenance. Small and self-contained: one table, one model, one command, one config file. The maintenance burden is in the policy surface, not the code — retention, masking, and actor attribution need an owner who reviews them when the schema or the org chart changes. Treat the config as a governed artefact, not an app default.

Support. High leverage. Stored actor and subject labels mean support can answer "who changed this and when" without joins to mutable tables or reconstructing state. The scopes cover the majority of ad-hoc queries, which reduces the temptation to grant broad database access to support staff. Batch UUID is the difference between a support ticket resolved in minutes and one escalated to engineering.

Scaling. Audit tables grow monotonically and faster than the entities they describe; append-only is good for integrity and unforgiving for volume. Mitigations exist in the package (retention, prune) but are opt-in. Expect write amplification on hot paths — every instrumented write adds at least one row and one index entry within the caller's transaction. Watch for: table and index bloat, properties/changes JSON growth, and long-running reporting queries competing with OLTP traffic. Plan retention and, if volume warrants, an archival destination before the table reaches a size where pruning becomes a maintenance window.

Failure modes.

  • Silent under-coverage — a new write path forgets to log; the trail looks complete but is not. Mitigate with review checklist plus periodic spot audits.
  • Runtime LogicException on Laravel 11 in the first flow to call Changes::fromModel().
  • Lost entries on rollback — intentional, but must be understood; attempted-but-failed actions leave no trace.
  • Business operation failure caused by audit write failure — same transaction, no isolation between audit and core writes.
  • Unmasked PII reaching the table by omission from hidden/configured attributes.
  • Unbounded growth because retention_days ships off and nobody owns it.
  • scrub() over- or under-reach — verify in staging that anonymisation hits exactly the subject's fields and the actor IP, and that it satisfies the erasure obligation you claim it does.

Ramp-up. A developer can write a first entry in an hour; writing a correct one — right actor, right scope, right masking, right changes semantics — takes a review cycle. Budget half a day of enablement covering the actor resolver, the Laravel 11 fallback, masking configuration, and the rollback semantics, plus a written standard for what must be logged. The failure mode to design against is a team that adopts the API quickly, skips the policy decisions, and discovers both the retention gap and the PII gap at the first audit.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource