Skip to content

Commit 8df0d02

Browse files
authored
feat(logs): Replace sentry.trace.parent_span_id attribute with spanId property on SentryLogEvent (#5040)
* Switch from span id attribute to property on SentryLogEvent * changelog
1 parent 8107c75 commit 8df0d02

File tree

7 files changed

+131
-6
lines changed

7 files changed

+131
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
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))
89

910
### Fixes
1011

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: 2 additions & 6 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,10 +239,6 @@ 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
}

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

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3157,6 +3157,52 @@ class ScopesTest {
31573157
)
31583158
}
31593159

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+
31603206
// endregion
31613207

31623208
// region metrics
@@ -4075,6 +4121,54 @@ class ScopesTest {
40754121
)
40764122
}
40774123

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+
40784172
// endregion
40794173

40804174
@Test

sentry/src/test/java/io/sentry/protocol/SentryLogsSerializationTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import io.sentry.SentryLogEvent
1111
import io.sentry.SentryLogEventAttributeValue
1212
import io.sentry.SentryLogEvents
1313
import io.sentry.SentryLogLevel
14+
import io.sentry.SpanId
1415
import java.io.StringReader
1516
import java.io.StringWriter
1617
import kotlin.test.assertEquals
@@ -31,6 +32,7 @@ class SentryLogsSerializationTest {
3132
SentryLogLevel.INFO,
3233
)
3334
.also {
35+
it.spanId = SpanId("0a53026963414893")
3436
it.attributes =
3537
mutableMapOf(
3638
"sentry.sdk.name" to

sentry/src/test/resources/json/sentry_logs.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
{
55
"timestamp": 1081621443.000000,
66
"trace_id": "5c1f73d39486827b9e60ceb1fc23277a",
7+
"span_id": "0a53026963414893",
78
"body": "42e6bd2a-c45e-414d-8066-ed5196fbc686",
89
"level": "info",
910
"severity_number": 10,

0 commit comments

Comments
 (0)