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
Elasticsearch Audit Bundle

Elasticsearch Audit Bundle Laravel Package

borsche/elasticsearch-audit-bundle

A Symfony bundle that records who changed what into Elasticsearch: Doctrine entities audited automatically, custom domain actions logged on demand, small changes coalesced into one record, async writes via Messenger, and a filterable read API for searchable audit history.

View on GitHub
Deep Wiki
Context7

Symfony bundle that records who changed what in your application into Elasticsearch: automatic Doctrine entity auditing, arbitrary domain events, coalescing of many small changes into one record, async writes through Messenger, and a filterable read API.

Frequently asked questions about Elasticsearch Audit Bundle
Can I use this bundle in a Laravel application with Eloquent models?
No, not as a drop-in. Despite being listed among PHP packages, this is a Symfony bundle built on Doctrine ORM and Symfony Messenger: it hooks the Doctrine unit of work at flush time and writes through a Messenger outbox, while Laravel's defaults are Eloquent and its own queue abstraction. Running it in Laravel would mean adopting Doctrine plus Symfony Messenger wiring, which is an architectural change, not a composer require. If you want a comparable audit approach, the closer alternatives are simplethings/entity-audit and Gedmo Loggable, though both write to SQL and target revision reverting rather than a searchable history.
What are the requirements and how do I install borsche/elasticsearch-audit-bundle?
You need PHP 8.1+, Symfony 6.4, 7.x or 8.x, and Elasticsearch 8 or 9 through elasticsearch/elasticsearch. The client major version must match your cluster's, because a 9.x client is refused by an 8.x cluster, so pin it explicitly, for example composer require elasticsearch/elasticsearch:^8.0 against an 8.x cluster. Beyond the Composer install you must configure an audited Doctrine connection, an outbox table in your own database, Messenger transports, a redaction policy and a failure policy per environment, so budget real integration effort.
How does automatic Doctrine entity auditing work in this bundle?
Entities on an audited Doctrine connection are captured at flush time, which is the only point where a change set is both known and still uncommitted. The record is written transactionally and shipped through a transactional outbox using Symfony Messenger, so the audit record and the data change succeed or fail together. Configuration covers Doctrine column and association mapping, and the audit:check command validates every audit declaration on the connection before anything is flushed.
How do I record audit events that are not entity changes, like a login or a file share?
The bundle exposes an API for arbitrary domain actions alongside automatic entity auditing. That covers the events a SQL audit table cannot express well, such as a call placed, a login refused or a file shared. Records created this way flow through the same writer, outbox and read API as entity changes, so an existing history screen shows them without additional work.
How does coalescing work when an entity is changed many times in one request?
Many small changes can be coalesced into a single audit record instead of one row per write, which keeps the history readable and reduces write volume. Coalescing happens in the writer before records leave for Elasticsearch, so the outbox does not fill with partial noise from a loop of saves. Watch this area across upgrades, because records started leaving the writer as plain values rather than application objects in a patch release.
How are audit writes delivered asynchronously through Symfony Messenger?
Writes use a transactional outbox: the record is stored in a table in your own database in the same transaction as the data change, then a Messenger transport ships it to Elasticsearch. Messenger here uses PhpSerializer, and the bundle includes a defensive warning when the outbox connection is not the audited connection. You must choose a failure policy per environment, log or throw, because that decision determines whether a failed audit write can break the request.
How do I search and filter the audit history this bundle records?
The bundle provides a filterable read API on top of Elasticsearch, which is the point of moving the audit log out of SQL: adding a filter does not require another index on your primary database. Queries such as everything a given user touched last month run against Elasticsearch instead of a report nobody wants to run in production. The read API covers both automatically audited entity changes and custom domain events recorded on demand.
How do I stop sensitive fields from ending up in Elasticsearch?
You configure a redaction policy with redact.fields, max_depth and max_nodes, and you must do it explicitly, because with no redact.fields configured nothing reads the record at all. A confirmed defect present since 1.0.0 had redaction read an object but then hand the object itself to Messenger, whose PhpSerializer serialized every property including private ones into a queue that, with the outbox, is a table in your own database. If you handle PII, credentials or health data, treat earlier versions as a data-exposure incident and assess breach-notification obligations rather than merely scheduling an upgrade.
Can I validate my audit configuration in CI before merging?
Yes. audit:check validates every audit declaration on the connection before anything is flushed, which turns a class of runtime data-loss bugs into a pre-merge CI failure. Wire it in as a required pipeline step so a bad declaration cannot reach production. It is the highest-value, lowest-effort integration point the bundle offers.
Is this bundle production ready and how do I upgrade safely?
Treat it as work in progress: the README states the API is being built up release by release and that on 0.x a ^0.1 constraint will not pull 0.2, so pin the exact minor you tested. Release hygiene is a genuine concern, since a patch release carries a behavioural breaking change where records leave the writer as plain values instead of application objects, so listeners doing instanceof checks or expecting DateTimeInterface will break; read UPGRADE.md before moving. The release notes are also internally inconsistent about which version fixed what, and there are audit-trail integrity defects around AuditTransaction::run() reporting commits that had not happened, so verify transaction behaviour and rollback handling yourself before depending on the history being true.
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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator