diff --git a/build.gradle.kts b/build.gradle.kts index c6c79eae19ded4acebdf9f74254356a66a9cf57c..bdce6aad5946851cc36bdb2ec29e5da218a39a93 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -254,6 +254,7 @@ dependencies { implementation("org.jboss.aerogear", "aerogear-otp-java", "1.0.0") implementation("com.github.kenglxn.qrgen", "javase", "2.6.0") implementation("org.mnode.ical4j", "ical4j", "2.2.0") + implementation("io.sentry", "sentry-spring", "1.7.30") } diff --git a/src/main/java/nl/tudelft/ewi/walkytalky/WalkytalkyApplication.java b/src/main/java/nl/tudelft/ewi/walkytalky/WalkytalkyApplication.java index 54505e47d69f8e6a769794151b2a8a3d7575c16b..5397b1724dddddee65859c8288aa59af65e76406 100644 --- a/src/main/java/nl/tudelft/ewi/walkytalky/WalkytalkyApplication.java +++ b/src/main/java/nl/tudelft/ewi/walkytalky/WalkytalkyApplication.java @@ -32,15 +32,20 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; import org.springframework.http.converter.BufferedImageHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; +import io.sentry.spring.SentryExceptionResolver; +import io.sentry.spring.SentryServletContextInitializer; + @EntityScan(basePackageClasses = WalkytalkyApplication.class) @SpringBootApplication public class WalkytalkyApplication implements WebMvcConfigurer { @@ -122,4 +127,15 @@ public class WalkytalkyApplication implements WebMvcConfigurer { public LoginAttemptService createGuestLoginAttemptService() { return new LoginAttemptService(5, 4); } + + @Bean + public HandlerExceptionResolver sentryExceptionResolver() { + return new SentryExceptionResolver(); + } + + @Bean + public ServletContextInitializer sentryServletContextInitializer() { + return new SentryServletContextInitializer(); + } + } diff --git a/src/main/java/nl/tudelft/ewi/walkytalky/configuration/SentryClientFactoryImpl.java b/src/main/java/nl/tudelft/ewi/walkytalky/configuration/SentryClientFactoryImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..7182bcfcd593e980482c5b1d7eb7a9a6e73fede7 --- /dev/null +++ b/src/main/java/nl/tudelft/ewi/walkytalky/configuration/SentryClientFactoryImpl.java @@ -0,0 +1,51 @@ +/* + * WalkyTalky - Enabling communication between patients in hospitals and their + * friends and family where they are no longer able to visit in person. + * + * Copyright (C) 2020 Delft University of Technology + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ +package nl.tudelft.ewi.walkytalky.configuration; + +import org.springframework.boot.info.BuildProperties; + +import io.sentry.DefaultSentryClientFactory; +import io.sentry.SentryClient; +import io.sentry.dsn.Dsn; +import io.sentry.event.helper.ContextBuilderHelper; +import io.sentry.event.helper.ForwardedAddressResolver; +import io.sentry.event.helper.HttpEventBuilderHelper; + +/** + * Class used by Sentry to setup the connection the server and include useful information such as release + * version. + */ +public class SentryClientFactoryImpl extends DefaultSentryClientFactory { + + @Override + public SentryClient createSentryClient(Dsn dsn) { + final SentryClient sentryClient = new SentryClient(createConnection(dsn), getContextManager(dsn)); + + final ForwardedAddressResolver addressResolver = new ForwardedAddressResolver(); + sentryClient.addBuilderHelper(new HttpEventBuilderHelper(addressResolver)); + + sentryClient.addBuilderHelper(new ContextBuilderHelper(sentryClient)); + + BuildProperties buildProperties = SpringContext.getBean(BuildProperties.class); + sentryClient.setRelease(buildProperties.getVersion()); + + return configureSentryClient(sentryClient, dsn); + } +} diff --git a/src/main/resources/sentry.properties.template b/src/main/resources/sentry.properties.template new file mode 100644 index 0000000000000000000000000000000000000000..a9f2e2b262f5e5513c9a738186cd9b9618f59d16 --- /dev/null +++ b/src/main/resources/sentry.properties.template @@ -0,0 +1,10 @@ +# This file is used to configure the Sentry logging. +# Uncomment the DSN key and insert the DSN key for the project. +# Make sure to set the other config values accordingly as well. +# The factory is necessary when running We\Visit behind a reverse proxy. Comment the line to use the default Factory. + +#dsn=your_key_here +environment=dev +servername=localhost +stacktrace.app.packages=nl.tudelft.ewi.walkytalky +factory=nl.tudelft.ewi.walkytalky.configuration.SentryClientFactoryImpl \ No newline at end of file