Manual Usage

Installation

Copied
<dependency>
    <groupId>io.sentry</groupId>
    <artifactId>sentry</artifactId>
    <version>7.13.0</version>
</dependency>

For other dependency managers see the central Maven repository.

Configuration

When Sentry is used in manual way, configuration options must be passed to a static Sentry#init method:

Copied
import io.sentry.Sentry;

public class MyClass {
  public static void main(String... args) {
    Sentry.init(options -> {
      // NOTE: Replace the test DSN below with YOUR OWN DSN to see the events from this app in
      // your Sentry project/dashboard
      options.setDsn("https://examplePublicKey@o0.ingest.sentry.io/0");

      // All events get assigned to the release. See more at
      // https://docs.sentry.io/workflow/releases/
      options.setRelease("io.sentry.samples.console@4.2.0+1");

      // Modifications to event before it goes out. Could replace the event altogether
      options.setBeforeSend((event, hint) -> {
        // Drop an event altogether:
        if (event.getTag("SomeTag") != null) {
          return null;
        }
        return event;
      });

      // Allows inspecting and modifying, returning a new or simply rejecting (returning null)
      options.setBeforeBreadcrumb((breadcrumb, hint) -> {
        // Don't add breadcrumbs with message containing:
        if (breadcrumb.getMessage() != null
            && breadcrumb.getMessage().contains("bad breadcrumb")) {
          return null;
        }
        return breadcrumb;
      });

      // Configure the background worker which sends events to sentry:
      // Wait up to 5 seconds before shutdown while there are events to send.
      options.setShutdownTimeout(5000);

      // Enable SDK logging with Debug level
      options.setDebug(true);
      // To change the verbosity, use:
      options.setDiagnosticLevel(
          // By default it's DEBUG.
          // A good option to have SDK debug log in prod is to use only level
          // ERROR here.
          SentryLevel.ERROR
      );

      // Exclude frames from some packages from being "inApp" so are hidden by default in Sentry
      // UI:
      options.addInAppExclude("org.jboss");
    });
  }
}

Find more configuration options in the Configuration section.

Capture an Error

To report an event manually you need to initialize a Sentry class. It is recommended that you use the static API via the Sentry class, but you can also construct and manage your own IHub instance. An example of each style is shown below:

Copied
import io.sentry.IHub;
import io.sentry.Hub;
import io.sentry.Sentry;
import io.sentry.protocol.User;

public class MyClass {
  private static IHub hub;

  public static void main(String... args) {
    // NOTE: Replace the test DSN below with YOUR OWN DSN
    Sentry.init(options -> {
      options.setDsn("https://examplePublicKey@o0.ingest.sentry.io/0");
    });

    // It is possible to go around the static Sentry API, which means
    // you are responsible for making the IHub instance available
    // to your code.
    SentryOptions options = new SentryOptions();
    options.setDsn("https://examplePublicKey@o0.ingest.sentry.io/0");
    hub = new Hub(options);

    MyClass myClass = new MyClass();
    myClass.logWithStaticAPI();
    myClass.logWithInstanceAPI();
  }

  /**
   * An example method that throws an exception.
   */
  void unsafeMethod() {
    throw new UnsupportedOperationException("You shouldn't call this!");
  }

  /**
   * Examples using the (recommended) static API.
   */
  void logWithStaticAPI() {
    // Note that all fields set on the scope are optional. Scope data is copied onto
    // all future events in the current scope (until the scope is cleared).

    // Record a breadcrumb in the current scope. By default the last 100 breadcrumbs are kept.
    Sentry.addBreadcrumb("User made an action");

    // Set the user in the current scope.
    User user = new User();
    user.setEmail("hello@sentry.io");
    Sentry.setUser(user);

    // Add extra data to future events in this scope.
    Sentry.setExtra("extra", "thing");

    // Add an additional tag to future events in this scope.
    Sentry.setTag("tagName", "tagValue");

    // This sends a simple event to Sentry using the statically stored instance
    // that was created in the ``main`` method.
    Sentry.captureMessage("This is a test");

    try {
      unsafeMethod();
    } catch (Exception e) {
      // This sends an exception event to Sentry using the statically stored instance
      // that was created in the ``main`` method.
      Sentry.captureException(e);
    }
  }

  /**
   * Examples that use the SentryClient instance directly.
   */
  void logWithInstanceAPI() {

    // Record a breadcrumb in the current scope. By default the last 100 breadcrumbs are kept.
    hub.addBreadcrumb("User made an action");

    // Set the user in the current scope.
    User user = new User();
    user.setEmail("hello@sentry.io");
    hub.setUser(user);

    // This sends a simple event to Sentry.
    hub.captureMessage("This is a test");

    try {
      unsafeMethod();
    } catch (Exception e) {
      // This sends an exception event to Sentry.
      hub.captureException(e);
    }
  }
}

Building More Complex Events

For more complex messages, you’ll need to build an SentryEvent object:

Copied
import io.sentry.Sentry;
import io.sentry.SentryEvent;
import io.sentry.SentryLevel;
import io.sentry.protocol.Message;

public class MyClass {
  public static void main(String... args) {
    // NOTE: Replace the test DSN below with YOUR OWN DSN
    Sentry.init(options -> {
      options.setDsn("https://examplePublicKey@o0.ingest.sentry.io/0");
    });
  }

  void unsafeMethod() {
    throw new UnsupportedOperationException("You shouldn't call this!");
  }

  void logSimpleMessage() {
    // This sends an event to Sentry.
    SentryEvent event = new SentryEvent();
    Message message = new Message();
    message.setMessage("This is a test");
    event.setMessage(message);
    event.setLevel(SentryLevel.INFO);
    event.setLogger(MyClass.class.getName());

    Sentry.captureEvent(event);
  }

  void logException() {
    try {
      unsafeMethod();
    } catch (Exception e) {
      // This sends an exception event to Sentry.
      SentryEvent event = new SentryEvent();
      Message message = new Message();
      message.setMessage("Exception caught");
      event.setMessage(message);
      event.setLevel(SentryLevel.INFO);
      event.setLogger(MyClass.class.getName());
      event.setThrowable(e);

      Sentry.captureEvent(event);
    }
  }
}

Automatically Enhancing Events

You can also implement an EventProcessor that is able to automatically enhance outgoing events.

Copied
import io.sentry.EventProcessor;
import io.sentry.IHub;
import io.sentry.Sentry;
import io.sentry.SentryEvent;
import io.sentry.protocol.Message;

public class MyClass {
  public void myMethod() {
    // Add an `EventProcessor` to the current scope. Note that
    // this helper will process *all* future events in this scope.
    Sentry.configureScope(scope -> {
      scope.addEventProcessor(new EventProcessor() {
        @Override
        public SentryEvent process(SentryEvent event, Object hint) {
          Message message = new Message();
          message.setMessage("Overwritten by myEventBuilderHelper!");
          event.setMessage(message);
          return event;
        }
      });
    });

    // Send an event to Sentry. During construction of the event the message
    // body will be overwritten by the event processor.
    Sentry.captureMessage("Hello, world!");
  }
}