diff --git a/saas-modules/pom.xml b/saas-modules/pom.xml index 7a626e7663..7e8adebdd9 100644 --- a/saas-modules/pom.xml +++ b/saas-modules/pom.xml @@ -20,6 +20,7 @@ stripe twilio twitter4j + sentry-servlet diff --git a/saas-modules/sentry-servlet/pom.xml b/saas-modules/sentry-servlet/pom.xml new file mode 100644 index 0000000000..c86fcbce03 --- /dev/null +++ b/saas-modules/sentry-servlet/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + com.baeldung + saas-modules + 1.0.0-SNAPSHOT + + sentry-servlet + sentry-servlet + war + + + 6.11.0 + 1.10.4 + + + + + io.sentry + sentry-servlet + ${sentry.version} + + + + javax.servlet + javax.servlet-api + provided + + + + + + + org.codehaus.cargo + cargo-maven3-plugin + ${cargo.version} + + + tomcat9x + embedded + + + + + + \ No newline at end of file diff --git a/saas-modules/sentry-servlet/src/main/java/com/baeldung/sentry/servlet/FaultyServlet.java b/saas-modules/sentry-servlet/src/main/java/com/baeldung/sentry/servlet/FaultyServlet.java new file mode 100644 index 0000000000..7a32094221 --- /dev/null +++ b/saas-modules/sentry-servlet/src/main/java/com/baeldung/sentry/servlet/FaultyServlet.java @@ -0,0 +1,32 @@ +package com.baeldung.sentry.servlet; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(urlPatterns = "/fault", loadOnStartup = 1) +public class FaultyServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + String op = req.getParameter("op"); + if( "fault".equals(op) ) { + resp.sendError(500, "Something bad happened !"); + } + else if ( "exception".equals(op) ) { + throw new IllegalArgumentException("Internal error"); + } + else { + resp.setStatus(200); + resp.setContentType("text/plain"); + resp.getWriter().println("OK"); + } + } +} diff --git a/saas-modules/sentry-servlet/src/main/java/com/baeldung/sentry/support/SentryContextListener.java b/saas-modules/sentry-servlet/src/main/java/com/baeldung/sentry/support/SentryContextListener.java new file mode 100644 index 0000000000..6f25dd36aa --- /dev/null +++ b/saas-modules/sentry-servlet/src/main/java/com/baeldung/sentry/support/SentryContextListener.java @@ -0,0 +1,39 @@ +package com.baeldung.sentry.support; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; + +import io.sentry.Sentry; +import io.sentry.SentryLevel; + +@WebListener +public class SentryContextListener implements ServletContextListener { + @Override + public void contextInitialized(ServletContextEvent sce) { + + // Besides standard supported locations, let's also allow the DSN to be + // passed using servlet container managed parameters. This can be useful if your app + // is hosted in a shared application server. + ServletContext context = sce.getServletContext(); + String sentryDsn = context.getInitParameter("sentry.dsn"); + + if ( sentryDsn != null ) { + context.log("[I21] sentry.dsn init parameter found. Configuring Sentry SDK..."); + Sentry.init(sentryDsn); + } + else { + context.log("[I25] sentry.dsn init parameter not found. Configuring Sentry SDK with defaults"); + Sentry.init(); + } + + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + sce.getServletContext().log("[I34] shutting down context"); + Sentry.captureMessage("[I35] contextDestroyed", SentryLevel.INFO); + Sentry.close(); + } +} diff --git a/saas-modules/sentry-servlet/src/main/java/com/baeldung/sentry/support/SentryFilter.java b/saas-modules/sentry-servlet/src/main/java/com/baeldung/sentry/support/SentryFilter.java new file mode 100644 index 0000000000..e853368ad9 --- /dev/null +++ b/saas-modules/sentry-servlet/src/main/java/com/baeldung/sentry/support/SentryFilter.java @@ -0,0 +1,32 @@ +package com.baeldung.sentry.support; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletResponse; + +import io.sentry.Sentry; +import io.sentry.SentryLevel; + +@WebFilter(urlPatterns = "/*") +public class SentryFilter implements Filter { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + try { + chain.doFilter(request, response); + int rc = ((HttpServletResponse) response).getStatus(); + if (rc/100 == 5) { + Sentry.captureMessage("Application error: code=" + rc, SentryLevel.ERROR); + } + } catch (Throwable t) { + Sentry.captureException(t); + throw t; + } + } +} diff --git a/saas-modules/sentry-servlet/src/main/resources/sentry.properties b/saas-modules/sentry-servlet/src/main/resources/sentry.properties new file mode 100644 index 0000000000..c937874420 --- /dev/null +++ b/saas-modules/sentry-servlet/src/main/resources/sentry.properties @@ -0,0 +1,3 @@ +# Sentry configuration file +# put your DSN here +dsn=https://xxxxxxxxxxxxxxxx@zzzzzzz.ingest.sentry.io/wwww \ No newline at end of file diff --git a/saas-modules/sentry-servlet/src/main/webapp/WEB-INF/web.xml b/saas-modules/sentry-servlet/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..e89de5f352 --- /dev/null +++ b/saas-modules/sentry-servlet/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/saas-modules/sentry-servlet/src/test/java/com/baeldung/sentry/servlet/FaultyServletLiveTest.java b/saas-modules/sentry-servlet/src/test/java/com/baeldung/sentry/servlet/FaultyServletLiveTest.java new file mode 100644 index 0000000000..3db0d1c66e --- /dev/null +++ b/saas-modules/sentry-servlet/src/test/java/com/baeldung/sentry/servlet/FaultyServletLiveTest.java @@ -0,0 +1,46 @@ +package com.baeldung.sentry.servlet; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.HttpURLConnection; +import java.net.URL; + +import org.junit.jupiter.api.Test; + +class FaultyServletLiveTest { + + + @Test + void testGivenFaultyRequestWithNoQueryString_thenSuccess() throws Exception { + + //int port = getServerPort(); + URL u = new URL("http://localhost:8080/sentry-servlet/fault"); + HttpURLConnection conn = (HttpURLConnection)u.openConnection(); + int rc = conn.getResponseCode(); + assertThat(rc) + .isEqualTo(200); + } + + @Test + void testGivenFaultyRequestWithFaultString_thenFail() throws Exception { + + //int port = getServerPort(); + URL u = new URL("http://localhost:8080/sentry-servlet/fault?fault=true"); + HttpURLConnection conn = (HttpURLConnection)u.openConnection(); + int rc = conn.getResponseCode(); + assertThat(rc) + .isEqualTo(500); + } + + @Test + void testGivenFaultyRequestWithExceptionString_thenFail() throws Exception { + + //int port = getServerPort(); + URL u = new URL("http://localhost:8080/sentry-servlet/fault?exception=true"); + HttpURLConnection conn = (HttpURLConnection)u.openConnection(); + int rc = conn.getResponseCode(); + assertThat(rc) + .isEqualTo(500); + } + +}