Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mechanism for logging integrations and update spring mechanism types #2595

Merged
merged 5 commits into from
Mar 15, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

- Fix timestamps of slow and frozen frames for profiles ([#2584](https://github.com/getsentry/sentry-java/pull/2584))
- Deprecate reportFullDisplayed in favor of reportFullyDisplayed ([#2585](https://github.com/getsentry/sentry-java/pull/2585))
- Add mechanism for logging integrations and update spring mechanism types ([#2595](https://github.com/getsentry/sentry-java/pull/2595))
adinauer marked this conversation as resolved.
Show resolved Hide resolved
- Filter out session cookies sent by Spring and Spring Boot integrations ([#2593](https://github.com/getsentry/sentry-java/pull/2593))
- We filter out some common cookies like JSESSIONID
- We also read the value from `server.servlet.session.cookie.name` and filter it out
Expand Down
1 change: 1 addition & 0 deletions sentry-jul/api/sentry-jul.api
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public final class io/sentry/jul/BuildConfig {
}

public class io/sentry/jul/SentryHandler : java/util/logging/Handler {
public static final field MECHANISM_TYPE Ljava/lang/String;
public static final field THREAD_ID Ljava/lang/String;
public fun <init> ()V
public fun <init> (Lio/sentry/SentryOptions;)V
Expand Down
9 changes: 8 additions & 1 deletion sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import io.sentry.SentryIntegrationPackageStorage;
import io.sentry.SentryLevel;
import io.sentry.SentryOptions;
import io.sentry.exception.ExceptionMechanismException;
import io.sentry.protocol.Mechanism;
import io.sentry.protocol.Message;
import io.sentry.protocol.SdkVersion;
import io.sentry.util.CollectionUtils;
Expand All @@ -34,6 +36,7 @@
/** Logging handler in charge of sending the java.util.logging records to a Sentry server. */
@Open
public class SentryHandler extends Handler {
public static final String MECHANISM_TYPE = "JulSentryHandler";
/** Name of the {@link SentryEvent} extra property containing the Thread id. */
public static final String THREAD_ID = "thread_id";
/**
Expand Down Expand Up @@ -196,7 +199,11 @@ SentryEvent createEvent(final @NotNull LogRecord record) {

final Throwable throwable = record.getThrown();
if (throwable != null) {
event.setThrowable(throwable);
final Mechanism mechanism = new Mechanism();
mechanism.setType(MECHANISM_TYPE);
final Throwable mechanismException =
new ExceptionMechanismException(mechanism, throwable, Thread.currentThread());
event.setThrowable(mechanismException);
}
Map<String, String> mdcProperties = MDC.getMDCAdapter().getCopyOfContextMap();
if (mdcProperties != null) {
Expand Down
16 changes: 16 additions & 0 deletions sentry-jul/src/test/kotlin/io/sentry/jul/SentryHandlerTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,22 @@ class SentryHandlerTest {
)
}

@Test
fun `converts severe log level to Sentry level with exception`() {
fixture = Fixture(minimumEventLevel = Level.SEVERE)
fixture.logger.log(Level.SEVERE, "testing error level", RuntimeException("test exc"))

verify(fixture.transport).send(
checkEvent { event ->
assertEquals(SentryLevel.ERROR, event.level)
val exception = event.exceptions!!.first()
assertEquals(SentryHandler.MECHANISM_TYPE, exception.mechanism!!.type)
assertEquals("test exc", exception.value)
},
anyOrNull()
)
}

@Test
fun `attaches thread information`() {
fixture = Fixture(minimumEventLevel = Level.WARNING)
Expand Down
1 change: 1 addition & 0 deletions sentry-log4j2/api/sentry-log4j2.api
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public final class io/sentry/log4j2/BuildConfig {
}

public class io/sentry/log4j2/SentryAppender : org/apache/logging/log4j/core/appender/AbstractAppender {
public static final field MECHANISM_TYPE Ljava/lang/String;
public fun <init> (Ljava/lang/String;Lorg/apache/logging/log4j/core/Filter;Ljava/lang/String;Lorg/apache/logging/log4j/Level;Lorg/apache/logging/log4j/Level;Ljava/lang/Boolean;Lio/sentry/ITransportFactory;Lio/sentry/IHub;[Ljava/lang/String;)V
public fun append (Lorg/apache/logging/log4j/core/LogEvent;)V
public static fun createAppender (Ljava/lang/String;Lorg/apache/logging/log4j/Level;Lorg/apache/logging/log4j/Level;Ljava/lang/String;Ljava/lang/Boolean;Lorg/apache/logging/log4j/core/Filter;Ljava/lang/String;)Lio/sentry/log4j2/SentryAppender;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import io.sentry.SentryIntegrationPackageStorage;
import io.sentry.SentryLevel;
import io.sentry.SentryOptions;
import io.sentry.exception.ExceptionMechanismException;
import io.sentry.protocol.Mechanism;
import io.sentry.protocol.Message;
import io.sentry.protocol.SdkVersion;
import io.sentry.util.CollectionUtils;
Expand All @@ -41,6 +43,8 @@
@Plugin(name = "Sentry", category = "Core", elementType = "appender", printObject = true)
@Open
public class SentryAppender extends AbstractAppender {
public static final String MECHANISM_TYPE = "Log4j2SentryAppender";

private final @Nullable String dsn;
private final @Nullable ITransportFactory transportFactory;
private @NotNull Level minimumBreadcrumbLevel = Level.INFO;
Expand Down Expand Up @@ -175,7 +179,12 @@ public void append(final @NotNull LogEvent eventObject) {

final ThrowableProxy throwableInformation = loggingEvent.getThrownProxy();
if (throwableInformation != null) {
event.setThrowable(throwableInformation.getThrowable());
final Mechanism mechanism = new Mechanism();
mechanism.setType(MECHANISM_TYPE);
final Throwable mechanismException =
new ExceptionMechanismException(
mechanism, throwableInformation.getThrowable(), Thread.currentThread());
event.setThrowable(mechanismException);
}

if (loggingEvent.getThreadName() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,22 @@ class SentryAppenderTest {
)
}

@Test
fun `converts error log level to Sentry level with exception`() {
val logger = fixture.getSut(minimumEventLevel = Level.ERROR)
logger.error("testing error level", RuntimeException("test exc"))

verify(fixture.transport).send(
checkEvent { event ->
assertEquals(SentryLevel.ERROR, event.level)
val exception = event.exceptions!!.first()
assertEquals(SentryAppender.MECHANISM_TYPE, exception.mechanism!!.type)
assertEquals("test exc", exception.value)
},
anyOrNull()
)
}

@Test
fun `converts fatal log level to Sentry level`() {
val logger = fixture.getSut(minimumEventLevel = Level.FATAL)
Expand Down
1 change: 1 addition & 0 deletions sentry-logback/api/sentry-logback.api
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public final class io/sentry/logback/BuildConfig {
}

public class io/sentry/logback/SentryAppender : ch/qos/logback/core/UnsynchronizedAppenderBase {
public static final field MECHANISM_TYPE Ljava/lang/String;
public fun <init> ()V
protected fun append (Lch/qos/logback/classic/spi/ILoggingEvent;)V
protected synthetic fun append (Ljava/lang/Object;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import io.sentry.SentryIntegrationPackageStorage;
import io.sentry.SentryLevel;
import io.sentry.SentryOptions;
import io.sentry.exception.ExceptionMechanismException;
import io.sentry.protocol.Mechanism;
import io.sentry.protocol.Message;
import io.sentry.protocol.SdkVersion;
import io.sentry.util.CollectionUtils;
Expand All @@ -37,6 +39,7 @@
/** Appender for logback in charge of sending the logged events to a Sentry server. */
@Open
public class SentryAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
public static final String MECHANISM_TYPE = "LogbackSentryAppender";
// WARNING: Do not use these options in here, they are only to be used for startup
private @NotNull SentryOptions options = new SentryOptions();
private @Nullable ITransportFactory transportFactory;
Expand Down Expand Up @@ -105,7 +108,12 @@ protected void append(@NotNull ILoggingEvent eventObject) {

final ThrowableProxy throwableInformation = (ThrowableProxy) loggingEvent.getThrowableProxy();
if (throwableInformation != null) {
event.setThrowable(throwableInformation.getThrowable());
final Mechanism mechanism = new Mechanism();
mechanism.setType(MECHANISM_TYPE);
final Throwable mechanismException =
new ExceptionMechanismException(
mechanism, throwableInformation.getThrowable(), Thread.currentThread());
event.setThrowable(mechanismException);
}

if (loggingEvent.getThreadName() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,22 @@ class SentryAppenderTest {
)
}

@Test
fun `converts error log level to Sentry level with exception`() {
fixture = Fixture(minimumEventLevel = Level.ERROR)
fixture.logger.error("testing error level", RuntimeException("test exc"))

verify(fixture.transport).send(
checkEvent { event ->
assertEquals(SentryLevel.ERROR, event.level)
val exception = event.exceptions!!.first()
assertEquals(SentryAppender.MECHANISM_TYPE, exception.mechanism!!.type)
assertEquals("test exc", exception.value)
},
anyOrNull()
)
}

@Test
fun `attaches thread information`() {
fixture = Fixture(minimumEventLevel = Level.WARN)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public PersonController(PersonService personService) {

@GetMapping("{id}")
Person person(@PathVariable Long id) {
LOGGER.info("Loading person with id={}", id);
LOGGER.error("Trying person with id={}", id, new RuntimeException("error while loading"));
throw new IllegalArgumentException("Something went wrong [id=" + id + "]");
}

Expand Down
1 change: 1 addition & 0 deletions sentry-spring-jakarta/api/sentry-spring-jakarta.api
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ public final class io/sentry/spring/jakarta/webflux/SentryScheduleHook : java/ut
}

public final class io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler : org/springframework/web/server/WebExceptionHandler {
public static final field MECHANISM_TYPE Ljava/lang/String;
public fun <init> (Lio/sentry/IHub;)V
public fun handle (Lorg/springframework/web/server/ServerWebExchange;Ljava/lang/Throwable;)Lreactor/core/publisher/Mono;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*/
@Open
public class SentryExceptionResolver implements HandlerExceptionResolver, Ordered {
public static final String MECHANISM_TYPE = "HandlerExceptionResolver";
public static final String MECHANISM_TYPE = "Spring6ExceptionResolver";

private final @NotNull IHub hub;
private final @NotNull TransactionNameProvider transactionNameProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
// at -1
@ApiStatus.Experimental
public final class SentryWebExceptionHandler implements WebExceptionHandler {
public static final String MECHANISM_TYPE = "Spring6WebFluxExceptionResolver";
private final @NotNull IHub hub;

public SentryWebExceptionHandler(final @NotNull IHub hub) {
Expand All @@ -44,7 +45,7 @@ public SentryWebExceptionHandler(final @NotNull IHub hub) {
it -> {
if (!(ex instanceof ResponseStatusException)) {
final Mechanism mechanism = new Mechanism();
mechanism.setType("SentryWebExceptionHandler");
mechanism.setType(MECHANISM_TYPE);
mechanism.setHandled(false);
final Throwable throwable =
new ExceptionMechanismException(mechanism, ex, Thread.currentThread());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class SentryExceptionResolverTest {
assertThat(eventCaptor.firstValue.throwableMechanism).isInstanceOf(ExceptionMechanismException::class.java)
with(eventCaptor.firstValue.throwableMechanism as ExceptionMechanismException) {
assertThat(exceptionMechanism.isHandled).isFalse
assertThat(exceptionMechanism.type).isEqualTo("HandlerExceptionResolver")
assertThat(exceptionMechanism.type).isEqualTo(SentryExceptionResolver.MECHANISM_TYPE)
assertThat(throwable).isEqualTo(expectedCause)
assertThat(thread).isEqualTo(Thread.currentThread())
assertThat(isSnapshot).isFalse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class SentryWebfluxIntegrationTest {
assertEquals("something went wrong", ex.value)
assertNotNull(ex.mechanism) {
assertThat(it.isHandled).isFalse()
assertThat(it.type).isEqualTo(SentryWebExceptionHandler.MECHANISM_TYPE)
}
}
},
Expand Down
1 change: 1 addition & 0 deletions sentry-spring/api/sentry-spring.api
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ public final class io/sentry/spring/webflux/SentryScheduleHook : java/util/funct
}

public final class io/sentry/spring/webflux/SentryWebExceptionHandler : org/springframework/web/server/WebExceptionHandler {
public static final field MECHANISM_TYPE Ljava/lang/String;
public fun <init> (Lio/sentry/IHub;)V
public fun handle (Lorg/springframework/web/server/ServerWebExchange;Ljava/lang/Throwable;)Lreactor/core/publisher/Mono;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*/
@Open
public class SentryExceptionResolver implements HandlerExceptionResolver, Ordered {
public static final String MECHANISM_TYPE = "HandlerExceptionResolver";
public static final String MECHANISM_TYPE = "Spring5ExceptionResolver";

private final @NotNull IHub hub;
private final @NotNull TransactionNameProvider transactionNameProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
// at -1
@ApiStatus.Experimental
public final class SentryWebExceptionHandler implements WebExceptionHandler {
public static final String MECHANISM_TYPE = "Spring5WebFluxExceptionResolver";
private final @NotNull IHub hub;

public SentryWebExceptionHandler(final @NotNull IHub hub) {
Expand All @@ -35,7 +36,7 @@ public SentryWebExceptionHandler(final @NotNull IHub hub) {
final @NotNull ServerWebExchange serverWebExchange, final @NotNull Throwable ex) {
if (!(ex instanceof ResponseStatusException)) {
final Mechanism mechanism = new Mechanism();
mechanism.setType("SentryWebExceptionHandler");
mechanism.setType(MECHANISM_TYPE);
mechanism.setHandled(false);
final Throwable throwable =
new ExceptionMechanismException(mechanism, ex, Thread.currentThread());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class SentryExceptionResolverTest {
assertThat(eventCaptor.firstValue.throwableMechanism).isInstanceOf(ExceptionMechanismException::class.java)
with(eventCaptor.firstValue.throwableMechanism as ExceptionMechanismException) {
assertThat(exceptionMechanism.isHandled).isFalse
assertThat(exceptionMechanism.type).isEqualTo("HandlerExceptionResolver")
assertThat(exceptionMechanism.type).isEqualTo(SentryExceptionResolver.MECHANISM_TYPE)
assertThat(throwable).isEqualTo(expectedCause)
assertThat(thread).isEqualTo(Thread.currentThread())
assertThat(isSnapshot).isFalse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class SentryWebfluxIntegrationTest {
assertEquals("something went wrong", ex.value)
assertNotNull(ex.mechanism) {
assertThat(it.isHandled).isFalse()
assertThat(it.type).isEqualTo(SentryWebExceptionHandler.MECHANISM_TYPE)
}
}
},
Expand Down