A lightweight, zero-configuration Application Performance Monitoring (APM) client for Spring Boot.
It uses Spring AOP to automatically intercept unhandled exceptions from @RestController classes and dispatch them asynchronously to your centralized log server.
- Zero Code Changes — Works out of the box with no changes to your controllers or exception handlers.
- Asynchronous — All log pushes run in a
CompletableFuturefire-and-forget thread with minimal impact on API response times. - Resilient — Fails silently if the log server is unreachable. Your application never crashes because of monitoring failures.
- Multi-Tenant Ready — Uses an
X-API-KEYheader to authenticate and route logs correctly. - Customizable — Use the
@LogDispatchannotation to control how errors appear on your dashboard.
Add the dependency to your pom.xml:
<dependency>
<groupId>in.maheshlangote</groupId>
<artifactId>logdispatch-spring-boot-starter</artifactId>
<version>1.0.6</version>
</dependency>logdispatch:
server-url: "https://your-apm-server.com/api/v1/ingest/logs"
api-key: "your-secret-api-key"
masked-headers: "authorization,cookie,x-api-key"
exclude-paths: "/health,/actuator/**,/metrics/**"logdispatch.server-url=https://your-apm-server.com/api/v1/ingest/logs
logdispatch.api-key=your-secret-api-key
logdispatch.masked-headers=authorization,cookie,x-api-key
logdispatch.exclude-paths=/health,/actuator/**,/metrics/**| Property | Required | Description |
|---|---|---|
logdispatch.server-url |
✅ Yes | Full URL of the APM ingest endpoint |
logdispatch.api-key |
✅ Yes | API key used to authenticate with the APM server |
logdispatch.masked-headers |
❌ No | Comma-separated list of headers to mask. Defaults to none |
logdispatch.exclude-paths |
❌ No | Comma-separated list of URI paths to exclude. Supports wildcards such as /actuator/** |
logdispatch.timeout-ms |
❌ No | Connection and read timeout in milliseconds. Defaults to 3000. |
When a @RestController method throws an unhandled exception, or when a filter rejects a request (e.g., 403 Forbidden, 404 Not Found), the SDK:
- Captures the request URI, HTTP method, exception class, message, and full stack trace.
- Reads optional metadata from the
@LogDispatchannotation. - Asynchronously sends a JSON payload to the configured
server-url. - Includes the
X-API-KEYheader for authentication. - Logs a warning if the push fails and continues execution without affecting the application.
Every exception is pushed as a POST request to the configured server-url.
| Header | Value |
|---|---|
Content-Type |
application/json |
X-API-KEY |
Value of logdispatch.api-key |
{
"timestamp": "2026-05-28T17:58:43.805Z",
"errorType": "IllegalArgumentException",
"statusCode": 500,
"errorMessage": "Invalid entries",
"errorPath": "/api/v1/user/create",
"affectedFeature": "UserController",
"affectedAPI": "/api/v1/user/create",
"apiType": "POST",
"affectedFunction": "createUser",
"stackTrace": "java.lang.IllegalArgumentException: Invalid entries\n\tat com.example...",
"severity": "CRITICAL",
"inputInformation": {
"queryString": null,
"parameters": {},
"headers": {
"host": "localhost:8080",
"content-type": "application/json"
},
"body": "{\"entries\": []}"
}
}| Field | Type | Description |
|---|---|---|
timestamp |
String | ISO-8601 UTC timestamp |
errorType |
String | Exception class name |
statusCode |
Number | HTTP status code |
errorMessage |
String | Exception message |
errorPath |
String | Request URI |
affectedFeature |
String | Controller name or annotation override |
affectedAPI |
String | API path or annotation override |
apiType |
String | HTTP method |
affectedFunction |
String | Method name or annotation override |
stackTrace |
String | Full stack trace |
severity |
String | WARNING, CRITICAL, or SECURITY |
inputInformation |
Object | Request metadata including headers, parameters, and body |
Note:
inputInformation.bodyis skipped formultipart/form-datauploads or payloads larger than 32 KB.
| HTTP Status / Condition | Severity |
|---|---|
| 4xx (Exception) | WARNING |
| 5xx (Exception) | CRITICAL |
| Filter/Routing Error | SECURITY |
The starter automatically exposes a lightweight endpoint that allows your APM server to verify application health and uptime.
GET /logdispatch/health{
"status": "UP",
"startupTime": "2026-05-31T02:00:00.000Z",
"uptimeSeconds": 120
}To prevent abuse, the endpoint is limited to:
60 requests per minute per IP
Requests exceeding the limit receive:
429 Too Many RequestsYour APM ingest endpoint should follow this contract.
Any 2xx response is treated as successful.
The SDK ignores the response body.
Example response:
{
"status": 401,
"error": "Unauthorized",
"message": "Invalid API key"
}SDK log:
WARN [LogDispatch] Failed to push error: 401 UNAUTHORIZED : {"status":401,"error":"Unauthorized","message":"Invalid API key"}
Example SDK log:
WARN [LogDispatch] Failed to push error: 500 INTERNAL_SERVER_ERROR : {"status":500,...}
Example SDK log:
WARN [LogDispatch] Failed to push error: Connection refused: connect
Important: The SDK never rethrows exceptions. Monitoring failures never affect the application.
Override default metadata with human-readable labels.
import in.maheshlangote.logdispatch.annotation.LogDispatch;
@RestController
@LogDispatch(feature = "Payment Gateway")
public class PaymentController {
@PostMapping("/pay")
@LogDispatch(
api = "Process Payment",
function = "handlePayment"
)
public void handlePayment() {
// ...
}
}Generated payload:
{
"affectedFeature": "Payment Gateway",
"affectedAPI": "Process Payment",
"affectedFunction": "handlePayment"
}Without the annotation, the SDK defaults to:
- Controller class name
- Method name
- Raw request URI
If you want to contribute to this project, please follow our established automation testing best practices.
Please see the TESTING.md file for detailed guidelines on how to run, structure, and write tests for this SDK.
For common problems and solutions, see:
TROUBLESHOOTING.md
A runnable Spring Boot demo is available in example-app. It includes dummy REST endpoints that intentionally throw exceptions so you can see LogDispatch capture and dispatch APM log payloads.
MIT License