DEV Community

Ed Legaspi
Ed Legaspi

Posted on

I Got Tired of Rewriting Audit Logs in Spring Boot — So I Built nerv-audit

Every backend system eventually hits this moment:

“Who changed this record?”
“What was the previous value?”
“When did it happen?”

Simple questions… until you actually need answers in production.


⚠️ Note: The core module is commercial, but you can explore the public modules and examples here:
👉 https://github.com/czetsuyatech/nerv-audit
👉 https://github.com/czetsuyatech/nerv-examples


The Problem

In most of my Spring Boot projects, I relied on Hibernate Envers.

It works—but in real systems, it starts to hurt:

  • You repeat the same setup across services
  • Audit queries are hard to read and maintain
  • Business-level audit logic gets scattered
  • Small mistakes become painful in production

After a few projects, I realized:

I wasn’t building features anymore—I was rebuilding audit infrastructure.


What I Actually Wanted

Not a replacement for Envers.

Just something that:

  • Standardizes audit handling
  • Reduces boilerplate
  • Makes queries readable
  • Works consistently across projects

So I Built nerv-audit

nerv-audit is a lightweight layer on top of Envers that focuses on developer experience.

Instead of wiring everything manually, you get a cleaner way to work with audit data.


Example

Without nerv-audit

You end up dealing with low-level Envers APIs and custom query logic.

With nerv-audit

service.getVerticalAudits(entity, criteria);
Enter fullscreen mode Exit fullscreen mode

That’s it.


Want to see how it's implemented in a real project?
👉 https://github.com/czetsuyatech/nerv-audit
👉 https://github.com/czetsuyatech/nerv-examples


What It Improves

1. Consistent Audit Handling

Define audit behavior once, reuse everywhere.

@AuditedEntity
public class Order {
    private String status;
}
Enter fullscreen mode Exit fullscreen mode

2. Cleaner Queries

No more complex Envers query construction.

You focus on:

  • What changed
  • When it changed

Not how to retrieve it.


3. Less Repetition

Across projects, the pattern is always the same.

nerv-audit abstracts that pattern so you don’t rewrite it every time.


Why I Built This

This came from real production work:

  • Multiple systems
  • Repeated audit requirements
  • Real incidents where audit data mattered

At some point, it made more sense to abstract the solution than keep rebuilding it.


About the Model (Transparency)

nerv-audit is not fully open-source.

  • There is a free tier you can use
  • Some advanced capabilities are part of a paid core

⚠️ Note: The core module is commercial, but you can explore the public modules and examples here:
👉 https://github.com/czetsuyatech/nerv-audit
👉 https://github.com/czetsuyatech/nerv-examples

I chose this approach to:

  • Keep the project sustainable
  • Continue improving it over time
  • Focus on real-world use cases

Who This Is For

This might be useful if you:

  • Build Spring Boot applications
  • Use Hibernate Envers (or plan to)
  • Want a cleaner way to handle audit logs

I’d Like Your Input

How are you handling audit logs today?

  • Pure Envers?
  • Custom implementation?
  • Something else?

I’m especially interested in:

  • Pain points
  • Query challenges
  • Scaling issues

If you're working with Envers, try it out and let me know what breaks—or what works better.


🔗 Resources

Top comments (5)

Collapse
 
buildbasekit profile image
buildbasekit

This hits a very real pain.

Audit logs are one of those things that start simple with Envers… and then turn into repeated setup, messy queries, and scattered logic across services.

I’ve seen the same pattern with auth and multi-tenancy too — every project ends up rebuilding the same backend foundation.

Feels like we’re slowly moving toward extracting these “repeatable backend layers” into reusable modules instead of rewriting them each time.

Curious — did you consider going beyond Envers and owning the full audit pipeline, or was keeping it as a layer on top a deliberate choice?

Collapse
 
czetsuya profile image
Ed Legaspi

Totally agree — it really does feel like a “repeatable backend layer.”

In my case, it came from working on multiple services and rebuilding the same audit setup every time — Envers config, revision handling, exposing history, etc. After a while, it just felt like boilerplate that should be standardized.

I haven’t gone beyond Hibernate Envers, and that’s intentional (for now). It already solves the hard parts well, and I wanted to keep nerv-audit focused on simplifying usage rather than rebuilding the whole audit system.

That said, I do think the next step could be a more decoupled, cross-service audit pipeline — but that’s a much bigger shift than what I’m aiming for today.

Collapse
 
buildbasekit profile image
buildbasekit

Yeah, that makes sense. Envers already solves the hard problem, so wrapping it for better DX is a smart first step.

That “repeatable backend layer” idea keeps showing up. Audit, auth, multi-tenancy… same pattern everywhere.

The cross-service audit pipeline is interesting, but yeah, that’s a different level. Feels like that only starts to matter once teams hit scale or need centralized visibility.

Right now, simplifying usage inside a service probably gives the highest ROI.

Curious, have you seen any friction when teams try to standardize this across multiple services, or does nerv-audit stay mostly per-service?

Thread Thread
 
czetsuya profile image
Ed Legaspi

Great point—and that’s been my experience as well.

Across most enterprise projects I’ve worked on, auditing is implemented per service, and in many cases (especially in payments or regulated systems), that’s actually a requirement. nerv-audit follows the same model: keeping audit trails close to the service boundary ensures better isolation, compliance, and control.

That said, I do think there’s an interesting opportunity on the centralization side. Tools like New Relic, Datadog, and Dynatrace show how powerful a unified view can be. In theory, a similar approach could be applied to audit data—aggregating insights across services while still keeping writes local.

From an architecture standpoint, nerv-audit already has most of the underlying pieces. What’s missing is more of an intuitive UI and aggregation layer on top. Definitely something I’m considering as a future direction—so I appreciate the question.

For now though, my focus is on building out a set of repeatable backend modules (audit, exception handling, messaging, security, etc.). The idea is to provide consistent patterns across services, while still allowing each service to evolve independently—especially in environments where multiple teams are contributing.

Thread Thread
 
buildbasekit profile image
buildbasekit

That aggregation + UI layer is where things get really interesting.

Feels like audit is following the same path as logs and metrics — local writes, centralized visibility.

If you ever explore that direction, would love to see how you handle:

  • cross-service querying
  • schema consistency
  • and keeping it simple for teams

Feels like that’s where this could go from useful → essential.