Skip to content

Commit f3c94e3

Browse files
authored
Merge branch 'main' into chore-ignore-claude-settings
2 parents d25d4fe + 96eeafa commit f3c94e3

File tree

11 files changed

+215
-11
lines changed

11 files changed

+215
-11
lines changed

.claude/settings.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(find:*)",
5+
"Bash(ls:*)",
6+
"Bash(git:*)",
7+
"Bash(git status:*)",
8+
"Bash(git log:*)",
9+
"Bash(git diff:*)",
10+
"Bash(git show:*)",
11+
"Bash(git branch:*)",
12+
"Bash(git remote:*)",
13+
"Bash(git tag:*)",
14+
"Bash(git stash list:*)",
15+
"Bash(git rev-parse:*)",
16+
"Bash(gh pr view:*)",
17+
"Bash(gh pr list:*)",
18+
"Bash(gh pr checks:*)",
19+
"Bash(gh pr diff:*)",
20+
"Bash(gh issue view:*)",
21+
"Bash(gh issue list:*)",
22+
"Bash(gh run view:*)",
23+
"Bash(gh run list:*)",
24+
"Bash(gh run logs:*)",
25+
"Bash(gh repo view:*)",
26+
"WebFetch(domain:github.com)",
27+
"WebFetch(domain:docs.sentry.io)",
28+
"WebFetch(domain:develop.sentry.dev)",
29+
"Bash(grep:*)",
30+
"Bash(mv:*)"
31+
],
32+
"deny": []
33+
}
34+
}

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
# Changelog
22

3-
## Unreleased
3+
## 8.31.0
44

55
### Features
66

77
- Added `io.sentry.ndk.sdk-name` Android manifest option to configure the native SDK's name ([#5027](https://github.com/getsentry/sentry-java/pull/5027))
8+
- Replace `sentry.trace.parent_span_id` attribute with `spanId` property on `SentryLogEvent` ([#5040](https://github.com/getsentry/sentry-java/pull/5040))
9+
10+
### Fixes
11+
12+
- Only attach user attributes to logs if `sendDefaultPii` is enabled ([#5036](https://github.com/getsentry/sentry-java/pull/5036))
13+
- Reject new logs if `LoggerBatchProcessor` is shutting down ([#5041](https://github.com/getsentry/sentry-java/pull/5041))
14+
- Downgrade protobuf-javalite dependency from 4.33.1 to 3.25.8 ([#5044](https://github.com/getsentry/sentry-java/pull/5044))
815

916
### Dependencies
1017

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
1111
android.useAndroidX=true
1212

1313
# Release information
14-
versionName=8.30.0
14+
versionName=8.31.0
1515

1616
# Override the SDK name on native crashes on Android
1717
sentryAndroidSdkName=sentry.native.android

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ spotless = "7.0.4"
4141
gummyBears = "0.12.0"
4242
camerax = "1.3.0"
4343
openfeature = "1.18.2"
44-
protobuf = "4.33.1"
44+
protobuf = "3.25.8"
4545

4646
[plugins]
4747
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

sentry/api/sentry.api

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3238,15 +3238,19 @@ public final class io/sentry/SentryLogEvent : io/sentry/JsonSerializable, io/sen
32383238
public fun getBody ()Ljava/lang/String;
32393239
public fun getLevel ()Lio/sentry/SentryLogLevel;
32403240
public fun getSeverityNumber ()Ljava/lang/Integer;
3241+
public fun getSpanId ()Lio/sentry/SpanId;
32413242
public fun getTimestamp ()Ljava/lang/Double;
3243+
public fun getTraceId ()Lio/sentry/protocol/SentryId;
32423244
public fun getUnknown ()Ljava/util/Map;
32433245
public fun serialize (Lio/sentry/ObjectWriter;Lio/sentry/ILogger;)V
32443246
public fun setAttribute (Ljava/lang/String;Lio/sentry/SentryLogEventAttributeValue;)V
32453247
public fun setAttributes (Ljava/util/Map;)V
32463248
public fun setBody (Ljava/lang/String;)V
32473249
public fun setLevel (Lio/sentry/SentryLogLevel;)V
32483250
public fun setSeverityNumber (Ljava/lang/Integer;)V
3251+
public fun setSpanId (Lio/sentry/SpanId;)V
32493252
public fun setTimestamp (Ljava/lang/Double;)V
3253+
public fun setTraceId (Lio/sentry/protocol/SentryId;)V
32503254
public fun setUnknown (Ljava/util/Map;)V
32513255
}
32523256

@@ -3261,6 +3265,7 @@ public final class io/sentry/SentryLogEvent$JsonKeys {
32613265
public static final field BODY Ljava/lang/String;
32623266
public static final field LEVEL Ljava/lang/String;
32633267
public static final field SEVERITY_NUMBER Ljava/lang/String;
3268+
public static final field SPAN_ID Ljava/lang/String;
32643269
public static final field TIMESTAMP Ljava/lang/String;
32653270
public static final field TRACE_ID Ljava/lang/String;
32663271
public fun <init> ()V

sentry/src/main/java/io/sentry/SentryLogEvent.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
public final class SentryLogEvent implements JsonUnknown, JsonSerializable {
1414

1515
private @NotNull SentryId traceId;
16+
private @Nullable SpanId spanId;
1617
private @NotNull Double timestamp;
1718
private @NotNull String body;
1819
private @NotNull SentryLogLevel level;
@@ -92,10 +93,27 @@ public void setSeverityNumber(final @Nullable Integer severityNumber) {
9293
this.severityNumber = severityNumber;
9394
}
9495

96+
public @Nullable SpanId getSpanId() {
97+
return spanId;
98+
}
99+
100+
public void setSpanId(final @Nullable SpanId spanId) {
101+
this.spanId = spanId;
102+
}
103+
104+
public @NotNull SentryId getTraceId() {
105+
return traceId;
106+
}
107+
108+
public void setTraceId(final @NotNull SentryId traceId) {
109+
this.traceId = traceId;
110+
}
111+
95112
// region json
96113
public static final class JsonKeys {
97114
public static final String TIMESTAMP = "timestamp";
98115
public static final String TRACE_ID = "trace_id";
116+
public static final String SPAN_ID = "span_id";
99117
public static final String LEVEL = "level";
100118
public static final String SEVERITY_NUMBER = "severity_number";
101119
public static final String BODY = "body";
@@ -109,6 +127,9 @@ public void serialize(final @NotNull ObjectWriter writer, final @NotNull ILogger
109127
writer.beginObject();
110128
writer.name(JsonKeys.TIMESTAMP).value(logger, doubleToBigDecimal(timestamp));
111129
writer.name(JsonKeys.TRACE_ID).value(logger, traceId);
130+
if (spanId != null) {
131+
writer.name(JsonKeys.SPAN_ID).value(logger, spanId);
132+
}
112133
writer.name(JsonKeys.BODY).value(body);
113134
writer.name(JsonKeys.LEVEL).value(logger, level);
114135
if (severityNumber != null) {
@@ -145,6 +166,7 @@ public static final class Deserializer implements JsonDeserializer<SentryLogEven
145166
final @NotNull ObjectReader reader, final @NotNull ILogger logger) throws Exception {
146167
@Nullable Map<String, Object> unknown = null;
147168
@Nullable SentryId traceId = null;
169+
@Nullable SpanId spanId = null;
148170
@Nullable Double timestamp = null;
149171
@Nullable String body = null;
150172
@Nullable SentryLogLevel level = null;
@@ -158,6 +180,9 @@ public static final class Deserializer implements JsonDeserializer<SentryLogEven
158180
case JsonKeys.TRACE_ID:
159181
traceId = reader.nextOrNull(logger, new SentryId.Deserializer());
160182
break;
183+
case JsonKeys.SPAN_ID:
184+
spanId = reader.nextOrNull(logger, new SpanId.Deserializer());
185+
break;
161186
case JsonKeys.TIMESTAMP:
162187
timestamp = reader.nextDoubleOrNull();
163188
break;
@@ -216,6 +241,7 @@ public static final class Deserializer implements JsonDeserializer<SentryLogEven
216241

217242
logEvent.setAttributes(attributes);
218243
logEvent.setSeverityNumber(severityNumber);
244+
logEvent.setSpanId(spanId);
219245
logEvent.setUnknown(unknown);
220246

221247
return logEvent;

sentry/src/main/java/io/sentry/logger/LoggerApi.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ private void captureLog(
131131
span == null ? propagationContext.getSpanId() : span.getSpanContext().getSpanId();
132132
final SentryLogEvent logEvent =
133133
new SentryLogEvent(traceId, timestampToUse, messageToUse, level);
134-
logEvent.setAttributes(createAttributes(params, message, spanId, args));
134+
logEvent.setSpanId(spanId);
135+
logEvent.setAttributes(createAttributes(params, message, args));
135136
logEvent.setSeverityNumber(level.getSeverityNumber());
136137

137138
scopes.getClient().captureLog(logEvent, combinedScope);
@@ -160,7 +161,6 @@ private void captureLog(
160161
private @NotNull HashMap<String, SentryLogEventAttributeValue> createAttributes(
161162
final @NotNull SentryLogParameters params,
162163
final @NotNull String message,
163-
final @NotNull SpanId spanId,
164164
final @Nullable Object... args) {
165165
final @NotNull HashMap<String, SentryLogEventAttributeValue> attributes = new HashMap<>();
166166
final @NotNull String origin = params.getOrigin();
@@ -239,15 +239,13 @@ private void captureLog(
239239
"sentry.release", new SentryLogEventAttributeValue(SentryAttributeType.STRING, release));
240240
}
241241

242-
attributes.put(
243-
"sentry.trace.parent_span_id",
244-
new SentryLogEventAttributeValue(SentryAttributeType.STRING, spanId));
245-
246242
if (Platform.isJvm()) {
247243
setServerName(attributes);
248244
}
249245

250-
setUser(attributes);
246+
if (scopes.getOptions().isSendDefaultPii()) {
247+
setUser(attributes);
248+
}
251249

252250
return attributes;
253251
}

sentry/src/main/java/io/sentry/logger/LoggerBatchProcessor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class LoggerBatchProcessor implements ILoggerBatchProcessor {
3838
private volatile @Nullable Future<?> scheduledFlush;
3939
private final @NotNull AutoClosableReentrantLock scheduleLock = new AutoClosableReentrantLock();
4040
private volatile boolean hasScheduled = false;
41+
private volatile boolean isShuttingDown = false;
4142

4243
private final @NotNull ReusableCountLatch pendingCount = new ReusableCountLatch();
4344

@@ -51,6 +52,9 @@ public LoggerBatchProcessor(
5152

5253
@Override
5354
public void add(final @NotNull SentryLogEvent logEvent) {
55+
if (isShuttingDown) {
56+
return;
57+
}
5458
if (pendingCount.getCount() >= MAX_QUEUE_SIZE) {
5559
options
5660
.getClientReportRecorder()
@@ -70,6 +74,7 @@ public void add(final @NotNull SentryLogEvent logEvent) {
7074
@SuppressWarnings("FutureReturnValueIgnored")
7175
@Override
7276
public void close(final boolean isRestarting) {
77+
isShuttingDown = true;
7378
if (isRestarting) {
7479
maybeSchedule(true, true);
7580
executorService.submit(() -> executorService.close(options.getShutdownTimeoutMillis()));

sentry/src/test/java/io/sentry/ScopesTest.kt

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2913,11 +2913,12 @@ class ScopesTest {
29132913
}
29142914

29152915
@Test
2916-
fun `adds user fields to log attributes`() {
2916+
fun `adds user fields to log attributes if sendDefaultPii is true`() {
29172917
val (sut, mockClient) =
29182918
getEnabledScopes {
29192919
it.logs.isEnabled = true
29202920
it.distinctId = "distinctId"
2921+
it.isSendDefaultPii = true
29212922
}
29222923

29232924
sut.configureScope { scope ->
@@ -2951,6 +2952,37 @@ class ScopesTest {
29512952
)
29522953
}
29532954

2955+
@Test
2956+
fun `does not add user fields to log attributes by default`() {
2957+
val (sut, mockClient) =
2958+
getEnabledScopes {
2959+
it.logs.isEnabled = true
2960+
it.distinctId = "distinctId"
2961+
}
2962+
2963+
sut.configureScope { scope ->
2964+
scope.user =
2965+
User().also {
2966+
it.id = "usrid"
2967+
it.username = "usrname"
2968+
it.email = "user@sentry.io"
2969+
}
2970+
}
2971+
sut.logger().log(SentryLogLevel.WARN, "log message")
2972+
2973+
verify(mockClient)
2974+
.captureLog(
2975+
check {
2976+
assertEquals("log message", it.body)
2977+
2978+
assertNull(it.attributes?.get("user.id"))
2979+
assertNull(it.attributes?.get("user.name"))
2980+
assertNull(it.attributes?.get("user.email"))
2981+
},
2982+
anyOrNull(),
2983+
)
2984+
}
2985+
29542986
@Test
29552987
fun `unset user does provide distinct-id as user-id`() {
29562988
val (sut, mockClient) =
@@ -3125,6 +3157,52 @@ class ScopesTest {
31253157
)
31263158
}
31273159

3160+
@Test
3161+
fun `log event has spanId from active span`() {
3162+
val (sut, mockClient) = getEnabledScopes { it.logs.isEnabled = true }
3163+
3164+
val transaction =
3165+
sut.startTransaction(
3166+
"test transaction",
3167+
"test.op",
3168+
TransactionOptions().also { it.isBindToScope = true },
3169+
)
3170+
3171+
sut.logger().log(SentryLogLevel.WARN, "log message")
3172+
3173+
verify(mockClient)
3174+
.captureLog(
3175+
check {
3176+
assertEquals("log message", it.body)
3177+
assertEquals(transaction.spanContext.traceId, it.traceId)
3178+
assertEquals(transaction.spanContext.spanId, it.spanId)
3179+
},
3180+
anyOrNull(),
3181+
)
3182+
3183+
transaction.finish()
3184+
}
3185+
3186+
@Test
3187+
fun `log event has spanId from propagation context when no active span`() {
3188+
val (sut, mockClient) = getEnabledScopes { it.logs.isEnabled = true }
3189+
3190+
var propagationContext: PropagationContext? = null
3191+
sut.configureScope { propagationContext = it.propagationContext }
3192+
3193+
sut.logger().log(SentryLogLevel.WARN, "log message")
3194+
3195+
verify(mockClient)
3196+
.captureLog(
3197+
check {
3198+
assertEquals("log message", it.body)
3199+
assertEquals(propagationContext!!.traceId, it.traceId)
3200+
assertEquals(propagationContext!!.spanId, it.spanId)
3201+
},
3202+
anyOrNull(),
3203+
)
3204+
}
3205+
31283206
// endregion
31293207

31303208
// region metrics
@@ -4043,6 +4121,54 @@ class ScopesTest {
40434121
)
40444122
}
40454123

4124+
@Test
4125+
fun `metric event has spanId from active span`() {
4126+
val (sut, mockClient) = getEnabledScopes { it.metrics.isEnabled = true }
4127+
4128+
val transaction =
4129+
sut.startTransaction(
4130+
"test transaction",
4131+
"test.op",
4132+
TransactionOptions().also { it.isBindToScope = true },
4133+
)
4134+
4135+
sut.metrics().count("metric name")
4136+
4137+
verify(mockClient)
4138+
.captureMetric(
4139+
check {
4140+
assertEquals("metric name", it.name)
4141+
assertEquals(transaction.spanContext.traceId, it.traceId)
4142+
assertEquals(transaction.spanContext.spanId, it.spanId)
4143+
},
4144+
anyOrNull(),
4145+
anyOrNull(),
4146+
)
4147+
4148+
transaction.finish()
4149+
}
4150+
4151+
@Test
4152+
fun `metric event has spanId from propagation context when no active span`() {
4153+
val (sut, mockClient) = getEnabledScopes { it.metrics.isEnabled = true }
4154+
4155+
var propagationContext: PropagationContext? = null
4156+
sut.configureScope { propagationContext = it.propagationContext }
4157+
4158+
sut.metrics().count("metric name")
4159+
4160+
verify(mockClient)
4161+
.captureMetric(
4162+
check {
4163+
assertEquals("metric name", it.name)
4164+
assertEquals(propagationContext!!.traceId, it.traceId)
4165+
assertEquals(propagationContext!!.spanId, it.spanId)
4166+
},
4167+
anyOrNull(),
4168+
anyOrNull(),
4169+
)
4170+
}
4171+
40464172
// endregion
40474173

40484174
@Test

0 commit comments

Comments
 (0)