tremor-client-java is a lightweight Java client for reporting exceptions and explicit error events to Tremor.
It targets Java 8, uses OkHttp for HTTP transport, Gson for JSON serialization, and keeps the public API small.
- Java 8 or higher
- A Tremor server exposing
/tremor/api/v1/ingest
<dependency>
<groupId>in.riido</groupId>
<artifactId>tremor-client-java</artifactId>
<version>0.1.0</version>
</dependency>implementation 'in.riido:tremor-client-java:0.1.0'implementation("in.riido:tremor-client-java:0.1.0")import in.riido.tremor.client.TremorClient;
try (TremorClient client = TremorClient.builder("your-tremor-key").build()) {
String fingerprint = client.report(new IllegalStateException("checkout failed"));
}Default base URL:
http://localhost:8080/tremor
import in.riido.tremor.client.TremorCaptureOptions;
import in.riido.tremor.client.TremorClient;
public final class OrderService {
private final TremorClient tremorClient =
TremorClient.builder("your-tremor-key")
.baseUrl("https://tremor.example.com/tremor")
.build();
public void processOrder(String orderId) {
try {
chargePayment(orderId);
reserveInventory(orderId);
} catch (Exception exception) {
tremorClient.report(
exception,
TremorCaptureOptions.builder()
.tag("orders")
.tag("payment")
.putUserCustomData("orderId", orderId)
.build());
throw exception;
}
}
}The client maps the throwable into Tremor's event shape, including:
- exception type
- message
- cause chain
- stack trace frames
import java.util.concurrent.CompletableFuture;
CompletableFuture<String> future =
tremorClient.reportAsync(new IllegalStateException("checkout failed"));The future completes with the Tremor fingerprint or completes exceptionally with the same client exception types used by the synchronous API.
Use this only when swallowing the original failure is intentional.
try {
refreshCache();
} catch (Exception exception) {
tremorClient.reportAndSuppress(exception);
}There are also runnable and callable overloads for best-effort work.
import in.riido.tremor.client.TremorClient;
import in.riido.tremor.client.model.TremorError;
import in.riido.tremor.client.model.TremorEvent;
import in.riido.tremor.client.model.TremorStackFrame;
TremorError error =
TremorError.builder()
.className("java.lang.IllegalStateException")
.message("checkout failed")
.frame(new TremorStackFrame("CheckoutService", "submit", "CheckoutService.java", 42))
.build();
TremorEvent event =
TremorEvent.builder().machineName("api-1").version("1.2.3").error(error).build();
try (TremorClient client = TremorClient.builder("your-tremor-key").build()) {
String fingerprint = client.report(event);
}TremorClient is built through TremorClient.builder(...) and is intended to be reused.
TremorClient client =
TremorClient.builder("your-tremor-key")
.baseUrl("https://tremor.example.com/tremor")
.build();Both String and URL forms are supported.
import java.net.URL;
TremorClient.builder("your-tremor-key")
.baseUrl("https://tremor.example.com/tremor")
.build();
TremorClient.builder("your-tremor-key")
.baseUrl(new URL("https://tremor.example.com/tremor"))
.build();Timeout knobs apply only when the library creates the OkHttpClient.
import java.util.concurrent.TimeUnit;
TremorClient client =
TremorClient.builder("your-tremor-key")
.connectTimeout(2, TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.SECONDS)
.writeTimeout(5, TimeUnit.SECONDS)
.callTimeout(15, TimeUnit.SECONDS)
.build();If you pass your own OkHttpClient, configure timeouts on that client instead.
import okhttp3.OkHttpClient;
OkHttpClient sharedClient = new OkHttpClient();
TremorClient client =
TremorClient.builder("your-tremor-key")
.baseUrl("https://tremor.example.com/tremor")
.httpClient(sharedClient)
.build();Ownership rules:
- If you pass an
OkHttpClient, Tremor uses that instance. - If you do not pass one, Tremor creates one internally.
TremorClient.close()only shuts down the internally created client.- A caller-provided
OkHttpClientis never shut down by the library.
For application-level metadata that should be reused across throwable reports, configure defaults once on the client.
import in.riido.tremor.client.TremorClientDefaults;
import in.riido.tremor.client.model.TremorClientInfo;
TremorClient client =
TremorClient.builder("your-tremor-key")
.defaults(
TremorClientDefaults.builder()
.version("1.2.3")
.client(new TremorClientInfo("orders-service", "1.2.3", "https://example.com"))
.build())
.build();Per-request TremorCaptureOptions take precedence over these defaults.
The client uses checked exceptions for runtime reporting failures.
IllegalArgumentExceptionindicates invalid client configuration or invalid event payload.TremorClientExceptionindicates a transport failure or general client-side reporting failure.TremorApiExceptionindicates Tremor responded with a non-2xx status.TremorSerializationExceptionindicates request or response JSON could not be serialized or parsed correctly.
Primary API:
report(TremorEvent event)report(Throwable throwable)report(Throwable throwable, TremorCaptureOptions options)reportAsync(TremorEvent event)reportAsync(Throwable throwable)reportAsync(Throwable throwable, TremorCaptureOptions options)reportAndSuppress(Throwable throwable)
Additional convenience overloads are available for tags, custom data, runnable suppression, and callable suppression.
Build and run tests:
mvn -q testInstall locally:
mvn -q install