Share on Twitter
Share on Facebook
Share on HackerNews

Sentry for Spring Boot & Logback

While Spring Boot provides everything developers need to build applications, it leaves operational aspects of debugging issues to the developers and third-party services. If up until now all you had was log aggregation, where you can browse and filter through a web UI, prepare to have your mind blown with Sentry’s automatic error grouping, alerting, breadcrumbs, and much more.

Sentry has recently launched a major update to the Java SDK. In the post, we’ll focus on Spring Boot and Logback, which takes only a minute to configure. With Sentry’s latest Spring Boot integration:

  • each exception is decorated with HTTP request metadata - URL, request parameters, headers, and optionally user-specific information like cookies, IP address.
  • each exception can be attached to the release - a Git commit id - helping you to identify which commit introduced an issue
  • each error sent to Sentry is decorated with info or debug events that happened prior to the error in the scope of the same HTTP request
  • seamless Logback integration

How to configure Sentry Spring Boot Starter

Add Sentry to your Spring Boot applications in two steps:

  1. Add sentry-spring-boot-starter as a dependency to pom.xml
<dependency>
    <groupId>io.sentry</groupId>
    <artifactId>sentry-spring-boot-starter</artifactId>
    <version>3.1.0</version>
</dependency>
  1. Set the sentry.dsn property in your applications.properties. Learn more about Sentry’s DSN in our docs.
# NOTE: Replace the test DSN below with YOUR OWN DSN
sentry.dsn=https://f7f320d5c3a54709be7b28e0f2ca7081@sentry.io/1808954

That’s it. Now, every unhandled exceptions (and more, see below) in your app will contain detailed metadata that will be reported in real-time to Sentry. You will be notified via email, Slack, or other sentry integrations using our powerful alerting capabilities.

Sentry Spring Boot Issue Details

Logback Integration

Not everything that is considered an error turns into an unhandled exception. In many cases, you can handle the exception while offering users a degraded functionality and still keep this exception in server logs to be addressed by developers. This is where the Sentry Logback integration comes in.

The new Java SDK 3.0 has a Sentry Logback module providing SentryAppender forwarding every error log to Sentry.

Sentry Logback configuration is straightforward for everyone who has worked with Logback but for the Spring Boot integration we took a step further - the autoconfiguration will detect if both Sentry and Logback are on the classpath and will configure appender for you without modifying logback.xml manually. The only necessary step is to add a dependency to sentry-logback module:

<dependency>
    <groupId>io.sentry</groupId>
    <artifactId>sentry-logback</artifactId>
    <version>3.1.0</version>
</dependency>

In addition to forwarding error logs to Sentry, SentryAppender collects each event with a log level lower than error as a breadcrumb - an additional context attached to every error. In the following example, startup logs with info level and every log entry that happened prior reporting an error in the scope of the HTTP request will appear in Sentry UI in the breadcrumbs section:

import io.sentry.Sentry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);

    @GetMapping("/")
    String hello(@RequestParam(required = false) String name) {
        logger.info("I am about to trigger an exception");
				logger.error(new RuntimeException("Expected: controller used to showcase what happens when an exception is thrown"));
        return "Hello " + name.toUpperCase();
    }
}

Sentry Java Spring Boot Breadcrumbs

What Logback logging level is considered a breadcrumb and what is considered an event is not set in stone and can be easily configured in Spring Boot application.properties:

sentry.logging.minimum-event-level=warn
sentry.logging.minimum-breadcrumb-level=debug

Attaching Release Information

If Spring Boot is configured to generate Git information for Spring Boot Actuator, Sentry Starter sets the current Git commit id as a release sent along with every error to Sentry. It enables Sentry Releases product which helps you to identify problematic commits, assign issues to responsible people and understand issues and regressions introduced in each release.

To use this feature just include git-commit-id-plugin in your pom.xml

<build>
    <plugins>
        <plugin>
            <groupId>pl.project13.maven</groupId>
            <artifactId>git-commit-id-plugin</artifactId>
        </plugin>
    </plugins>
</build>

If you use Gradle add following plugin to build.gradle file:

plugins {
    id "com.gorylenko.gradle-git-properties" version "2.2.2"
}

Once this is done, each issue will state the release in which it was introduced and the latest release in which it occurred.

Sentry Spring Boot Releases

Attaching User Information

Sentry Spring Boot Starter offers a simple way to enable collecting users data - name, cookies, and even the IP address. Since user data is sensitive information, this feature is not enabled by default. To turn it on you must add an extra property to application.properties file:

sentry.send-default-pii=true

While cookies and the IP address can be collected in any Spring MVC application, to attach users names to events, users must be authenticated with any authentication framework that sets the java.security.Principal object on the HttpServletRequest. We realize that you may need more or different information to successfully identify users. That’s why the new SDK lets you hook into the user processing pipeline by implementing SentryUserProvider interface. With Spring Security on the classpath, you can access current user and use this information to set SentryUser properties:

@Component
class CustomUserProvider implements SentryUserProvider {
    private final UserRepository userRepository;

    public CustomUserProvider(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public User provideUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        User user = new User();
        user.setEmail(...);
        return user;
    }
}

Other Integrations

Along with Sentry Spring Boot Starter, the new Java SDK contains integrations with Log4j2 and traditional non-Spring servlet applications. Head over to Java SDK docs to learn all the details.

Additional Resources

To learn more about features offered in the latest release take a look at the sample projects in Sentry Java Github Repository and for step by step walkthrough of the Sentry Spring Boot check out this video from Spring Academy YouTube channel.

Your code is broken. Let's Fix it.
Get Started
© 2020 • Sentry is a registered Trademark
of Functional Software, Inc.