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

Elastic Audit Laravel Package

tsitsishvili/elastic-audit

A Laravel package for Elasticsearch-backed audit logging. Capture Eloquent model changes and application events, store structured audit records in Elasticsearch, and search or analyze activity trails at scale with a simple, scalable setup.

View on GitHub
Deep Wiki
Context7

Getting Started

tsitsishvili/elastic-audit writes your Laravel audit trail into Elasticsearch instead of a relational table — you get Kibana dashboards, full-text search over old events, and retention handled by index lifecycle management rather than DELETE queries.

Minimal path from zero to first audited event:

  1. composer require tsitsishvili/elastic-audit
  2. Publish the config and review it before touching any model:
    php artisan vendor:publish --tag=elastic-audit-config
    
    Set your hosts/credentials (ELASTIC_AUDIT_HOSTS, user/password or API key) and the index name/prefix. Point it at a non-production cluster first — an audit package writing to the wrong index in prod is a bad first day.
  3. Create the index and mapping (schema must exist before documents arrive, otherwise Elasticsearch infers types and you get text where you wanted keyword):
    php artisan list elastic
    
    Run whichever index/mapping/health commands the package exposes, then confirm with curl localhost:9200/_cat/indices?v.
  4. Pick one model and one behaviour. The best first use case is a security-relevant state change, e.g. User login, role change, or an Order status transition — something you'd actually want to query later ("who changed this order to refunded, and when?").
  5. Trigger it, then verify the document exists and the field types are what you expect: GET <index>/_search or a Kibana Discover view.

Where to look first: config/elastic-audit.php (the whole package's behaviour is driven from there), then the package's trait/observer entry point that you attach to models. Read the mapping definition before you write code — it dictates what you can and can't change later.

Implementation Patterns

Model-driven auditing. Attach the package's trait/observer to models you want tracked, and keep the audited field list explicit rather than "all attributes". Auditing everything means every unrelated column addition silently changes your document shape, and it leaks sensitive fields (tokens, password hashes, PII) into a searchable index.

Manual, event-shaped writes. For things that aren't simple CRUD — a refund, a permission grant, a webhook received — call the audit API directly with a semantic event name (order.refunded, auth.login.failed) plus a small, stable payload. Free-form payloads are the number one cause of mapping conflicts later.

Always queue the write. Elasticsearch is a network dependency; a 300ms round-trip inside a request or inside a saving observer is a latency tax on every write. Push audit writes onto a queue worker. The trade-off is real: queued audits can be lost on worker crash or queue backlog, so pair queueing with the v4.2 failure observability work below.

Source identity (new in 4.2). Use it to distinguish where an audit originated — HTTP request, artisan command, queue job, seeder. This matters more than it sounds: without it, a nightly reconciliation job and a real user look identical in Kibana, and your "who did this" queries are wrong. Where the source is a console/job context there is no request, so expect nulls for IP/user-agent; don't build dashboards that assume those fields are always populated.

Failure observability (new in 4.2). Wire audit write failures into something you actually watch. The correct posture is: an audit failure must never break the user's request, but it must never be silent either. Route failures to your log/error tracker and, ideally, alert on sustained failure — a silently dead audit pipeline you only discover during an incident review is the classic failure mode of this whole package category.

Schema health checks (new in 4.2). Put the health-check command in your scheduler (daily is plenty) and in CI/CD after deploy. It catches mapping drift, missing indices, and cluster connectivity problems before they become a compliance gap.

Retention via ILM, not code. Define index lifecycle policy on the cluster (hot/warm/delete) rather than writing pruning logic in Laravel. Daily or monthly indices with a prefix are the standard pattern; if you need per-tenant separation, be deliberate — index-per-tenant multiplies shard count fast.

Integration tips. Inject the audit service rather than calling facades deep inside domain code, so it's swappable in tests. In tests, disable the package or point it at a fake — unit tests should not require a live cluster. For reads, use the package/Kibana for investigation and keep your operational dashboards out of the request path.

Gotchas and Tips

  • Dual-write is not transactional. Your DB commit and the Elasticsearch document are two separate systems. If the DB rolls back after you queued the audit, you've logged an event that never happened. Fire audits from an after_commit hook or an event dispatched post-commit, and accept that some audits will be missing rather than wrong-and-duplicated.
  • Queued failure is invisible by default. QUEUE_CONNECTION=sync in dev hides every problem you'll hit in prod. Test with a real worker and kill the cluster mid-run to see what v4.2's failure observability actually tells you.
  • Mapping is a one-way door. Changing a field from text to keyword (or long to object) requires a reindex. Nail the mapping on day one and treat payload changes as schema changes — review them.
  • Refresh interval delays. Documents aren't searchable for ~1s by default; tests that write then immediately search will flake. Force a refresh in test helpers or poll.
  • Guzzle bump in 4.2. The release updates the Guzzle constraint. If your app pins Guzzle or an older elasticsearch-php client, run composer update --dry-run before deploying — dependency conflicts here surface as confusing runtime errors, not install failures.
  • Timezone and clock skew. Store UTC consistently; mixed app timezone vs. cluster assumptions make timeline reconstruction painful, which defeats the point.
  • Redaction is your job. Add an explicit deny-list for password, token, secret, authorization, card data. An audit index is often readable by more people than your database.
  • 4.2.0 upgrade looks safe. Minor version, no breaking changes or deprecations signalled in the notes (new features + dependency bumps only). Standard composer update and re-run the schema health check afterwards; nothing here implies config changes are required.
  • Extension points to reach for first: the config file (index, queue, redaction, hosts), custom event/payload shaping for domain events, and the failure hook — those three cover 90% of real-world customisation without forking.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
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