REF / WRITING · SOFTWARE

Spring Boot AI Error Analyzer: One Annotation, Plain-English Stack Traces

First AI error analysis library for Spring Boot. Drop in @AiAnalyze, get root-cause analysis from six providers, with PII redaction and rate limits.

DomainSoftware
Formattutorial
Published3 Dec 2024
Tagsspring-boot · java · ai

Every Java team I've worked with loses hours per week to the same ritual. An exception fires in production, an engineer copies the stack trace into a chat, scrolls past framework noise to find the one line that matters, then walks back through the code to figure out which input actually broke things. The information needed to diagnose the bug is usually right there in the stack trace, the failing method, and the parameters. It just takes a human to assemble it.

LLMs are good at exactly this kind of assembly. The catch: every team I saw rolling their own integration was rebuilding the same plumbing. Prompt construction, PII redaction, rate limiting, deduplication, a dashboard, multi-provider failover. None of it was the interesting work, and none of it was easy to get right.

So I built Spring Boot AI Error Analyzer, an open-source library that solves this once. As far as I can tell, it is the first library of its kind for the Java / Spring Boot ecosystem. There is no equivalent on Maven Central.

The Pitch in Thirty Seconds

Add one starter dependency. Annotate the methods or classes you care about with @AiAnalyze. Set an API key. Open /ai-errors in your browser.

That's it. From the next exception onwards, you get a structured root-cause analysis (likely cause, suggested fix, severity, confidence) for every failure, stored, deduplicated, and searchable.

<dependency>
  <groupId>io.github.usamaqamar</groupId>
  <artifactId>spring-boot-ai-error-analyzer-starter</artifactId>
  <version>1.0.0</version>
</dependency>
ai-error-analyzer:
  enabled: true
  provider: openai
  openai:
    api-key: ${OPENAI_API_KEY}
    model: gpt-4o-mini
@RestController
@AiAnalyze
public class OrderController {
  @PostMapping("/orders")
  public Order create(@RequestBody @SensitiveParam OrderRequest req) {
    return orderService.create(req);
  }
}

The @AiAnalyze annotation wires up an AspectJ aspect that intercepts every thrown exception, builds a structured prompt (exception, stack trace, parameters, source code, HTTP context), sends it to the configured provider, stores the result, and surfaces it in the built-in dashboard.

Why a Library, Not a SaaS

Three reasons.

Data residency. Most production stack traces contain enough business context that legal teams will say no to "ship it to a third-party vendor." A library you control, with an Ollama provider that keeps inference on your own hardware, sidesteps that conversation entirely.

Cost. A vendor charges per seat or per error. The library charges you whatever your LLM provider charges. At gpt-4o-mini prices, a typical analysis costs around one tenth of a cent. A team seeing a thousand exceptions a day pays roughly one US dollar.

Lock-in. Your error history sits in your own Postgres, MySQL, or Elasticsearch. If the library disappears tomorrow, the data and dashboards stay.

Six Providers, With Failover

The library ships adapters for OpenAI, Anthropic Claude, Google Gemini, Groq, Ollama (fully offline), and any OpenAI-compatible custom endpoint. You configure a primary and a fallback chain.

ai-error-analyzer:
  provider: openai
  fallback-providers:
    - anthropic
    - groq
    - ollama

If OpenAI returns a 5xx or times out, the next provider in the chain runs. A transient outage at one vendor never drops your error pipeline. For teams that want a frontier model for HIGH severity bugs and a cheap model for noise, you can route by severity.

PII Redaction That Actually Works

The reason most teams stall on "send our errors to an LLM" is data leakage. The library treats this as a first-class concern.

public Order create(
    @SensitiveParam OrderRequest req,
    Authentication auth) { ... }

public class User {
  private String name;
  @SensitiveField private String email;
  @SensitiveField private String taxId;
}

@SensitiveParam redacts the entire parameter before serialisation. @SensitiveField redacts individual fields recursively. HTTP request bodies are never sent. There is also a global allow-list and deny-list for header capture. For teams with strict residency requirements, configuring provider: ollama keeps every byte of the analysis inside your VPC.

Production Controls, Not Just a Demo

The "rolled their own" version of this in most companies dies the day it gets pointed at production traffic. Either the bill explodes, or the LLM rate-limits, or every retry of the same bug burns another dollar.

The library ships with the controls you'd build in week two anyway:

  • Rate limits: per-minute, per-hour, and per-day, evaluated atomically.
  • Daily budget cap in USD. When the cap is hit, analyses queue or skip based on policy.
  • Deduplication: identical stack traces (normalised, with line numbers) are merged into a single record with an occurrence counter and last-seen timestamp. The dashboard shows you "this bug happened 1,847 times today" instead of 1,847 separate cards.
  • Retention policies: auto-delete analyses older than N days.
  • Pluggable storage: in-memory for dev, JPA (Postgres or MySQL) for typical production, Elasticsearch for teams that already have an ELK stack.

Notifications That Actually Page the Right Person

The library wires into Spring Mail, Slack incoming webhooks, and arbitrary webhooks (PagerDuty, Opsgenie, your own service). Each channel is configured per severity level.

ai-error-analyzer:
  notifications:
    slack:
      webhook-url: ${SLACK_WEBHOOK}
      min-severity: HIGH
    email:
      to: oncall@example.com
      min-severity: CRITICAL

Combined with the LLM-assigned severity field, on-call gets paged for CRITICAL only. The LOW and MEDIUM noise lands in the dashboard and the morning digest.

What the Dashboard Actually Shows

/ai-errors is a single-page Thymeleaf dashboard with no JavaScript framework dependency. For each unique exception group it shows:

  • Exception class, message, and the offending method.
  • The AI's plain-English root-cause analysis.
  • Suggested fix, with code references.
  • Severity and confidence.
  • Occurrence count, first-seen and last-seen timestamps.
  • The redacted parameter snapshot at the time of failure.

You can filter by severity, status (new, acknowledged, resolved), date range, or full-text search across the analyses.

What I Got Wrong on the First Pass

Two things, both worth flagging if you're building something similar.

Prompt size matters more than I expected. The first version sent the full stack trace, the full source of the failing method, and every parameter. That hit ten thousand tokens on Spring Boot apps with deep call chains, and gpt-4o-mini started losing the plot. The fix was to truncate the stack trace to the first frame inside your package plus three frames around it, and to send only the failing method's source rather than the whole class. Quality went up and cost went down.

Naive deduplication was wrong. My first key was exceptionClass + message. That collapses too aggressively. Two genuinely different bugs that happened to throw IllegalStateException with the same message merged into one record. The fix was a normalised stack-trace fingerprint: exception class plus the first user-package frame plus the line number, with line numbers stripped from anonymous lambdas. Bugs that share a root cause merge. Bugs that don't, don't.

When Not to Use This

Be honest about the boundaries.

  • Hot paths with sub-millisecond latency budgets. The aspect catches the exception after the fact, so it adds nothing to the success path. But the analysis itself is async and runs against a remote LLM. If you need synchronous structured error data inside a request, this isn't the tool.
  • Errors where the stack trace is genuinely meaningless. A SocketTimeoutException from a third party isn't going to get a useful root cause from any model. The library still logs and dedupes it, but don't expect insight.
  • Compliance environments where no LLM is acceptable. Use the Ollama provider, or skip the library.

Getting Started

Three lines of YAML, one annotation, one dependency. The full quickstart, configuration reference, and source code are on GitHub: github.com/usamaqamar/spring-boot-ai-error-analyzer. Maven Central artifact is io.github.usamaqamar:spring-boot-ai-error-analyzer-starter. MIT licensed.

If you ship Spring Boot apps and you're tired of manually walking stack traces at 2am, give it five minutes. That's about how long it takes to wire up. The first time it tells you exactly which null check you forgot, you'll wonder why the Java ecosystem didn't have this already.