Getting Started¶
Choose a Package¶
Java¶
Use the core artifact for plain Java applications (Java 8+):
<dependency>
<groupId>io.github.arnabnandy7</groupId>
<artifactId>bugdna</artifactId>
<version>1.2.0</version>
</dependency>
Gradle:
Use the starter for Spring Boot applications (Java 17+, Spring Boot 4.x):
<dependency>
<groupId>io.github.arnabnandy7</groupId>
<artifactId>bugdna-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
Gradle:
The starter already depends on the core artifact.
Node.js / TypeScript¶
Requires Node.js 18+ (dual ESM and CommonJS with TypeScript definitions):
Python¶
Requires Python 3.9+ (zero dependencies, PEP 561 typed):
Generate a Fingerprint¶
Java¶
import io.github.bugdna.BugDna;
import io.github.bugdna.Fingerprint;
try {
runApplicationCode();
} catch (Exception exception) {
Fingerprint fingerprint = BugDna.generate(exception);
System.out.println(fingerprint.getId());
}
Node.js / TypeScript¶
import { generate } from 'bugdna';
try {
runApplicationCode();
} catch (err) {
const fingerprint = generate(err as Error);
console.log(fingerprint.id);
}
Python¶
from bugdna import generate
try:
run_application_code()
except Exception as exc:
fingerprint = generate(exc)
print(fingerprint.id)
Example output:
Every fingerprint identifier uses 16 uppercase hexadecimal characters after the BUGDNA- prefix.
Inspect the Failure¶
Java¶
System.out.println(fingerprint.getRootCause());
System.out.println(fingerprint.getSignature());
System.out.println(fingerprint.getQualifiedSignature());
System.out.println(fingerprint.getCategory());
System.out.println(fingerprint.getFamily());
System.out.println(fingerprint.getStabilityScore());
Node.js / TypeScript¶
console.log(fingerprint.rootCause);
console.log(fingerprint.signature);
console.log(fingerprint.qualifiedSignature);
console.log(fingerprint.category);
console.log(fingerprint.family);
console.log(fingerprint.stabilityScore);
Python¶
print(fingerprint.root_cause)
print(fingerprint.signature)
print(fingerprint.qualified_signature)
print(fingerprint.category)
print(fingerprint.family)
print(fingerprint.stability_score)
Example output:
java.lang.NullPointerException
UserService#getUser
com.example.UserService#getUser
UNKNOWN
UNKNOWN
90
For a log-friendly multi-line summary across any language, call fingerprint.explain():
BUGDNA-7A3F21B9E4C018D2
Root Cause:
NullPointerException
Origin:
UserService#getUser
Confidence:
90%
Failure Chain:
UserController -> UserService
Assert Fingerprints in Automated Tests¶
Java¶
import static io.github.bugdna.BugDnaAssertions.assertThat;
assertThat(fingerprint)
.hasCategory(FailureCategory.DATABASE)
.hasRootCause(SQLTimeoutException.class);
Node.js / TypeScript¶
import { BugDnaAssertions, FailureCategory } from 'bugdna';
BugDnaAssertions.assertThat(fingerprint)
.hasCategory(FailureCategory.DATABASE)
.hasRootCause('SQLTimeoutException');
Python¶
from bugdna import BugDnaAssertions, FailureCategory
BugDnaAssertions.assert_that(fingerprint) \
.has_category(FailureCategory.DATABASE) \
.has_root_cause( TimeoutError )
Render Causal Dependencies¶
// Node.js / TypeScript
import { dependencyGraph } from 'bugdna';
console.log(dependencyGraph(err).report());
Look Up Runbooks and Ownership¶
Create a bugdna.yml file in your working directory:
Look up context by ID in Java (BugDna.lookup("BUGDNA-001")), Node.js (lookup('BUGDNA-001')), or Python (lookup("BUGDNA-001")).
Track Recurring Failures¶
Java¶
FailureTracker tracker = new FailureTracker();
tracker.capture(exception);
System.out.println(tracker.getTotalOccurrences());
System.out.println(tracker.getUniqueFailures());
System.out.println(tracker.topFailureReport());
Node.js / TypeScript¶
import { FailureTracker } from 'bugdna';
const tracker = new FailureTracker();
tracker.capture(err as Error);
console.log(tracker.getTotalOccurrences());
console.log(tracker.getUniqueFailures());
console.log(tracker.topFailureReport());
Python¶
from bugdna import FailureTracker
tracker = FailureTracker()
tracker.capture(exc)
print(tracker.total_occurrences)
print(tracker.unique_failures)
print(tracker.top_failure_report())
The tracker is in-memory only (and thread-safe in Java and Python). After repeated captures, tracker.report() groups occurrences by fingerprint:
Enable Spring Capture (Java)¶
The Spring Boot starter participates in Spring Boot auto-configuration. You may also make the integration explicit:
import io.github.bugdna.spring.EnableBugDna;
@EnableBugDna
@SpringBootApplication
class Application {
}
Unhandled Spring MVC and WebFlux exceptions then pass through BugDNA without replacing Spring's normal exception handling.
Next Steps¶
- Learn fingerprint behavior in Core library.
- Configure aggregation in Failure tracking.
- Configure Spring in Spring Boot starter.
- Add metrics, OpenTelemetry, and MDC in Observability.