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

Doctrine Entity Logger Bundle Laravel Package

kikwik/doctrine-entity-logger-bundle

A Symfony bundle that automatically logs Doctrine entity changes—creates, updates, and deletes—to give you a reliable audit trail. It hooks into Doctrine events and stores a history of modifications, making it easy to track who changed what and when.

View on GitHub
Deep Wiki
Context7

Getting Started

The v0.2.0 release changes logging from implicit/global to opt-in per entity: a model is only logged when it carries the LoggableEntity attribute. That is the first thing to internalize — a model can have the logging trait, be observed, or be listed in config, and still produce no logs unless the attribute is present.

Minimal setup:

  1. Install the package as usual (composer require <vendor>/<package>) and run any publish/migrate steps if the package provides them.
  2. Locate the attribute class first — typically src/Attributes/LoggableEntity.php. Confirm its namespace before annotating models; a wrong import is a silent no-op.
  3. Annotate a single model and trigger an event:
use Vendor\Package\Attributes\LoggableEntity;

#[LoggableEntity]
class Order extends Model
{
    //
}
  1. Create/update an Order and confirm a log entry appears. Then create/update a non-annotated model and confirm it does not — that verifies the new gate is active.

First real use case: pick one high-value entity (Order, Invoice, Subscription), annotate it, and validate the log output before rolling the attribute out across the domain. Do not bulk-annotate everything on day one; the release intentionally narrows what gets logged.

Implementation Patterns

Attribute-first opt-in. Treat #[LoggableEntity] as the switch, not the trait/config. Audit every model you expect to log and add the attribute explicitly. Keep a short internal list/PR checklist of “loggable entities” so the set is intentional rather than accidental.

Migration from pre-0.2.0 behavior. Anything that logged before may now be silent. Grep your codebase and tests for log assertions, then map each expected log source to a model and confirm the attribute is present. This is the primary upgrade task.

Per-concrete-model annotation. PHP class attributes are not inherited. If you annotate a base model, child models will not automatically be treated as loggable. Add the attribute to each concrete model you want logged.

#[LoggableEntity]
class Order extends Model {}

#[LoggableEntity]
class Invoice extends Model {}

Test both sides of the gate. Add a feature test that asserts a log row is created for an annotated model and one that asserts no log row is created for an unannotated model. That second test is what protects you from future attribute-discovery regressions.

$this->assertDatabaseCount('activity_log', 1);
Order::create([...]);

$this->assertDatabaseCount('activity_log', 1); // unchanged
Draft::create([...]); // no attribute

Runtime conditionality. The attribute is static metadata. If you need “log only in production” or “log only for tenant X,” do that in the package config/channel or around the logging call — do not expect the attribute to accept runtime conditions. If the attribute constructor exposes options, inspect it; otherwise keep the gate simple and layer runtime rules elsewhere.

Queue/worker and Octane awareness. Attribute discovery often happens during boot or is cached. After adding the attribute, clear caches and restart long-running workers so the change is picked up.

Gotchas and Tips

  • Silent no-op is the default failure mode. No exception is thrown for an unannotated model; you just get no logs. When debugging “why isn’t this logged?”, check the attribute before checking the trait, observers, or config.
  • Verify the attribute is actually seen with reflection:
$attrs = (new ReflectionClass(Order::class))
    ->getAttributes(\Vendor\Package\Attributes\LoggableEntity::class);

dump($attrs); // empty array means the gate is closed
  • Namespace/import mistakes are easy and invisible. Confirm the use statement matches the package’s attribute class exactly.
  • Inheritance trap. Annotating an abstract/base model does not annotate its children. Add the attribute to each concrete model.
  • Cache invalidation. If the package caches discovered loggable entities, run php artisan optimize:clear (and any package-specific cache command) after adding or removing the attribute.
  • Long-running processes. Queue workers, Octane, and Swoole workers may have resolved the attribute set at boot. Restart them after code changes.
  • Wrong target. Apply the attribute to the class, not a method or property, unless the package explicitly supports other targets.
  • DTOs and non-Eloquent objects. The gate is on the entity being persisted. Annotating a DTO or request object will not cause the underlying model to log.
  • Temporary “log everything” shortcuts. Adding the attribute to a shared base model looks convenient but falls foul of the inheritance caveat. Prefer explicit per-model annotation, or generate the annotations deliberately.
  • Check the attribute constructor. If it accepts arguments (channel, events, guard), that is your extension point for per-entity tuning without touching global config.
  • Upgrade note for reviewers: v0.2.0 is a behavioral narrowing, not a cosmetic release. Treat it as a potentially breaking change for any environment that relied on implicit logging, and call it out in the upgrade notes.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager