manasbala/doctrine-log-bundle
A Symfony bundle for audit logging Doctrine entity changes. It captures create, update, and delete events and stores a change history for traceability, integrating through Doctrine event listeners with configurable logging options.
Architecture fit — poor for a stock Laravel stack. This is not a Laravel package; it is a Symfony bundle built against Doctrine ORM. Its composition assumes a Symfony kernel: a Bundle subclass, a DependencyInjection extension, YAML/XML service definitions, and compiler passes. The actual value — an audit/change-log listener bound to Doctrine's onFlush/postFlush events plus a log entity — is buried under framework plumbing that Laravel will never invoke. Laravel's default persistence layer is Eloquent, not Doctrine, so there is no event dispatcher to hook into and no UnitOfWork to inspect. Integration therefore means extraction, not adoption: copy the listener and entity classes, discard the bundle layer, and re-register listeners manually.
Integration feasibility — low, and conditional on a Doctrine commitment. Two viable paths exist. (a) Introduce Doctrine ORM into Laravel via laravel-doctrine/orm, then wire this package's listeners into the EntityManager's EventManager from a service provider. This works but imports a second ORM alongside Eloquent, which is a large architectural tax for an audit-log feature. (b) Fork the listener logic into an internal package with a Laravel service provider and config file — smaller blast radius, but you now own ~all of the code that mattered. Neither path is an afternoon's work; budget a spike to confirm the change-set shape and storage model before committing.
Technical risk — high, dominated by single-maintainer dependency and Doctrine version exposure. The 1.0.7 release ("added support for jms serializer 4") is a dependency-compatibility bump, not a functional change. It is weakly positive — it shows the maintainer still touches the repository, which softens the pure-abandonment read from the earlier February 2022 last-release date — but it does not address any of the material risks. There is still no security response path, no compatibility work for Doctrine ORM 3.x / DBAL 4, and no evidence of production usage anywhere. The release also reveals a dependency we had not accounted for: the package pulls in JMSSerializer, which means the audit payload is produced through a serializer abstraction rather than hand-rolled array mapping. That is useful evidence for the snapshot-vs-diff question below, and it is an extra transitive dependency you inherit and must keep patched if you fork. The opportunity: 9.2 score remains misleading in isolation — it reflects whitespace in the audit-logging category, not the viability of this artifact. Combine staleness with the fact that audit logging is a commodity concern with maintained alternatives (DoctrineExtensions Loggable on the Doctrine side; owen-it/laravel-auditing or spatie/laravel-activitylog on the Eloquent side), and the build-vs-buy-vs-adopt calculus still tilts hard away from this package.
Key questions to resolve before any commitment:
DQL UPDATE/DELETE, which bypasses the unit of work entirely?Stack fit. Only sensible if the target application already runs Doctrine ORM — i.e., a Laravel app using laravel-doctrine/orm as a primary or secondary persistence layer. On a pure Eloquent codebase, do not force this in; the correct TPM recommendation is to evaluate owen-it/laravel-auditing first and treat this repository as reference implementation only.
Migration path (assuming Doctrine is present):
Bundle class, DI extension, and Symfony service YAML — retain only listeners, the audit entity, and any mapping metadata.EventManager in a DatabaseServiceProvider or a dedicated AuditServiceProvider, gated behind a config flag.config/audit.php file and a typed config object; hard-code sensible defaults rather than porting the full config tree.toArray() normalizer. For an audit trail, replacing it is usually the cheaper long-term call and removes an entire upgrade surface — but confirm the payload shape first, since changing it later invalidates historical rows.Compatibility. Verify PHP version support, Doctrine ORM 2.14+ API surface (OnFlushEventArgs, UnitOfWork::getEntityChangeSet, computeChangeSets), and whether the code references removed Doctrine\Common\Persistence namespaces. Confirm the JMSSerializer 4 constraint resolves against your Laravel/Symfony-component versions — the same Symfony packages Laravel ships may satisfy it at a version you did not choose. Note that Laravel shipping Symfony components is coincidental: the bundle wiring will not activate, and you should not attempt to make it.
Sequencing. Run the fork-and-strip spike first (timeboxed, one engineer, ~3–5 days) to answer the key questions above against a realistic entity model — including a concrete look at what 1.0.7's serializer path actually emits. Only after that does it make sense to design the audit table, decide synchronous vs. queued writes, and schedule the Doctrine adoption decision — which is the real project here, not the logging.
Maintenance. You inherit 100% of upkeep on day one. Expect dependency churn to be the recurring cost: every Doctrine ORM major bump requires validating the listener against changed UnitOfWork internals, and the 1.0.7 release adds a second axis — the serializer — that will major-version independently and drag PHP constraints with it. There is no upstream to defer to, and a single dependency-maintenance commit is not a support commitment. Plan for a named owner and a quarterly compatibility review, or accept that the fork will rot within two years; if you keep JMSSerializer, add it to the same review.
Support. Effectively none. No maintainer responsiveness, no issue history to mine, no community to escalate to. Internal documentation must be written from scratch by reading the source — which is feasible, as the code volume is small, but the Doctrine UnitOfWork semantics and the serializer's proxy/circular-reference behavior are not obvious.
Scaling. Audit logging roughly doubles write volume per mutation and grows storage monotonically. Two scaling hazards are structural: the flush-time listener increases transaction size and lock duration on hot tables, and bulk operations produce very large change sets in a single unit of work, spiking memory. Serializer-based payloads amplify both — snapshot serialization is more expensive per row than a field diff. Mitigations — async/queued audit writes, table partitioning, TTL or archival to cold storage — must be designed in, not retrofitted. If the listener writes inside the business transaction, throughput on write-heavy paths will degrade measurably; benchmark before rollout.
Failure modes to instrument explicitly:
DQL UPDATE/DELETE and raw SQL produce no audit trail at all.Ramp-up. Low line count, but a real knowledge cliff: the team needs working fluency in Doctrine's change-tracking model (UnitOfWork, change sets, flush lifecycle) to debug this meaningfully, plus enough serializer familiarity to diagnose bad payloads. An Eloquent-native team should assume 2–3 weeks to first competent modification. Factor that into the build-vs-buy decision — the maintained Eloquent auditing packages require days, not weeks, and carry a support community this repository does not.
How can I help you explore Laravel packages today?