Skip to content

Explicit Event Model

Garvit Joshi edited this page Apr 2, 2026 · 3 revisions

Explicit Event Model

Use the explicit model when you want full control over the payload that reaches Tremor.

Main Public Models

  • TremorEvent
  • TremorError
  • TremorStackFrame
  • TremorBreadcrumb
  • TremorEnvironment
  • TremorClientInfo
  • TremorUser

Example

import in.riido.tremor.client.TremorClient;
import in.riido.tremor.client.model.TremorBreadcrumb;
import in.riido.tremor.client.model.TremorClientInfo;
import in.riido.tremor.client.model.TremorEnvironment;
import in.riido.tremor.client.model.TremorError;
import in.riido.tremor.client.model.TremorEvent;
import in.riido.tremor.client.model.TremorStackFrame;
import in.riido.tremor.client.model.TremorUser;
import java.time.OffsetDateTime;

String tremorKey = "...";

TremorError error = TremorError.builder()
    .className("java.lang.IllegalStateException")
    .message("checkout failed")
    .frame(new TremorStackFrame("CheckoutService", "submit", "CheckoutService.java", 42))
    .innerError(
        TremorError.builder()
            .className("java.lang.NullPointerException")
            .message("orderId was null")
            .build())
    .build();

TremorEvent event = TremorEvent.builder()
    .occurredOn(OffsetDateTime.parse("2026-04-01T10:15:30Z"))
    .machineName("machine-a")
    .version("1.2.3")
    .groupingKey("checkout-failure")
    .error(error)
    .environment(
        TremorEnvironment.builder()
            .osVersion("Linux")
            .architecture("amd64")
            .processorCount(8)
            .locale("en-IN")
            .utcOffset(5.5d)
            .build())
    .client(new TremorClientInfo("tremor-client-java", "0.1.0", "https://example.com/client"))
    .tag("critical")
    .tag("payments")
    .putUserCustomData("orderId", "12345")
    .user(new TremorUser("user-123", "user@example.com", "Jane Doe"))
    .breadcrumb(
        TremorBreadcrumb.builder()
            .message("started checkout")
            .category("lifecycle")
            .type("manual")
            .lineNumber(42)
            .build())
    .build();

try (TremorClient client = TremorClient.builder(tremorKey).build()) {
    String fingerprint = client.send(event);
}

Wire Shape

The client serializes the event into Tremor's ingest shape:

{
  "occurredOn": "2026-04-01T10:15:30Z",
  "details": {
    "machineName": "machine-a",
    "version": "1.2.3",
    "groupingKey": "checkout-failure",
    "error": {
      "className": "java.lang.IllegalStateException",
      "message": "checkout failed"
    }
  }
}

Optional fields such as environment, client, tags, userCustomData, user, and breadcrumbs are included only when present.

Validation Rules

TremorEvent.builder().build() validates the payload before any network call happens.

Important rules:

  • error is required
  • error.className is required
  • error.message is required
  • machineName max length: 255
  • version max length: 100
  • groupingKey max length: 100
  • error.message max length: 2000
  • tags max count: 20
  • tag max length: 64
  • stack frames max count: 100
  • breadcrumbs max count: 100
  • userCustomData max top-level entries: 50
  • nested structured data max depth: 5
  • nested collection item limit: 20
  • inner error depth max: 5

When to Use This Path

Use the explicit event model when:

  • you already have structured error data
  • you want to control the exact metadata fields
  • you are translating errors from another system
  • you do not want throwable-to-event conversion

If you already have a Throwable, the simpler path is usually Throwable Capture.

Clone this wiki locally