From 0cc3de457c3d4f3bc197a04621e8b5718745c350 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Thu, 12 Jun 2025 11:41:58 +0200 Subject: [PATCH 01/14] Add user id, username and email to log attributes --- .../main/java/io/sentry/logger/LoggerApi.java | 23 +++++++ .../main/java/io/sentry/protocol/User.java | 10 ++- sentry/src/test/java/io/sentry/ScopesTest.kt | 63 +++++++++++++++++++ 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/sentry/src/main/java/io/sentry/logger/LoggerApi.java b/sentry/src/main/java/io/sentry/logger/LoggerApi.java index 71eccb4840..6a904e96c3 100644 --- a/sentry/src/main/java/io/sentry/logger/LoggerApi.java +++ b/sentry/src/main/java/io/sentry/logger/LoggerApi.java @@ -17,6 +17,7 @@ import io.sentry.SpanId; import io.sentry.protocol.SdkVersion; import io.sentry.protocol.SentryId; +import io.sentry.protocol.User; import io.sentry.util.Platform; import io.sentry.util.TracingUtils; import java.util.HashMap; @@ -213,6 +214,10 @@ private void captureLog( setServerName(attributes); } + if (scopes.getOptions().isSendDefaultPii()) { + setUser(attributes); + } + return attributes; } @@ -231,6 +236,24 @@ private void setServerName( } } + private void setUser(final @NotNull HashMap attributes) { + final @Nullable User user = scopes.getCombinedScopeView().getUser(); + if (user != null) { + final @Nullable String id = user.getId(); + if (id != null) { + attributes.put("user.id", new SentryLogEventAttributeValue("string", id)); + } + final @Nullable String username = user.getUsername(); + if (username != null) { + attributes.put("user.name", new SentryLogEventAttributeValue("string", username)); + } + final @Nullable String email = user.getEmail(); + if (email != null) { + attributes.put("user.email", new SentryLogEventAttributeValue("string", email)); + } + } + } + private @NotNull SentryAttributeType getType(final @Nullable Object arg) { if (arg instanceof Boolean) { return SentryAttributeType.BOOLEAN; diff --git a/sentry/src/main/java/io/sentry/protocol/User.java b/sentry/src/main/java/io/sentry/protocol/User.java index e19525eefc..0035f85c21 100644 --- a/sentry/src/main/java/io/sentry/protocol/User.java +++ b/sentry/src/main/java/io/sentry/protocol/User.java @@ -37,8 +37,10 @@ public final class User implements JsonUnknown, JsonSerializable { /** Remote IP address of the user. */ private @Nullable String ipAddress; - /** Human readable name. */ - private @Nullable String name; + /** + * @deprecated please use {@link User#username} Human readable name. + */ + @Deprecated private @Nullable String name; /** User geo location. */ private @Nullable Geo geo; @@ -215,7 +217,9 @@ public void setIpAddress(final @Nullable String ipAddress) { * Get human readable name. * * @return Human readable name + * @deprecated please use {@link User#getUsername()} */ + @Deprecated public @Nullable String getName() { return name; } @@ -224,7 +228,9 @@ public void setIpAddress(final @Nullable String ipAddress) { * Set human readable name. * * @param name Human readable name + * @deprecated please use {@link User#setUsername(String)} */ + @Deprecated public void setName(final @Nullable String name) { this.name = name; } diff --git a/sentry/src/test/java/io/sentry/ScopesTest.kt b/sentry/src/test/java/io/sentry/ScopesTest.kt index 49a9500216..f0dec629de 100644 --- a/sentry/src/test/java/io/sentry/ScopesTest.kt +++ b/sentry/src/test/java/io/sentry/ScopesTest.kt @@ -2851,6 +2851,69 @@ class ScopesTest { ) } + @Test + fun `adds user fields to log attributes if sendDefaultPii is true`() { + val (sut, mockClient) = getEnabledScopes { + it.logs.isEnabled = true + it.isSendDefaultPii = true + } + + sut.configureScope { scope -> + scope.user = User().also { + it.id = "usrid" + it.username = "usrname" + it.email = "user@sentry.io" + } + } + sut.logger().log(SentryLogLevel.WARN, "log message") + + verify(mockClient).captureLog( + check { + assertEquals("log message", it.body) + + val userId = it.attributes?.get("user.id")!! + assertEquals("usrid", userId.value) + assertEquals("string", userId.type) + + val userName = it.attributes?.get("user.name")!! + assertEquals("usrname", userName.value) + assertEquals("string", userName.type) + + val userEmail = it.attributes?.get("user.email")!! + assertEquals("user@sentry.io", userEmail.value) + assertEquals("string", userEmail.type) + }, + anyOrNull() + ) + } + + @Test + fun `does not add user fields to log attributes by default`() { + val (sut, mockClient) = getEnabledScopes { + it.logs.isEnabled = true + } + + sut.configureScope { scope -> + scope.user = User().also { + it.id = "usrid" + it.username = "usrname" + it.email = "user@sentry.io" + } + } + sut.logger().log(SentryLogLevel.WARN, "log message") + + verify(mockClient).captureLog( + check { + assertEquals("log message", it.body) + + assertNull(it.attributes?.get("user.id")) + assertNull(it.attributes?.get("user.name")) + assertNull(it.attributes?.get("user.email")) + }, + anyOrNull() + ) + } + //endregion @Test From 57e7d5cca04e4b1cbea991a456dae66f8350b615 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Mon, 16 Jun 2025 14:15:06 +0200 Subject: [PATCH 02/14] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71abe457e8..fee869d5e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ SentryUserFeedbackDialog.Builder(context).create().show() ``` +- Add `user.id`, `user.name` and `user.email` to log attributes ([#4486](https://github.com/getsentry/sentry-java/pull/4486)) ## 8.13.3 From 5900c4e4eea309e93be21d4dce1a1db94aa1e119 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Mon, 16 Jun 2025 14:15:16 +0200 Subject: [PATCH 03/14] use enum for attribute type --- .../main/java/io/sentry/logger/LoggerApi.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sentry/src/main/java/io/sentry/logger/LoggerApi.java b/sentry/src/main/java/io/sentry/logger/LoggerApi.java index 6a904e96c3..1a2d2c9bc7 100644 --- a/sentry/src/main/java/io/sentry/logger/LoggerApi.java +++ b/sentry/src/main/java/io/sentry/logger/LoggerApi.java @@ -185,30 +185,30 @@ private void captureLog( } if (i > 0) { attributes.put( - "sentry.message.template", new SentryLogEventAttributeValue("string", message)); + "sentry.message.template", new SentryLogEventAttributeValue(SentryAttributeType.STRING, message)); } } final @Nullable SdkVersion sdkVersion = scopes.getOptions().getSdkVersion(); if (sdkVersion != null) { attributes.put( - "sentry.sdk.name", new SentryLogEventAttributeValue("string", sdkVersion.getName())); + "sentry.sdk.name", new SentryLogEventAttributeValue(SentryAttributeType.STRING, sdkVersion.getName())); attributes.put( "sentry.sdk.version", - new SentryLogEventAttributeValue("string", sdkVersion.getVersion())); + new SentryLogEventAttributeValue(SentryAttributeType.STRING, sdkVersion.getVersion())); } final @Nullable String environment = scopes.getOptions().getEnvironment(); if (environment != null) { - attributes.put("sentry.environment", new SentryLogEventAttributeValue("string", environment)); + attributes.put("sentry.environment", new SentryLogEventAttributeValue(SentryAttributeType.STRING, environment)); } final @Nullable String release = scopes.getOptions().getRelease(); if (release != null) { - attributes.put("sentry.release", new SentryLogEventAttributeValue("string", release)); + attributes.put("sentry.release", new SentryLogEventAttributeValue(SentryAttributeType.STRING, release)); } attributes.put( - "sentry.trace.parent_span_id", new SentryLogEventAttributeValue("string", spanId)); + "sentry.trace.parent_span_id", new SentryLogEventAttributeValue(SentryAttributeType.STRING, spanId)); if (Platform.isJvm()) { setServerName(attributes); @@ -227,11 +227,11 @@ private void setServerName( final @Nullable String optionsServerName = options.getServerName(); if (optionsServerName != null) { attributes.put( - "server.address", new SentryLogEventAttributeValue("string", optionsServerName)); + "server.address", new SentryLogEventAttributeValue(SentryAttributeType.STRING, optionsServerName)); } else if (options.isAttachServerName()) { final @Nullable String hostname = HostnameCache.getInstance().getHostname(); if (hostname != null) { - attributes.put("server.address", new SentryLogEventAttributeValue("string", hostname)); + attributes.put("server.address", new SentryLogEventAttributeValue(SentryAttributeType.STRING, hostname)); } } } @@ -241,15 +241,15 @@ private void setUser(final @NotNull HashMap Date: Mon, 16 Jun 2025 14:19:25 +0200 Subject: [PATCH 04/14] no longer check isSendDefaultPii --- .../main/java/io/sentry/logger/LoggerApi.java | 4 +-- sentry/src/test/java/io/sentry/ScopesTest.kt | 30 +------------------ 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/sentry/src/main/java/io/sentry/logger/LoggerApi.java b/sentry/src/main/java/io/sentry/logger/LoggerApi.java index 1a2d2c9bc7..c3f837f4d4 100644 --- a/sentry/src/main/java/io/sentry/logger/LoggerApi.java +++ b/sentry/src/main/java/io/sentry/logger/LoggerApi.java @@ -214,9 +214,7 @@ private void captureLog( setServerName(attributes); } - if (scopes.getOptions().isSendDefaultPii()) { - setUser(attributes); - } + setUser(attributes); return attributes; } diff --git a/sentry/src/test/java/io/sentry/ScopesTest.kt b/sentry/src/test/java/io/sentry/ScopesTest.kt index f0dec629de..4e879a2ab6 100644 --- a/sentry/src/test/java/io/sentry/ScopesTest.kt +++ b/sentry/src/test/java/io/sentry/ScopesTest.kt @@ -2852,10 +2852,9 @@ class ScopesTest { } @Test - fun `adds user fields to log attributes if sendDefaultPii is true`() { + fun `adds user fields to log attributes`() { val (sut, mockClient) = getEnabledScopes { it.logs.isEnabled = true - it.isSendDefaultPii = true } sut.configureScope { scope -> @@ -2887,33 +2886,6 @@ class ScopesTest { ) } - @Test - fun `does not add user fields to log attributes by default`() { - val (sut, mockClient) = getEnabledScopes { - it.logs.isEnabled = true - } - - sut.configureScope { scope -> - scope.user = User().also { - it.id = "usrid" - it.username = "usrname" - it.email = "user@sentry.io" - } - } - sut.logger().log(SentryLogLevel.WARN, "log message") - - verify(mockClient).captureLog( - check { - assertEquals("log message", it.body) - - assertNull(it.attributes?.get("user.id")) - assertNull(it.attributes?.get("user.name")) - assertNull(it.attributes?.get("user.email")) - }, - anyOrNull() - ) - } - //endregion @Test From 225e4a8b5f2f3d829eb92300df15ce64b378cab6 Mon Sep 17 00:00:00 2001 From: Sentry Github Bot Date: Mon, 16 Jun 2025 12:24:16 +0000 Subject: [PATCH 05/14] Format code --- .../main/java/io/sentry/logger/LoggerApi.java | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/sentry/src/main/java/io/sentry/logger/LoggerApi.java b/sentry/src/main/java/io/sentry/logger/LoggerApi.java index c3f837f4d4..1e8fef75a8 100644 --- a/sentry/src/main/java/io/sentry/logger/LoggerApi.java +++ b/sentry/src/main/java/io/sentry/logger/LoggerApi.java @@ -185,14 +185,16 @@ private void captureLog( } if (i > 0) { attributes.put( - "sentry.message.template", new SentryLogEventAttributeValue(SentryAttributeType.STRING, message)); + "sentry.message.template", + new SentryLogEventAttributeValue(SentryAttributeType.STRING, message)); } } final @Nullable SdkVersion sdkVersion = scopes.getOptions().getSdkVersion(); if (sdkVersion != null) { attributes.put( - "sentry.sdk.name", new SentryLogEventAttributeValue(SentryAttributeType.STRING, sdkVersion.getName())); + "sentry.sdk.name", + new SentryLogEventAttributeValue(SentryAttributeType.STRING, sdkVersion.getName())); attributes.put( "sentry.sdk.version", new SentryLogEventAttributeValue(SentryAttributeType.STRING, sdkVersion.getVersion())); @@ -200,15 +202,19 @@ private void captureLog( final @Nullable String environment = scopes.getOptions().getEnvironment(); if (environment != null) { - attributes.put("sentry.environment", new SentryLogEventAttributeValue(SentryAttributeType.STRING, environment)); + attributes.put( + "sentry.environment", + new SentryLogEventAttributeValue(SentryAttributeType.STRING, environment)); } final @Nullable String release = scopes.getOptions().getRelease(); if (release != null) { - attributes.put("sentry.release", new SentryLogEventAttributeValue(SentryAttributeType.STRING, release)); + attributes.put( + "sentry.release", new SentryLogEventAttributeValue(SentryAttributeType.STRING, release)); } attributes.put( - "sentry.trace.parent_span_id", new SentryLogEventAttributeValue(SentryAttributeType.STRING, spanId)); + "sentry.trace.parent_span_id", + new SentryLogEventAttributeValue(SentryAttributeType.STRING, spanId)); if (Platform.isJvm()) { setServerName(attributes); @@ -225,11 +231,14 @@ private void setServerName( final @Nullable String optionsServerName = options.getServerName(); if (optionsServerName != null) { attributes.put( - "server.address", new SentryLogEventAttributeValue(SentryAttributeType.STRING, optionsServerName)); + "server.address", + new SentryLogEventAttributeValue(SentryAttributeType.STRING, optionsServerName)); } else if (options.isAttachServerName()) { final @Nullable String hostname = HostnameCache.getInstance().getHostname(); if (hostname != null) { - attributes.put("server.address", new SentryLogEventAttributeValue(SentryAttributeType.STRING, hostname)); + attributes.put( + "server.address", + new SentryLogEventAttributeValue(SentryAttributeType.STRING, hostname)); } } } @@ -243,11 +252,13 @@ private void setUser(final @NotNull HashMap Date: Tue, 17 Jun 2025 08:05:43 +0200 Subject: [PATCH 06/14] ignore IntelliJ / Android Studio run configs --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 95ed0f498a..52bec85e0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .DS_Store .idea/ .gradle/ +.run/ build/ artifacts/ out/ From 76ac22bea08f8ea1b54027cbdae490295971cd1f Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 17 Jun 2025 08:10:48 +0200 Subject: [PATCH 07/14] suppress deprecation warning for user.name --- .../java/io/sentry/android/core/SentryUserFeedbackDialog.java | 1 + 1 file changed, 1 insertion(+) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SentryUserFeedbackDialog.java b/sentry-android-core/src/main/java/io/sentry/android/core/SentryUserFeedbackDialog.java index a188d8a371..77c9a61d2d 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SentryUserFeedbackDialog.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SentryUserFeedbackDialog.java @@ -43,6 +43,7 @@ public void setCancelable(boolean cancelable) { } @Override + @SuppressWarnings("deprecation") protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.sentry_dialog_user_feedback); From 72b09b1453b584f9515d843f40c399419bb80d90 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 17 Jun 2025 08:20:02 +0200 Subject: [PATCH 08/14] Add device and OS attributes to logs --- .../core/DefaultAndroidEventProcessor.java | 42 +++++++++++++++++ .../main/java/io/sentry/EventProcessor.java | 11 +++++ .../src/main/java/io/sentry/SentryClient.java | 45 +++++++++++++++++++ .../main/java/io/sentry/SentryLogEvent.java | 11 +++++ 4 files changed, 109 insertions(+) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java b/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java index 646f3c91dc..b13803f61c 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java @@ -7,14 +7,18 @@ import io.sentry.EventProcessor; import io.sentry.Hint; import io.sentry.IpAddressUtils; +import io.sentry.SentryAttributeType; import io.sentry.SentryBaseEvent; import io.sentry.SentryEvent; import io.sentry.SentryLevel; +import io.sentry.SentryLogEvent; +import io.sentry.SentryLogEventAttributeValue; import io.sentry.SentryReplayEvent; import io.sentry.android.core.internal.util.AndroidThreadChecker; import io.sentry.android.core.performance.AppStartMetrics; import io.sentry.android.core.performance.TimeSpan; import io.sentry.protocol.App; +import io.sentry.protocol.Device; import io.sentry.protocol.OperatingSystem; import io.sentry.protocol.SentryException; import io.sentry.protocol.SentryStackFrame; @@ -81,6 +85,13 @@ public DefaultAndroidEventProcessor( return event; } + @Override + public @Nullable SentryLogEvent process(@NotNull SentryLogEvent event) { + setDevice(event); + setOs(event); + return event; + } + /** * The last exception is usually used for picking the issue title, but the convention is to send * inner exceptions first, e.g. [inner, outer] This doesn't work very well on Android, as some @@ -199,6 +210,37 @@ private void mergeOS(final @NotNull SentryBaseEvent event) { } } + private void setDevice(final @NotNull SentryLogEvent event) { + try { + final @NotNull Device device = deviceInfoUtil.get().collectDeviceInformation(false, false); + event.setAttribute( + "device.brand", + new SentryLogEventAttributeValue(SentryAttributeType.STRING, device.getBrand())); + event.setAttribute( + "device.model", + new SentryLogEventAttributeValue(SentryAttributeType.STRING, device.getModel())); + event.setAttribute( + "device.family", + new SentryLogEventAttributeValue(SentryAttributeType.STRING, device.getFamily())); + } catch (Throwable e) { + options.getLogger().log(SentryLevel.ERROR, "Failed to retrieve device info", e); + } + } + + private void setOs(final @NotNull SentryLogEvent event) { + try { + final OperatingSystem androidOS = deviceInfoUtil.get().getOperatingSystem(); + event.setAttribute( + "os.name", + new SentryLogEventAttributeValue(SentryAttributeType.STRING, androidOS.getName())); + event.setAttribute( + "os.version", + new SentryLogEventAttributeValue(SentryAttributeType.STRING, androidOS.getVersion())); + } catch (Throwable e) { + options.getLogger().log(SentryLevel.ERROR, "Failed to retrieve os system", e); + } + } + // Data to be applied to events that was created in the running process private void processNonCachedEvent( final @NotNull SentryBaseEvent event, final @NotNull Hint hint) { diff --git a/sentry/src/main/java/io/sentry/EventProcessor.java b/sentry/src/main/java/io/sentry/EventProcessor.java index 3ee289a8fa..b258132edf 100644 --- a/sentry/src/main/java/io/sentry/EventProcessor.java +++ b/sentry/src/main/java/io/sentry/EventProcessor.java @@ -45,6 +45,17 @@ default SentryReplayEvent process(@NotNull SentryReplayEvent event, @NotNull Hin return event; } + /** + * May mutate or drop a SentryLogEvent + * + * @param event the SentryLogEvent + * @return the event itself, a mutated SentryLogEvent or null + */ + @Nullable + default SentryLogEvent process(@NotNull SentryLogEvent event) { + return event; + } + /** * Controls when this EventProcessor is invoked. * diff --git a/sentry/src/main/java/io/sentry/SentryClient.java b/sentry/src/main/java/io/sentry/SentryClient.java index 95ceacef88..617083b1a3 100644 --- a/sentry/src/main/java/io/sentry/SentryClient.java +++ b/sentry/src/main/java/io/sentry/SentryClient.java @@ -470,6 +470,38 @@ private SentryEvent processEvent( return event; } + @Nullable + private SentryLogEvent processLogEvent( + @NotNull SentryLogEvent event, final @NotNull List eventProcessors) { + for (final EventProcessor processor : eventProcessors) { + try { + event = processor.process(event); + } catch (Throwable e) { + options + .getLogger() + .log( + SentryLevel.ERROR, + e, + "An exception occurred while processing log event by processor: %s", + processor.getClass().getName()); + } + + if (event == null) { + options + .getLogger() + .log( + SentryLevel.DEBUG, + "Log event was dropped by a processor: %s", + processor.getClass().getName()); + options + .getClientReportRecorder() + .recordLostEvent(DiscardReason.EVENT_PROCESSOR, DataCategory.LogItem); + break; + } + } + return event; + } + private @Nullable SentryTransaction processTransaction( @NotNull SentryTransaction transaction, final @NotNull Hint hint, @@ -1138,6 +1170,19 @@ public void captureSession(final @NotNull Session session, final @Nullable Hint @ApiStatus.Experimental @Override public void captureLog(@Nullable SentryLogEvent logEvent, @Nullable IScope scope) { + if (logEvent != null && scope != null) { + logEvent = processLogEvent(logEvent, scope.getEventProcessors()); + if (logEvent == null) { + return; + } + } + + if (logEvent != null) { + logEvent = processLogEvent(logEvent, options.getEventProcessors()); + if (logEvent == null) { + return; + } + } if (logEvent != null) { logEvent = executeBeforeSendLog(logEvent); diff --git a/sentry/src/main/java/io/sentry/SentryLogEvent.java b/sentry/src/main/java/io/sentry/SentryLogEvent.java index 61065ff666..2afcf57a1d 100644 --- a/sentry/src/main/java/io/sentry/SentryLogEvent.java +++ b/sentry/src/main/java/io/sentry/SentryLogEvent.java @@ -73,6 +73,17 @@ public void setAttributes(final @Nullable Map(); + } + this.attributes.put(key, value); + } + public @Nullable Integer getSeverityNumber() { return severityNumber; } From f1afe92ac80a0055f0b138f1885f43221e9db723 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 17 Jun 2025 14:46:14 +0200 Subject: [PATCH 09/14] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fee869d5e4..5b52a53a85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ SentryUserFeedbackDialog.Builder(context).create().show() ``` - Add `user.id`, `user.name` and `user.email` to log attributes ([#4486](https://github.com/getsentry/sentry-java/pull/4486)) +- Add device (brand, model and family) and OS (name and version) attributes to logs ([#4493](https://github.com/getsentry/sentry-java/pull/4493)) ## 8.13.3 From c234a3dcbd1302f57c3dfb29f6d1a3fee0220ed9 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 17 Jun 2025 14:47:03 +0200 Subject: [PATCH 10/14] add method impl for MainEventProcessor --- sentry/src/main/java/io/sentry/MainEventProcessor.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sentry/src/main/java/io/sentry/MainEventProcessor.java b/sentry/src/main/java/io/sentry/MainEventProcessor.java index 7f44d61df4..ddf7b3828e 100644 --- a/sentry/src/main/java/io/sentry/MainEventProcessor.java +++ b/sentry/src/main/java/io/sentry/MainEventProcessor.java @@ -142,6 +142,11 @@ private void processNonCachedEvent(final @NotNull SentryBaseEvent event) { return event; } + @Override + public @Nullable SentryLogEvent process(@NotNull SentryLogEvent event) { + return event; + } + private void setCommons(final @NotNull SentryBaseEvent event) { setPlatform(event); } From 57d679f49d0dfeeacd1e44ac3cd4fbabe9e62995 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 17 Jun 2025 14:59:16 +0200 Subject: [PATCH 11/14] use device and os info more directly --- .../core/DefaultAndroidEventProcessor.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java b/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java index b13803f61c..80122f12c3 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java @@ -3,10 +3,13 @@ import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.os.Build; + import io.sentry.DateUtils; import io.sentry.EventProcessor; import io.sentry.Hint; import io.sentry.IpAddressUtils; +import io.sentry.NoOpLogger; import io.sentry.SentryAttributeType; import io.sentry.SentryBaseEvent; import io.sentry.SentryEvent; @@ -18,7 +21,6 @@ import io.sentry.android.core.performance.AppStartMetrics; import io.sentry.android.core.performance.TimeSpan; import io.sentry.protocol.App; -import io.sentry.protocol.Device; import io.sentry.protocol.OperatingSystem; import io.sentry.protocol.SentryException; import io.sentry.protocol.SentryStackFrame; @@ -27,6 +29,7 @@ import io.sentry.protocol.SentryTransaction; import io.sentry.protocol.User; import io.sentry.util.HintUtils; +import io.sentry.util.LazyEvaluator; import io.sentry.util.Objects; import java.util.Collections; import java.util.List; @@ -46,6 +49,7 @@ final class DefaultAndroidEventProcessor implements EventProcessor { private final @NotNull BuildInfoProvider buildInfoProvider; private final @NotNull SentryAndroidOptions options; private final @NotNull Future deviceInfoUtil; + private final @NotNull LazyEvaluator deviceFamily = new LazyEvaluator<>(() -> ContextUtils.getFamily(NoOpLogger.getInstance())); public DefaultAndroidEventProcessor( final @NotNull Context context, @@ -212,16 +216,15 @@ private void mergeOS(final @NotNull SentryBaseEvent event) { private void setDevice(final @NotNull SentryLogEvent event) { try { - final @NotNull Device device = deviceInfoUtil.get().collectDeviceInformation(false, false); event.setAttribute( "device.brand", - new SentryLogEventAttributeValue(SentryAttributeType.STRING, device.getBrand())); + new SentryLogEventAttributeValue(SentryAttributeType.STRING, Build.BRAND)); event.setAttribute( "device.model", - new SentryLogEventAttributeValue(SentryAttributeType.STRING, device.getModel())); + new SentryLogEventAttributeValue(SentryAttributeType.STRING, Build.MODEL)); event.setAttribute( "device.family", - new SentryLogEventAttributeValue(SentryAttributeType.STRING, device.getFamily())); + new SentryLogEventAttributeValue(SentryAttributeType.STRING, deviceFamily.getValue())); } catch (Throwable e) { options.getLogger().log(SentryLevel.ERROR, "Failed to retrieve device info", e); } @@ -229,13 +232,12 @@ private void setDevice(final @NotNull SentryLogEvent event) { private void setOs(final @NotNull SentryLogEvent event) { try { - final OperatingSystem androidOS = deviceInfoUtil.get().getOperatingSystem(); event.setAttribute( "os.name", - new SentryLogEventAttributeValue(SentryAttributeType.STRING, androidOS.getName())); + new SentryLogEventAttributeValue(SentryAttributeType.STRING, "Android")); event.setAttribute( "os.version", - new SentryLogEventAttributeValue(SentryAttributeType.STRING, androidOS.getVersion())); + new SentryLogEventAttributeValue(SentryAttributeType.STRING, Build.VERSION.RELEASE)); } catch (Throwable e) { options.getLogger().log(SentryLevel.ERROR, "Failed to retrieve os system", e); } From 42ae4c2fbfc2a2c37b4521a9362539edec94fbd9 Mon Sep 17 00:00:00 2001 From: Sentry Github Bot Date: Tue, 17 Jun 2025 13:01:16 +0000 Subject: [PATCH 12/14] Format code --- .../sentry/android/core/DefaultAndroidEventProcessor.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java b/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java index 80122f12c3..9409c29b0d 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java @@ -4,7 +4,6 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Build; - import io.sentry.DateUtils; import io.sentry.EventProcessor; import io.sentry.Hint; @@ -49,7 +48,8 @@ final class DefaultAndroidEventProcessor implements EventProcessor { private final @NotNull BuildInfoProvider buildInfoProvider; private final @NotNull SentryAndroidOptions options; private final @NotNull Future deviceInfoUtil; - private final @NotNull LazyEvaluator deviceFamily = new LazyEvaluator<>(() -> ContextUtils.getFamily(NoOpLogger.getInstance())); + private final @NotNull LazyEvaluator deviceFamily = + new LazyEvaluator<>(() -> ContextUtils.getFamily(NoOpLogger.getInstance())); public DefaultAndroidEventProcessor( final @NotNull Context context, @@ -233,8 +233,7 @@ private void setDevice(final @NotNull SentryLogEvent event) { private void setOs(final @NotNull SentryLogEvent event) { try { event.setAttribute( - "os.name", - new SentryLogEventAttributeValue(SentryAttributeType.STRING, "Android")); + "os.name", new SentryLogEventAttributeValue(SentryAttributeType.STRING, "Android")); event.setAttribute( "os.version", new SentryLogEventAttributeValue(SentryAttributeType.STRING, Build.VERSION.RELEASE)); From f29c3ca9ccb4a6b41e572908b85abe2943855d98 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 17 Jun 2025 15:52:20 +0200 Subject: [PATCH 13/14] update changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16165c5462..b7645f3ef0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,8 @@ SentryUserFeedbackDialog.Builder(context).create().show() ``` - Add `user.id`, `user.name` and `user.email` to log attributes ([#4486](https://github.com/getsentry/sentry-java/pull/4486)) -- Add device (brand, model and family) and OS (name and version) attributes to logs ([#4493](https://github.com/getsentry/sentry-java/pull/4493)) +- User `name` attribute has been deprecated, please use `username` instead ([#4486](https://github.com/getsentry/sentry-java/pull/4486)) +- Add device (`device.brand`, `device.model` and `device.family`) and OS (`os.name` and `os.version`) attributes to logs ([#4493](https://github.com/getsentry/sentry-java/pull/4493)) - Serialize `preContext` and `postContext` in `SentryStackFrame` ([#4482](https://github.com/getsentry/sentry-java/pull/4482)) ## 8.13.3 From 299663c7e379c4b9fe9ff59ec59ca077f4b3d2fd Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 17 Jun 2025 15:59:06 +0200 Subject: [PATCH 14/14] api --- sentry/api/sentry.api | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 2449e93b87..985c2205f5 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -458,6 +458,7 @@ public final class io/sentry/EnvelopeSender : io/sentry/IEnvelopeSender { public abstract interface class io/sentry/EventProcessor { public fun getOrder ()Ljava/lang/Long; public fun process (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/SentryEvent; + public fun process (Lio/sentry/SentryLogEvent;)Lio/sentry/SentryLogEvent; public fun process (Lio/sentry/SentryReplayEvent;Lio/sentry/Hint;)Lio/sentry/SentryReplayEvent; public fun process (Lio/sentry/protocol/SentryTransaction;Lio/sentry/Hint;)Lio/sentry/protocol/SentryTransaction; } @@ -1284,6 +1285,7 @@ public final class io/sentry/MainEventProcessor : io/sentry/EventProcessor, java public fun close ()V public fun getOrder ()Ljava/lang/Long; public fun process (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/SentryEvent; + public fun process (Lio/sentry/SentryLogEvent;)Lio/sentry/SentryLogEvent; public fun process (Lio/sentry/SentryReplayEvent;Lio/sentry/Hint;)Lio/sentry/SentryReplayEvent; public fun process (Lio/sentry/protocol/SentryTransaction;Lio/sentry/Hint;)Lio/sentry/protocol/SentryTransaction; } @@ -3143,6 +3145,7 @@ public final class io/sentry/SentryLogEvent : io/sentry/JsonSerializable, io/sen public fun getTimestamp ()Ljava/lang/Double; public fun getUnknown ()Ljava/util/Map; public fun serialize (Lio/sentry/ObjectWriter;Lio/sentry/ILogger;)V + public fun setAttribute (Ljava/lang/String;Lio/sentry/SentryLogEventAttributeValue;)V public fun setAttributes (Ljava/util/Map;)V public fun setBody (Ljava/lang/String;)V public fun setLevel (Lio/sentry/SentryLogLevel;)V