Skip to content

Commit 64295f6

Browse files
adinauerlciangetsentry-bot
authored
Only set log template if message differs from template (#4682)
Co-authored-by: lcian <[email protected]> Co-authored-by: Sentry Github Bot <[email protected]>
1 parent 85d7417 commit 64295f6

File tree

7 files changed

+269
-9
lines changed

7 files changed

+269
-9
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
### Fixes
6+
7+
- Only set log template for logging integrations if formatted message differs from template ([#4682](https://github.com/getsentry/sentry-java/pull/4682))
8+
59
### Features
610

711
- Add support for Spring Boot 4 and Spring 7 ([#4601](https://github.com/getsentry/sentry-java/pull/4601))

sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,12 @@ protected void captureLog(@NotNull LogRecord loggingEvent) {
154154
message = loggingEvent.getResourceBundle().getString(loggingEvent.getMessage());
155155
}
156156

157-
attributes.add(SentryAttribute.stringAttribute("sentry.message.template", message));
158-
159157
final @NotNull String formattedMessage = maybeFormatted(arguments, message);
158+
159+
if (!formattedMessage.equals(message)) {
160+
attributes.add(SentryAttribute.stringAttribute("sentry.message.template", message));
161+
}
162+
160163
final @NotNull SentryLogParameters params = SentryLogParameters.create(attributes);
161164
params.setOrigin("auto.log.jul");
162165

sentry-jul/src/test/kotlin/io/sentry/jul/SentryHandlerTest.kt

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class SentryHandlerTest {
3535
val configureWithLogManager: Boolean = false,
3636
val transport: ITransport = mock(),
3737
contextTags: List<String>? = null,
38+
printfStyle: Boolean? = null,
3839
) {
3940
var logger: Logger
4041
var handler: SentryHandler
@@ -49,6 +50,9 @@ class SentryHandlerTest {
4950
handler.setMinimumBreadcrumbLevel(minimumBreadcrumbLevel)
5051
handler.setMinimumEventLevel(minimumEventLevel)
5152
handler.setMinimumLevel(minimumLevel)
53+
if (printfStyle == true) {
54+
handler.setPrintfStyle(printfStyle)
55+
}
5256
handler.level = Level.ALL
5357
logger.handlers.forEach { logger.removeHandler(it) }
5458
logger.addHandler(handler)
@@ -476,4 +480,79 @@ class SentryHandlerTest {
476480
verify(fixture.transport)
477481
.send(checkLogs { event -> assertEquals(SentryLogLevel.ERROR, event.items.first().level) })
478482
}
483+
484+
@Test
485+
fun `does not set template on log when logging message without parameters`() {
486+
fixture = Fixture(minimumLevel = Level.SEVERE)
487+
fixture.logger.severe("testing message without parameters")
488+
489+
Sentry.flush(1000)
490+
491+
verify(fixture.transport)
492+
.send(
493+
checkLogs { logs ->
494+
val log = logs.items.first()
495+
assertEquals("testing message without parameters", log.body)
496+
assertNull(log.attributes?.get("sentry.message.template"))
497+
}
498+
)
499+
}
500+
501+
@Test
502+
fun `sets template on log when logging message with parameters`() {
503+
fixture = Fixture(minimumLevel = Level.SEVERE)
504+
fixture.logger.log(Level.SEVERE, "testing message {0}", arrayOf("param"))
505+
506+
Sentry.flush(1000)
507+
508+
verify(fixture.transport)
509+
.send(
510+
checkLogs { logs ->
511+
val log = logs.items.first()
512+
assertEquals("testing message param", log.body)
513+
assertEquals("testing message {0}", log.attributes?.get("sentry.message.template")?.value)
514+
assertEquals("param", log.attributes?.get("sentry.message.parameter.0")?.value)
515+
}
516+
)
517+
}
518+
519+
@Test
520+
fun `sets template on log when logging message with parameters and using printfStyle`() {
521+
fixture = Fixture(minimumLevel = Level.SEVERE, printfStyle = true)
522+
fixture.logger.log(Level.SEVERE, "testing message %s", arrayOf("param"))
523+
524+
Sentry.flush(1000)
525+
526+
verify(fixture.transport)
527+
.send(
528+
checkLogs { logs ->
529+
val log = logs.items.first()
530+
assertEquals("testing message param", log.body)
531+
assertEquals("testing message %s", log.attributes?.get("sentry.message.template")?.value)
532+
assertEquals("param", log.attributes?.get("sentry.message.parameter.0")?.value)
533+
}
534+
)
535+
}
536+
537+
@Test
538+
fun `sets template on log when logging message with parameters and formatting fails`() {
539+
fixture = Fixture(minimumLevel = Level.SEVERE, printfStyle = true)
540+
fixture.logger.log(Level.SEVERE, "testing message %d %d", arrayOf(1))
541+
542+
Sentry.flush(1000)
543+
544+
verify(fixture.transport)
545+
.send(
546+
checkLogs { logs ->
547+
val log = logs.items.first()
548+
assertEquals("testing message %d %d", log.body)
549+
assertEquals(
550+
"testing message %d %d",
551+
log.attributes?.get("sentry.message.template")?.value,
552+
)
553+
assertEquals(1, log.attributes?.get("sentry.message.parameter.0")?.value)
554+
assertNull(log.attributes?.get("sentry.message.parameter.1"))
555+
}
556+
)
557+
}
479558
}

sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,14 @@ protected void captureLog(@NotNull LogEvent loggingEvent) {
222222
final @Nullable Object[] arguments = loggingEvent.getMessage().getParameters();
223223
final @NotNull SentryAttributes attributes = SentryAttributes.of();
224224

225-
attributes.add(
226-
SentryAttribute.stringAttribute(
227-
"sentry.message.template", loggingEvent.getMessage().getFormat()));
228-
225+
final @Nullable String nonFormattedMessage = loggingEvent.getMessage().getFormat();
229226
final @NotNull String formattedMessage = loggingEvent.getMessage().getFormattedMessage();
227+
228+
if (nonFormattedMessage != null && !formattedMessage.equals(nonFormattedMessage)) {
229+
attributes.add(
230+
SentryAttribute.stringAttribute("sentry.message.template", nonFormattedMessage));
231+
}
232+
230233
final @NotNull SentryLogParameters params = SentryLogParameters.create(attributes);
231234
params.setOrigin("auto.log.log4j2");
232235

sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,4 +533,62 @@ class SentryAppenderTest {
533533
fixture.getSut(debug = true)
534534
assertTrue(ScopesAdapter.getInstance().options.isDebug)
535535
}
536+
537+
@Test
538+
fun `does not set template on log when logging message without parameters`() {
539+
val logger = fixture.getSut(minimumLevel = Level.ERROR)
540+
logger.error("testing message without parameters")
541+
542+
Sentry.flush(1000)
543+
544+
verify(fixture.transport)
545+
.send(
546+
checkLogs { logs ->
547+
val log = logs.items.first()
548+
assertEquals("testing message without parameters", log.body)
549+
assertNull(log.attributes?.get("sentry.message.template"))
550+
}
551+
)
552+
}
553+
554+
@Test
555+
fun `sets template on log when logging message with parameters`() {
556+
val logger = fixture.getSut(minimumLevel = Level.ERROR)
557+
logger.error("testing message {}", "param")
558+
559+
Sentry.flush(1000)
560+
561+
verify(fixture.transport)
562+
.send(
563+
checkLogs { logs ->
564+
val log = logs.items.first()
565+
assertEquals("testing message param", log.body)
566+
assertEquals("testing message {}", log.attributes?.get("sentry.message.template")?.value)
567+
assertEquals("param", log.attributes?.get("sentry.message.parameter.0")?.value)
568+
}
569+
)
570+
}
571+
572+
@Test
573+
fun `sets template on log when logging message with parameters and number of parameters is wrong`() {
574+
val logger = fixture.getSut(minimumLevel = Level.ERROR)
575+
logger.error("testing message {} {} {}", "param1", "param2")
576+
577+
Sentry.flush(1000)
578+
579+
verify(fixture.transport)
580+
.send(
581+
checkLogs { logs ->
582+
val log = logs.items.first()
583+
assertEquals("testing message param1 param2 {}", log.body)
584+
assertEquals(
585+
"testing message {} {} {}",
586+
log.attributes?.get("sentry.message.template")?.value,
587+
)
588+
assertEquals("param1", log.attributes?.get("sentry.message.parameter.0")?.value)
589+
assertEquals("param2", log.attributes?.get("sentry.message.parameter.1")?.value)
590+
assertNull(log.attributes?.get("sentry.message.parameter.2"))
591+
}
592+
)
593+
}
536594
}

sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,18 @@ protected void captureLog(@NotNull ILoggingEvent loggingEvent) {
183183

184184
@Nullable Object[] arguments = null;
185185
final @NotNull SentryAttributes attributes = SentryAttributes.of();
186+
final @NotNull String formattedMessage = formatted(loggingEvent);
186187

187188
// if encoder is set we treat message+params as PII as encoders may be used to mask/strip PII
188189
if (encoder == null || ScopesAdapter.getInstance().getOptions().isSendDefaultPii()) {
189-
attributes.add(
190-
SentryAttribute.stringAttribute("sentry.message.template", loggingEvent.getMessage()));
190+
final @Nullable String nonFormattedMessage = loggingEvent.getMessage();
191+
if (nonFormattedMessage != null && !formattedMessage.equals(nonFormattedMessage)) {
192+
attributes.add(
193+
SentryAttribute.stringAttribute("sentry.message.template", nonFormattedMessage));
194+
}
191195
arguments = loggingEvent.getArgumentArray();
192196
}
193197

194-
final @NotNull String formattedMessage = formatted(loggingEvent);
195198
final @NotNull SentryLogParameters params = SentryLogParameters.create(attributes);
196199
params.setOrigin("auto.log.logback");
197200

sentry-logback/src/test/kotlin/io/sentry/logback/SentryAppenderTest.kt

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,4 +711,114 @@ class SentryAppenderTest {
711711
anyOrNull(),
712712
)
713713
}
714+
715+
@Test
716+
fun `does not set template on log when logging message without parameters`() {
717+
fixture = Fixture(minimumLevel = Level.ERROR, enableLogs = true)
718+
fixture.logger.error("testing message without parameters")
719+
720+
Sentry.flush(1000)
721+
722+
verify(fixture.transport)
723+
.send(
724+
checkLogs { logs ->
725+
val log = logs.items.first()
726+
assertEquals("testing message without parameters", log.body)
727+
assertNull(log.attributes?.get("sentry.message.template"))
728+
}
729+
)
730+
}
731+
732+
@Test
733+
fun `sets template on log when logging message with parameters`() {
734+
fixture = Fixture(minimumLevel = Level.ERROR, enableLogs = true)
735+
fixture.logger.error("testing message {}", "param")
736+
737+
Sentry.flush(1000)
738+
739+
verify(fixture.transport)
740+
.send(
741+
checkLogs { logs ->
742+
val log = logs.items.first()
743+
assertEquals("testing message param", log.body)
744+
assertEquals("testing message {}", log.attributes?.get("sentry.message.template")?.value)
745+
assertEquals("param", log.attributes?.get("sentry.message.parameter.0")?.value)
746+
}
747+
)
748+
}
749+
750+
@Test
751+
fun `sets template on log when logging message with parameters and number of parameters is wrong`() {
752+
fixture = Fixture(minimumLevel = Level.ERROR, enableLogs = true)
753+
fixture.logger.error("testing message {} {} {}", "param1", "param2")
754+
755+
Sentry.flush(1000)
756+
757+
verify(fixture.transport)
758+
.send(
759+
checkLogs { logs ->
760+
val log = logs.items.first()
761+
assertEquals("testing message param1 param2 {}", log.body)
762+
assertEquals(
763+
"testing message {} {} {}",
764+
log.attributes?.get("sentry.message.template")?.value,
765+
)
766+
assertEquals("param1", log.attributes?.get("sentry.message.parameter.0")?.value)
767+
assertEquals("param2", log.attributes?.get("sentry.message.parameter.1")?.value)
768+
assertNull(log.attributes?.get("sentry.message.parameter.2"))
769+
}
770+
)
771+
}
772+
773+
@Test
774+
fun `does not set template or attributes on log with encoder when sendDefaultPii is false`() {
775+
var encoder = PatternLayoutEncoder()
776+
encoder.pattern = "encoded %msg"
777+
fixture =
778+
Fixture(
779+
minimumLevel = Level.ERROR,
780+
enableLogs = true,
781+
encoder = encoder,
782+
sendDefaultPii = false,
783+
)
784+
fixture.logger.error("testing message {}", "param")
785+
786+
Sentry.flush(1000)
787+
788+
verify(fixture.transport)
789+
.send(
790+
checkLogs { logs ->
791+
val log = logs.items.first()
792+
assertEquals("encoded testing message param", log.body)
793+
assertNull(log.attributes?.get("sentry.message.template"))
794+
assertNull(log.attributes?.get("sentry.message.parameter.0"))
795+
}
796+
)
797+
}
798+
799+
@Test
800+
fun `sets template and attributes on log with encoder when sendDefaultPii is true`() {
801+
var encoder = PatternLayoutEncoder()
802+
encoder.pattern = "encoded %msg"
803+
fixture =
804+
Fixture(
805+
minimumLevel = Level.ERROR,
806+
enableLogs = true,
807+
encoder = encoder,
808+
sendDefaultPii = true,
809+
)
810+
fixture.logger.error("testing message {}", "param")
811+
812+
Sentry.flush(1000)
813+
814+
verify(fixture.transport)
815+
.send(
816+
checkLogs { logs ->
817+
val log = logs.items.first()
818+
assertEquals("encoded testing message param", log.body)
819+
assertEquals("testing message {}", log.attributes?.get("sentry.message.template")?.value)
820+
assertEquals("param", log.attributes?.get("sentry.message.parameter.0")?.value)
821+
}
822+
)
823+
}
714824
}

0 commit comments

Comments
 (0)