Back to Blog Home

Capturing Java Exceptions with Sentry

Ted Kaemming image

Ted Kaemming -

Capturing Java Exceptions with Sentry

Getting started with Java exception handling can be an intimidating
prospect. The large number of dependency managers, logging frameworks,
configuration methods, and programming languages that run on the JVM can create
a dizzying number of options for a programmer to choose between, so we’ve put
this guide together to help you navigate the world of modern Java error tracking
with Sentry.

Choosing a Java Integration

The Sentry Java SDK (sentry-java) is hosted at Maven Central, a repository
that hosts many widely distributed Java packages (JARs) and works with many of
the popular JVM dependency managers, including Maven. A search for Sentry on
Maven Central yields several results for different distributions of the
project, and in this post we’ll help you figure out which is the right one to
use with your application.

The major components of the SDK can be divided into two categories:

  • Logging integrations, commonly referred to as appenders, used to
    translate log records generated by your application via a logging framework
    into Sentry events. These integrations are packaged as sentry-logback,
    sentry-log4j, and sentry-log4j2.

  • Sentry, used by the logging integrations to send events to a Sentry server.
    This is packaged as sentry and also includes the logging handler for
    java.util.logging.

For most applications, we recommend using one of the logging integrations to
communicate with a Sentry server
, and we’ll be mainly focusing on those in
this post. For existing applications that are already using a logging
framework, integrating with Sentry is often as simple as adding or changing a
few lines in your logging configuration files. We recommend using the logging
integrations over interfacing with Sentry directly for several reasons:

  • The logging APIs are easy to understand. The patterns and vocabulary used
    by logging APIs are familiar to many developers, even across different
    platforms.

  • Producing messages via the logging frameworks reduce the amount of
    boilerplate code.
    For example, compare the logback appender event building
    method
    with a call to the logger.error method.

  • Using a logging framework provides greater control over reporting
    configuration.
    It is easy to replace reporting to Sentry in your
    development environment with console logging by using a different logging
    configuration file. Contrast this with having to wrap all calls in
    conditionals or mocking out the Sentry interface with a fake instance.

  • Many other libraries also utilize logging frameworks. Using the logging
    framework enables collecting better data from other libraries in your
    application that also utilize the logging system, such as database drivers or
    a web framework.

The Java Logging Ecosystem

If you’re new to Java and have a background in a platform such as Python with
a de facto logging solution, one of the first things that
you will notice is the large number of logging frameworks that are available
and remain used today. To understand why so many different frameworks exist,
we’ll start with a quick history lesson.

Log4j was introduced in 1999 and was one of the first widely
adopted logging frameworks. A few years later in 2002, Sun introduced an
alternative framework, java.util.logging (commonly referred to by the acronym
“JUL”), which is distributed with the Java platform. In reaction, the Apache
Commons Logging project was created with the intention of providing a unified
logging API that could be used to interact with whichever backing logging
implementation that the user preferred, including Log4j and JUL (among others.)
However, yet another alternative “unified” logging API emerged in
2005 from the author of Log4j — SLF4J, the “Simple Logging Facade for Java.”
Later, the author of Log4j and SLF4J released logback, which provided a
native implementation of the SLF4J interface. Around the same time, development
also began on the (now stable) Log4j 2 — without the author of the first
version. Simple, right?

There was a lot of code that was written at different points in time during
this history and like so much software there was — and still is — lot of
debates on which framework is the best choice. Since many of these projects are
still in use today, Sentry provides integrations for several of the most widely
adopted frameworks including JUL, logback,
Log4j, and Log4j 2. Getting started is typically
a matter of configuration, and the documentation for each integration contains
instructions on how to include the integration as a dependency as well as a
sample configuration to help you get started.

Choosing the Right Integration for Your Projects

When choosing which logging framework to use for your own projects, that
decision is often mandated to you by your choice of framework. For projects
that don’t depend on a framework, targeting the SLF4J interface is often
recommended due to its ubiquity and flexibility. The backing logging
implementation is largely a matter of developer preference, with logback and
Log4j 2 being common choices.

Starting from Scratch

For example, it only takes a few moments to start reporting to Sentry with
SLF4J and logback.

  1. Add sentry-logback to your project dependencies. If you’re using Maven,
    dependencies are declared in pom.xml, and you can see an example in our
    logback example project
    . If you’re not using Maven,
    the project details on Maven Central have dependency information for a variety
    of different package managers.

    <dependency> <groupId>io.sentry</groupId> <artifactId>sentry-logback</artifactId> <version>1.2.0</version> </dependency>
  2. Add the Sentry appender to your logback.xml configuration file. You can
    set the Sentry DSN for your project via JDNI, as the SENTRY_DSN environment
    variable or sentry.dsn system property.

    <appender name="Sentry" class="io.sentry.logback.SentryAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>WARN</level> </filter> </appender> <root level="INFO"> <appender-ref ref="Sentry"/> </root>
  3. Add logging calls to your application. It is usually most effective to
    add logging.error calls as far towards the top of the stack in your
    application as possible — good [examples are a main method in a console
    application] _logback-example/app, or request handler in a web application —
    to capture as many exceptions as possible. It can also be helpful to log errors
    as a warning or lower level in other try/catch blocks where checked
    exceptions are captured.

    public static void main(String[] args) { try { application.run() } catch (Exception e) { logger.error("Caught exception!", e); } }
  4. That’s it! Your project should now be reporting Java errors to Sentry. Tell your
    boss that you deserve a promotion!

We have several other example integrations in our sentry-java-examples
repository
, and are adding more all the time.

Beyond Log Messages

The Sentry Java SDK also provides additional features that extend beyond simple
log messages and tracebacks.

HTTP Request Details

When developing a web application, much of the state that is useful for
identifying patterns among exception reports is contained within the attributes
of the HTTP request, such as the logged in user account, request URL, headers,
and query parameters. If your deployment environment utilizes Java Servlets,
these attributes are included automatically on all log messages that occur
during the context of a request.

Mapped Diagnostic Context

In addition to HTTP request attributes, it can often be helpful to add
additional context to exception reports that are specific to your application.
For example, an if you’re running an e-commerce application, it can be helpful
to track what step of a checkout process a customer was in when an error
occurred. For a consumer product, it can be helpful to track the subscription
that the user is a member of so you can effectively triage issues by customer
impact. For a stream processing system, it can be helpful to track the
component in the processing pipeline where the error occurred.

The SLF4J API provides a feature called the Mapped Diagnostic Context, or MDC,
for recording this data. This data is represented as tags or extra data in the
Sentry UI. (This feature is available when using the Log4j, Log4j 2, and
logback appenders.)

MDC.put("checkout-step", "submit"); try { // Any exceptions raised during order submission will include the // `checkout-step` tag. order.submit(); } finally { MDC.remove("checkout-step"); }

In addition to user supplied tags, a few additional tags are included in each
event, including the logger, log level, and hostname.

Beyond Log Messages

Asynchronous Logging

A common concern with over-the-network logging is the performance hit incurred
from communicating synchronously with a remote server. Asynchronous logging
prevents network latency due to logging from directly impacting your
application. The SDK design also enables asynchronous logging by frameworks
that do not natively support asynchronous appenders. The ability to tune thread
pool size, priority, and queue size also allows you to have fine-grained
control over how much logging effects your application’s CPU, memory, and
latency profile.

Not Just for Java

Although the project is named sentry-java on GitHub, the Sentry Java SDK can
be used by any JVM language that provides Java interoperability capabilities,
including Clojure, Scala, Kotlin, and Groovy. Because idiomatic Clojure is quite
different than the other languages, we offer a sentry-clojure SDK wrapper
for a more native experience.

Take a look at the documentation for details on implementing the Sentry SDK. If you’re not yet a Sentry user, you can sign up at any time.

Share

Share on Twitter
Share on Bluesky
Share on HackerNews
Share on LinkedIn

Published

Sentry Sign Up CTA

Code breaks, fix it faster

Sign up for Sentry and monitor your application in minutes.

Try Sentry Free

Topics

SDK Updates

New product releases and exclusive demos

Listen to the Syntax Podcast

Of course we sponsor a developer podcast. Check it out on your favorite listening platform.

Listen To Syntax
© 2024 • Sentry is a registered Trademark of Functional Software, Inc.