Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

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

### Features

- Add an explicit Logs opt-in to Spring Boot logging auto-configuration ([#5946](https://github.com/getsentry/sentry-java/pull/5946))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add the concrete opt-in flags to the changelog when merging the stack?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes we should list them for easier migration

- Add an explicit Logs opt-in to the Android Logcat integration ([#5945](https://github.com/getsentry/sentry-java/pull/5945))
- Add an explicit Logs opt-in to the Android Timber integration ([#5943](https://github.com/getsentry/sentry-java/pull/5943))
- Add an explicit Logs opt-in to the JUL handler ([#5942](https://github.com/getsentry/sentry-java/pull/5942))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ sentry.enable-backpressure-handling=true
sentry.enable-spotlight=true
sentry.enablePrettySerializationOutput=false
sentry.logs.enabled=true
sentry.logging.enable-logs=true
sentry.in-app-includes="io.sentry.samples"
sentry.profile-session-sample-rate=1.0
sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ sentry.enable-backpressure-handling=true
sentry.enable-spotlight=true
sentry.enablePrettySerializationOutput=false
sentry.logs.enabled=true
sentry.logging.enable-logs=true
sentry.in-app-includes="io.sentry.samples"
sentry.profile-session-sample-rate=1.0
sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ sentry.enable-spotlight=true
sentry.enablePrettySerializationOutput=false
sentry.in-app-includes="io.sentry.samples"
sentry.logs.enabled=true
sentry.logging.enable-logs=true
sentry.profile-session-sample-rate=1.0
sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces
sentry.profile-lifecycle=TRACE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ sentry.reactive.thread-local-accessor-enabled=true
sentry.traces-sample-rate=1.0
sentry.enable-backpressure-handling=true
sentry.logs.enabled=true
sentry.logging.enable-logs=true
sentry.enable-spotlight=true
sentry.profile-session-sample-rate=1.0
sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ sentry.enable-spotlight=true
sentry.enablePrettySerializationOutput=false
sentry.in-app-includes="io.sentry.samples"
sentry.logs.enabled=true
sentry.logging.enable-logs=true
sentry.profile-session-sample-rate=1.0
sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces
sentry.profile-lifecycle=TRACE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ sentry.enable-backpressure-handling=true
sentry.enable-spotlight=true
sentry.enablePrettySerializationOutput=false
sentry.logs.enabled=true
sentry.logging.enable-logs=true
sentry.in-app-includes="io.sentry.samples"
sentry.profile-session-sample-rate=1.0
sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ sentry.enable-backpressure-handling=true
sentry.enable-spotlight=true
sentry.enablePrettySerializationOutput=false
sentry.logs.enabled=true
sentry.logging.enable-logs=true
sentry.in-app-includes="io.sentry.samples"
sentry.profile-session-sample-rate=1.0
sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ sentry.enable-spotlight=false
sentry.enablePrettySerializationOutput=false
sentry.in-app-includes="io.sentry.samples"
sentry.logs.enabled=true
sentry.logging.enable-logs=true
sentry.profile-session-sample-rate=1.0
sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces
sentry.profile-lifecycle=TRACE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ sentry.graphql.ignored-error-types=SOME_ERROR,ANOTHER_ERROR
sentry.enable-backpressure-handling=true
sentry.enable-spotlight=true
sentry.logs.enabled=true
sentry.logging.enable-logs=true
sentry.in-app-includes="io.sentry.samples"
sentry.profile-session-sample-rate=1.0
sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ sentry.graphql.ignored-error-types=SOME_ERROR,ANOTHER_ERROR
sentry.enable-backpressure-handling=true
sentry.enable-spotlight=true
sentry.logs.enabled=true
sentry.logging.enable-logs=true
sentry.in-app-includes="io.sentry.samples"
sentry.profile-session-sample-rate=1.0
sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ sentry.reactive.thread-local-accessor-enabled=true
sentry.traces-sample-rate=1.0
sentry.enable-backpressure-handling=true
sentry.logs.enabled=true
sentry.logging.enable-logs=true
sentry.enable-spotlight=true
sentry.in-app-includes="io.sentry.samples"
sentry.profile-session-sample-rate=1.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ spring.graphql.websocket.path=/graphql
spring.graphql.schema.printer.enabled=true
sentry.enable-backpressure-handling=true
sentry.logs.enabled=true
sentry.logging.enable-logs=true
sentry.enable-spotlight=true
sentry.in-app-includes="io.sentry.samples"
sentry.profile-session-sample-rate=1.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ sentry.graphql.ignored-error-types=SOME_ERROR,ANOTHER_ERROR
sentry.enable-backpressure-handling=true
sentry.enable-spotlight=true
sentry.logs.enabled=true
sentry.logging.enable-logs=true
sentry.in-app-includes="io.sentry.samples"
sentry.profile-session-sample-rate=1.0
sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces
Expand Down
2 changes: 2 additions & 0 deletions sentry-spring-boot-4/api/sentry-spring-boot-4.api
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ public class io/sentry/spring/boot4/SentryProperties$Logging {
public fun getMinimumBreadcrumbLevel ()Lorg/slf4j/event/Level;
public fun getMinimumEventLevel ()Lorg/slf4j/event/Level;
public fun getMinimumLevel ()Lorg/slf4j/event/Level;
public fun isEnableLogs ()Z
public fun isEnabled ()Z
public fun setEnableLogs (Z)V
public fun setEnabled (Z)V
public fun setLoggers (Ljava/util/List;)V
public fun setMinimumBreadcrumbLevel (Lorg/slf4j/event/Level;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public void onApplicationEvent(final @NotNull ApplicationEvent event) {
toLog4jLevel(sentryProperties.getLogging().getMinimumBreadcrumbLevel()),
toLog4jLevel(sentryProperties.getLogging().getMinimumEventLevel()),
toLog4jLevel(sentryProperties.getLogging().getMinimumLevel()),
sentryProperties.getLogging().isEnableLogs(),
null,
null,
ScopesAdapter.getInstance(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public void onApplicationEvent(final @NotNull ApplicationEvent event) {
if (!isSentryAppenderRegistered(logger)) {
final SentryAppender sentryAppender = getSentryAppender();

sentryAppender.setEnableLogs(sentryProperties.getLogging().isEnableLogs());
Optional.ofNullable(sentryProperties.getLogging().getMinimumBreadcrumbLevel())
.map(slf4jLevel -> Level.toLevel(slf4jLevel.name()))
.ifPresent(sentryAppender::setMinimumBreadcrumbLevel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ public static class Logging {
/** Enable/Disable logging auto-configuration. */
private boolean enabled = true;

/** Enable/Disable Sentry Logs capture from the auto-configured appender. */
private boolean enableLogs = false;

/** Minimum logging level for recording breadcrumbs. */
private @Nullable Level minimumBreadcrumbLevel;

Expand All @@ -149,6 +152,14 @@ public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public boolean isEnableLogs() {
return enableLogs;
}

public void setEnableLogs(boolean enableLogs) {
this.enableLogs = enableLogs;
}
Comment thread
cursor[bot] marked this conversation as resolved.

public @Nullable Level getMinimumBreadcrumbLevel() {
return minimumBreadcrumbLevel;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ class SentryAutoConfigurationTest {
"sentry.cron.default-failure-issue-threshold=40",
"sentry.cron.default-recovery-threshold=50",
"sentry.logs.enabled=true",
"sentry.logging.enable-logs=true",
"sentry.strict-trace-continuation=true",
"sentry.org-id=12345",
)
Expand Down Expand Up @@ -302,6 +303,7 @@ class SentryAutoConfigurationTest {
assertThat(options.cron!!.defaultFailureIssueThreshold).isEqualTo(40L)
assertThat(options.cron!!.defaultRecoveryThreshold).isEqualTo(50L)
assertThat(options.logs.isEnabled).isEqualTo(true)
assertThat(options.logging.isEnableLogs).isTrue()
assertThat(options.isStrictTraceContinuation).isEqualTo(true)
assertThat(options.orgId).isEqualTo("12345")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import ch.qos.logback.core.read.ListAppender
import io.sentry.ITransportFactory
import io.sentry.NoOpTransportFactory
import io.sentry.ScopesAdapter
import io.sentry.Sentry
import io.sentry.checkLogs
import io.sentry.log4j2.SentryAppender
import io.sentry.transport.ITransport
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test
Expand All @@ -17,6 +20,11 @@ import org.apache.logging.log4j.core.LoggerContext
import org.apache.logging.log4j.core.config.DefaultConfiguration
import org.apache.logging.log4j.core.config.LoggerConfig
import org.assertj.core.api.Assertions.assertThat
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.AutoConfigurations
import org.springframework.boot.test.context.FilteredClassLoader
Expand Down Expand Up @@ -63,6 +71,16 @@ class SentryLog4j2AppenderAutoConfigurationTest {

private val dsnEnabledRunner = dsnOnlyRunner.withPropertyValues("sentry.logging.enabled=true")

private val logsRunner =
baseContextRunner
.withLog4j2CoreProvider()
.withPropertyValues(
"sentry.dsn=http://key@localhost/proj",
"sentry.logging.enabled=true",
"sentry.logs.enabled=true",
)
.withUserConfiguration(MockTransportConfiguration::class.java)

// Hide the Log4j2 Core provider so LogManager uses the Log4j-to-SLF4J bridge.
private val log4j2BridgeDsnEnabledRunner =
baseContextRunner
Expand Down Expand Up @@ -181,6 +199,29 @@ class SentryLog4j2AppenderAutoConfigurationTest {
}
}

@Test
fun `forwards Sentry Logs when enabled`() {
logsRunner.withPropertyValues("sentry.logging.enable-logs=true").run {
LogManager.getLogger("io.sentry.spring.boot4.logs-enabled").error("enabled log")
Sentry.flush(1000)

val transport = it.getBean(ITransport::class.java)
verify(transport)
.send(checkLogs { logs -> assertThat(logs.items.single().body).isEqualTo("enabled log") })
}
}

@Test
fun `does not forward Sentry Logs by default`() {
logsRunner.run {
LogManager.getLogger("io.sentry.spring.boot4.logs-disabled").error("disabled log")
Sentry.flush(1000)

val transport = it.getBean(ITransport::class.java)
verify(transport, never()).send(checkLogs {})
}
}

@Test
fun `does not configure SentryAppender when logging is disabled`() {
dsnEnabledRunner.withPropertyValues("sentry.logging.enabled=false").run {
Expand Down Expand Up @@ -251,6 +292,21 @@ class SentryLog4j2AppenderAutoConfigurationTest {
.run { assertThat(rootLogger.getAppenders(SentryAppender::class.java)).isEmpty() }
}

@Configuration(proxyBeanMethods = false)
open class MockTransportConfiguration {

private val transport = mock<ITransport>()

@Bean
open fun mockTransportFactory(): ITransportFactory {
val factory = mock<ITransportFactory>()
whenever(factory.create(any(), any())).thenReturn(transport)
return factory
}

@Bean open fun sentryTransport() = transport
}

@Configuration(proxyBeanMethods = false)
open class NoOpTransportConfiguration {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class SentryLogbackAppenderAutoConfigurationTest {
"sentry.logging.minimum-event-level=info",
"sentry.logging.minimum-breadcrumb-level=debug",
"sentry.logging.minimum-level=error",
"sentry.logging.enable-logs=true",
)
.run {
val appenders = rootLogger.getAppenders(SentryAppender::class.java)
Expand All @@ -121,9 +122,19 @@ class SentryLogbackAppenderAutoConfigurationTest {
assertThat(sentryAppender.minimumBreadcrumbLevel).isEqualTo(Level.DEBUG)
assertThat(sentryAppender.minimumEventLevel).isEqualTo(Level.INFO)
assertThat(sentryAppender.minimumLevel).isEqualTo(Level.ERROR)
assertThat(sentryAppender.isEnableLogs).isTrue()
}
}

@Test
fun `SentryAppender Logs are disabled by default`() {
dsnEnabledRunner.run {
val sentryAppender = rootLogger.getAppenders(SentryAppender::class.java).single()

assertThat((sentryAppender as SentryAppender).isEnableLogs).isFalse()
}
}

@Test
fun `does not configure SentryAppender when logging is disabled`() {
contextRunner.withPropertyValues("sentry.logging.enabled=false").run {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ public class io/sentry/spring/boot/jakarta/SentryProperties$Logging {
public fun getMinimumBreadcrumbLevel ()Lorg/slf4j/event/Level;
public fun getMinimumEventLevel ()Lorg/slf4j/event/Level;
public fun getMinimumLevel ()Lorg/slf4j/event/Level;
public fun isEnableLogs ()Z
public fun isEnabled ()Z
public fun setEnableLogs (Z)V
public fun setEnabled (Z)V
public fun setLoggers (Ljava/util/List;)V
public fun setMinimumBreadcrumbLevel (Lorg/slf4j/event/Level;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public void onApplicationEvent(final @NotNull ApplicationEvent event) {
toLog4jLevel(sentryProperties.getLogging().getMinimumBreadcrumbLevel()),
toLog4jLevel(sentryProperties.getLogging().getMinimumEventLevel()),
toLog4jLevel(sentryProperties.getLogging().getMinimumLevel()),
sentryProperties.getLogging().isEnableLogs(),
null,
null,
ScopesAdapter.getInstance(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public void onApplicationEvent(final @NotNull ApplicationEvent event) {
if (!isSentryAppenderRegistered(logger)) {
final SentryAppender sentryAppender = getSentryAppender();

sentryAppender.setEnableLogs(sentryProperties.getLogging().isEnableLogs());
Optional.ofNullable(sentryProperties.getLogging().getMinimumBreadcrumbLevel())
.map(slf4jLevel -> Level.toLevel(slf4jLevel.name()))
.ifPresent(sentryAppender::setMinimumBreadcrumbLevel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ public static class Logging {
/** Enable/Disable logging auto-configuration. */
private boolean enabled = true;

/** Enable/Disable Sentry Logs capture from the auto-configured appender. */
private boolean enableLogs = false;

/** Minimum logging level for recording breadcrumbs. */
private @Nullable Level minimumBreadcrumbLevel;

Expand All @@ -149,6 +152,14 @@ public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public boolean isEnableLogs() {
return enableLogs;
}

public void setEnableLogs(boolean enableLogs) {
this.enableLogs = enableLogs;
}

public @Nullable Level getMinimumBreadcrumbLevel() {
return minimumBreadcrumbLevel;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ class SentryAutoConfigurationTest {
"sentry.cron.default-failure-issue-threshold=40",
"sentry.cron.default-recovery-threshold=50",
"sentry.logs.enabled=true",
"sentry.logging.enable-logs=true",
"sentry.profile-session-sample-rate=1.0",
"sentry.profiling-traces-dir-path=tmp/sentry/profiling-traces",
"sentry.profile-lifecycle=TRACE",
Expand Down Expand Up @@ -306,6 +307,7 @@ class SentryAutoConfigurationTest {
assertThat(options.cron!!.defaultFailureIssueThreshold).isEqualTo(40L)
assertThat(options.cron!!.defaultRecoveryThreshold).isEqualTo(50L)
assertThat(options.logs.isEnabled).isEqualTo(true)
assertThat(options.logging.isEnableLogs).isTrue()
assertThat(options.profileSessionSampleRate).isEqualTo(1.0)
assertThat(options.profilingTracesDirPath)
.startsWith(File("tmp/sentry/profiling-traces").absolutePath)
Expand Down
Loading
Loading