Custom grouping enhancements for java client

client: java
sdk: io.sentry:sentry-log4j2:1.7.30

we have an error log thrown in a library without a stacktrace and logging without place holders,
as a result, each log entry is seen as a separate issue.

Now i tried to force group them together with a custom grouping config: https://docs.sentry.io/data-management/event-grouping/grouping-enhancements/

however i’ve tried:
path:org.springframework.messaging.simp.stomp +group
module:org.springframework.messaging.simp.stomp +group
package:org.springframework.messaging.simp.stomp +group
And none of the above actually groups the new issues together.

So i’m wondering what matcher rule i could use to force group these issues together?

With log4j2, it’s expected that each log template will be grouped together. But not each time different variables values are used.

logger.info("User {} has logged in using id {}", map.get("Name"), user.getId());

In this case there should be 1 issue, regardless of the value of name and id.
Is that the case in your setup?

Please note that if a log message is recorded with a concatenated string as:

logger.info("User " + map.get("Name") + " has logged in using id " + user.getId());

Since it’s not possible for the SDK to know the template, grouping will happen only for the whole matching string.

Hi bruno-garcia

Unfortunately the actual log statement is in a library, and it doesn’t use templates, as a result grouping is done on the whole string, which contains a constantly changing element, meaning a new event per log event.

So i was hoping to solve this using the new feature of v10: custom grouping rules, hoping to group all errors of the class/package together, but it seems that non of the 3 possible matchers(path/module/package) is matching and this grouping them together.

So my question is: is there a field in the log event i can configure and then use in the

Hello @bmaassen, it’s hard to tell without looking at concrete data. Could you share two issue links that ought to be grouped together?

Thanks,
Markus

So this is how it looks like:

two sample event json’s:

{
	"event_id": "6191566d76fe45548648136022f726dd",
	"project": 4,
	"release": "20.7.2-0",
	"dist": null,
	"platform": "java",
	"message": "Received ERROR {message=[No subscription found], content-type=[text/plain], version=[1.0,1.1,1.2], content-length=[92]} session=31b61eb8, user=aaaa@gmail.com text/plain payload=UNSUBSCRIBE must refer to an existing subscription.\nSubscription to \"id='sub-0'\"...(truncated)",
	"datetime": "2020-07-24T14:12:46.000000Z",
	"tags": [
		[
			"environment",
			"production"
		],
		[
			"level",
			"error"
		],
		[
			"logger",
			"org.springframework.messaging.simp.stomp.StompBrokerRelayMess..."
		],
		[
			"namespace",
			"cm-c006"
		],
		[
			"release",
			"20.7.2-0"
		],
		[
			"server_name",
			"cm-c006-easy-cm-api-v2-76f9d4f8cc-hl5pr"
		]
	],
	"_meta": {
		"logger": {
			"": {
				"len": 71,
				"rem": [
					[
						"!limit",
						"s",
						61,
						64
					]
				]
			}
		}
	},
	"culprit": "",
	"environment": "production",
	"extra": {
		"Sentry-Threadname": "reactor-tcp-io-1",
		"log4j2-NDC": []
	},
	"fingerprint": [
		"{{ default }}"
	],
	"grouping_config": {
		"enhancements": "eJybzDhxY3J-bm5-npWRgaGlroGxrpHx5EkTbzFoFuQXpesVFxRl5qWnFSXmppbnF2Xr5aYWFyemA4X0ijNzC_SKS_JzCyYygNXnkqg-gHj1AMigQI4",
		"id": "newstyle:2019-10-29"
	},
	"hashes": [
		"1197de5cf25bb919c480d5ba9bba809b"
	],
	"key_id": "4",
	"level": "error",
	"logentry": {
		"formatted": "Received ERROR {message=[No subscription found], content-type=[text/plain], version=[1.0,1.1,1.2], content-length=[92]} session=31b61eb8, user=aaaa@gmail.com text/plain payload=UNSUBSCRIBE must refer to an existing subscription.\nSubscription to \"id='sub-0'\"...(truncated)"
	},
	"logger": "org.springframework.messaging.simp.stomp.StompBrokerRelayMess...",
	"metadata": {
		"title": "Received ERROR {message=[No subscription found], content-type=[text/plain], version=[1.0,1.1,1.2]..."
	},
	"received": 1595599968.202802,
	"sdk": {
		"version": "1.7.30-7a445",
		"name": "sentry-java",
		"integrations": [
			"log4j2"
		]
	},
	"timestamp": 1595599966.0,
	"title": "Received ERROR {message=[No subscription found], content-type=[text/plain], version=[1.0,1.1,1.2]...",
	"type": "default",
	"version": "6",
	"location": null
}

and

{
	"event_id": "4b8b6802816b44adbbfc2be7f5c70010",
	"project": 4,
	"release": "20.7.2-0",
	"dist": null,
	"platform": "java",
	"message": "Received ERROR {message=[No subscription found], content-type=[text/plain], version=[1.0,1.1,1.2], content-length=[92]} session=3da6c20d, user=bbbb@gmail.com text/plain payload=UNSUBSCRIBE must refer to an existing subscription.\nSubscription to \"id='sub-0'\"...(truncated)",
	"datetime": "2020-07-24T14:13:51.000000Z",
	"tags": [
		[
			"environment",
			"production"
		],
		[
			"level",
			"error"
		],
		[
			"logger",
			"org.springframework.messaging.simp.stomp.StompBrokerRelayMess..."
		],
		[
			"namespace",
			"cm-c006"
		],
		[
			"release",
			"20.7.2-0"
		],
		[
			"server_name",
			"cm-c006-easy-cm-api-v2-76f9d4f8cc-hl5pr"
		]
	],
	"_meta": {
		"logger": {
			"": {
				"len": 71,
				"rem": [
					[
						"!limit",
						"s",
						61,
						64
					]
				]
			}
		}
	},
	"culprit": "",
	"environment": "production",
	"extra": {
		"Sentry-Threadname": "reactor-tcp-io-1",
		"log4j2-NDC": []
	},
	"fingerprint": [
		"{{ default }}"
	],
	"grouping_config": {
		"enhancements": "eJybzDhxY3J-bm5-npWRgaGlroGxrpHx5EkTbzFoFuQXpesVFxRl5qWnFSXmppbnF2Xr5aYWFyemA4X0ijNzC_SKS_JzCyYygNXnkqg-gHj1AMigQI4",
		"id": "newstyle:2019-10-29"
	},
	"hashes": [
		"9a000678b844dc5bed3b5dcc52db4e6b"
	],
	"key_id": "4",
	"level": "error",
	"logentry": {
		"formatted": "Received ERROR {message=[No subscription found], content-type=[text/plain], version=[1.0,1.1,1.2], content-length=[92]} session=3da6c20d, user=bbbbb@gmail.com text/plain payload=UNSUBSCRIBE must refer to an existing subscription.\nSubscription to \"id='sub-0'\"...(truncated)"
	},
	"logger": "org.springframework.messaging.simp.stomp.StompBrokerRelayMess...",
	"metadata": {
		"title": "Received ERROR {message=[No subscription found], content-type=[text/plain], version=[1.0,1.1,1.2]..."
	},
	"received": 1595600032.299082,
	"sdk": {
		"version": "1.7.30-7a445",
		"name": "sentry-java",
		"integrations": [
			"log4j2"
		]
	},
	"timestamp": 1595600031.0,
	"title": "Received ERROR {message=[No subscription found], content-type=[text/plain], version=[1.0,1.1,1.2]...",
	"type": "default",
	"version": "6",
	"location": null
}

for privacy reasons i’ve changed the email addresses ofc

The actual code that logs(in a library so can’t change it)

if (logger.isErrorEnabled() && StompCommand.ERROR.equals(command)) {
	logger.error("Received " + accessor.getShortLogMessage(message.getPayload()));
}

Ahh I see! There’s no stacktrace here. That’s something we need to fix in the docs, but most of the matchers are referring to attributes on stacktrace frames. We are currently not able to match on the logger at all.

I think you’ll have to set a custom fingerprint on the sdk side, or hack around it on the server side using advanced data scrubbing (i.e. delete the data from the event that causes the messages to group differently, using a regex for example)

I’ll make a pr to update the docs

Thank you for the answer, applied a server side fingerprint

1 Like