Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Features

- 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))
- Replace `sentry.trace.parent_span_id` attribute with `spanId` property on `SentryLogEvent` ([#5040](https://github.com/getsentry/sentry-java/pull/5040))

### Fixes

Expand Down
5 changes: 5 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -3238,15 +3238,19 @@ public final class io/sentry/SentryLogEvent : io/sentry/JsonSerializable, io/sen
public fun getBody ()Ljava/lang/String;
public fun getLevel ()Lio/sentry/SentryLogLevel;
public fun getSeverityNumber ()Ljava/lang/Integer;
public fun getSpanId ()Lio/sentry/SpanId;
public fun getTimestamp ()Ljava/lang/Double;
public fun getTraceId ()Lio/sentry/protocol/SentryId;
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
public fun setSeverityNumber (Ljava/lang/Integer;)V
public fun setSpanId (Lio/sentry/SpanId;)V
public fun setTimestamp (Ljava/lang/Double;)V
public fun setTraceId (Lio/sentry/protocol/SentryId;)V
public fun setUnknown (Ljava/util/Map;)V
}

Expand All @@ -3261,6 +3265,7 @@ public final class io/sentry/SentryLogEvent$JsonKeys {
public static final field BODY Ljava/lang/String;
public static final field LEVEL Ljava/lang/String;
public static final field SEVERITY_NUMBER Ljava/lang/String;
public static final field SPAN_ID Ljava/lang/String;
public static final field TIMESTAMP Ljava/lang/String;
public static final field TRACE_ID Ljava/lang/String;
public fun <init> ()V
Expand Down
26 changes: 26 additions & 0 deletions sentry/src/main/java/io/sentry/SentryLogEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
public final class SentryLogEvent implements JsonUnknown, JsonSerializable {

private @NotNull SentryId traceId;
private @Nullable SpanId spanId;
private @NotNull Double timestamp;
private @NotNull String body;
private @NotNull SentryLogLevel level;
Expand Down Expand Up @@ -92,10 +93,27 @@ public void setSeverityNumber(final @Nullable Integer severityNumber) {
this.severityNumber = severityNumber;
}

public @Nullable SpanId getSpanId() {
return spanId;
}

public void setSpanId(final @Nullable SpanId spanId) {
this.spanId = spanId;
}

public @NotNull SentryId getTraceId() {
return traceId;
}

public void setTraceId(final @NotNull SentryId traceId) {
this.traceId = traceId;
}

// region json
public static final class JsonKeys {
public static final String TIMESTAMP = "timestamp";
public static final String TRACE_ID = "trace_id";
public static final String SPAN_ID = "span_id";
public static final String LEVEL = "level";
public static final String SEVERITY_NUMBER = "severity_number";
public static final String BODY = "body";
Expand All @@ -109,6 +127,9 @@ public void serialize(final @NotNull ObjectWriter writer, final @NotNull ILogger
writer.beginObject();
writer.name(JsonKeys.TIMESTAMP).value(logger, doubleToBigDecimal(timestamp));
writer.name(JsonKeys.TRACE_ID).value(logger, traceId);
if (spanId != null) {
writer.name(JsonKeys.SPAN_ID).value(logger, spanId);
}
writer.name(JsonKeys.BODY).value(body);
writer.name(JsonKeys.LEVEL).value(logger, level);
if (severityNumber != null) {
Expand Down Expand Up @@ -145,6 +166,7 @@ public static final class Deserializer implements JsonDeserializer<SentryLogEven
final @NotNull ObjectReader reader, final @NotNull ILogger logger) throws Exception {
@Nullable Map<String, Object> unknown = null;
@Nullable SentryId traceId = null;
@Nullable SpanId spanId = null;
@Nullable Double timestamp = null;
@Nullable String body = null;
@Nullable SentryLogLevel level = null;
Expand All @@ -158,6 +180,9 @@ public static final class Deserializer implements JsonDeserializer<SentryLogEven
case JsonKeys.TRACE_ID:
traceId = reader.nextOrNull(logger, new SentryId.Deserializer());
break;
case JsonKeys.SPAN_ID:
spanId = reader.nextOrNull(logger, new SpanId.Deserializer());
break;
case JsonKeys.TIMESTAMP:
timestamp = reader.nextDoubleOrNull();
break;
Expand Down Expand Up @@ -216,6 +241,7 @@ public static final class Deserializer implements JsonDeserializer<SentryLogEven

logEvent.setAttributes(attributes);
logEvent.setSeverityNumber(severityNumber);
logEvent.setSpanId(spanId);
logEvent.setUnknown(unknown);

return logEvent;
Expand Down
8 changes: 2 additions & 6 deletions sentry/src/main/java/io/sentry/logger/LoggerApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ private void captureLog(
span == null ? propagationContext.getSpanId() : span.getSpanContext().getSpanId();
final SentryLogEvent logEvent =
new SentryLogEvent(traceId, timestampToUse, messageToUse, level);
logEvent.setAttributes(createAttributes(params, message, spanId, args));
logEvent.setSpanId(spanId);
logEvent.setAttributes(createAttributes(params, message, args));
logEvent.setSeverityNumber(level.getSeverityNumber());

scopes.getClient().captureLog(logEvent, combinedScope);
Expand Down Expand Up @@ -160,7 +161,6 @@ private void captureLog(
private @NotNull HashMap<String, SentryLogEventAttributeValue> createAttributes(
final @NotNull SentryLogParameters params,
final @NotNull String message,
final @NotNull SpanId spanId,
final @Nullable Object... args) {
final @NotNull HashMap<String, SentryLogEventAttributeValue> attributes = new HashMap<>();
final @NotNull String origin = params.getOrigin();
Expand Down Expand Up @@ -239,10 +239,6 @@ private void captureLog(
"sentry.release", new SentryLogEventAttributeValue(SentryAttributeType.STRING, release));
}

attributes.put(
"sentry.trace.parent_span_id",
new SentryLogEventAttributeValue(SentryAttributeType.STRING, spanId));

if (Platform.isJvm()) {
setServerName(attributes);
}
Expand Down
94 changes: 94 additions & 0 deletions sentry/src/test/java/io/sentry/ScopesTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3157,6 +3157,52 @@ class ScopesTest {
)
}

@Test
fun `log event has spanId from active span`() {
val (sut, mockClient) = getEnabledScopes { it.logs.isEnabled = true }

val transaction =
sut.startTransaction(
"test transaction",
"test.op",
TransactionOptions().also { it.isBindToScope = true },
)

sut.logger().log(SentryLogLevel.WARN, "log message")

verify(mockClient)
.captureLog(
check {
assertEquals("log message", it.body)
assertEquals(transaction.spanContext.traceId, it.traceId)
assertEquals(transaction.spanContext.spanId, it.spanId)
},
anyOrNull(),
)

transaction.finish()
}

@Test
fun `log event has spanId from propagation context when no active span`() {
val (sut, mockClient) = getEnabledScopes { it.logs.isEnabled = true }

var propagationContext: PropagationContext? = null
sut.configureScope { propagationContext = it.propagationContext }

sut.logger().log(SentryLogLevel.WARN, "log message")

verify(mockClient)
.captureLog(
check {
assertEquals("log message", it.body)
assertEquals(propagationContext!!.traceId, it.traceId)
assertEquals(propagationContext!!.spanId, it.spanId)
},
anyOrNull(),
)
}

// endregion

// region metrics
Expand Down Expand Up @@ -4075,6 +4121,54 @@ class ScopesTest {
)
}

@Test
fun `metric event has spanId from active span`() {
val (sut, mockClient) = getEnabledScopes { it.metrics.isEnabled = true }

val transaction =
sut.startTransaction(
"test transaction",
"test.op",
TransactionOptions().also { it.isBindToScope = true },
)

sut.metrics().count("metric name")

verify(mockClient)
.captureMetric(
check {
assertEquals("metric name", it.name)
assertEquals(transaction.spanContext.traceId, it.traceId)
assertEquals(transaction.spanContext.spanId, it.spanId)
},
anyOrNull(),
anyOrNull(),
)

transaction.finish()
}

@Test
fun `metric event has spanId from propagation context when no active span`() {
val (sut, mockClient) = getEnabledScopes { it.metrics.isEnabled = true }

var propagationContext: PropagationContext? = null
sut.configureScope { propagationContext = it.propagationContext }

sut.metrics().count("metric name")

verify(mockClient)
.captureMetric(
check {
assertEquals("metric name", it.name)
assertEquals(propagationContext!!.traceId, it.traceId)
assertEquals(propagationContext!!.spanId, it.spanId)
},
anyOrNull(),
anyOrNull(),
)
}

// endregion

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import io.sentry.SentryLogEvent
import io.sentry.SentryLogEventAttributeValue
import io.sentry.SentryLogEvents
import io.sentry.SentryLogLevel
import io.sentry.SpanId
import java.io.StringReader
import java.io.StringWriter
import kotlin.test.assertEquals
Expand All @@ -31,6 +32,7 @@ class SentryLogsSerializationTest {
SentryLogLevel.INFO,
)
.also {
it.spanId = SpanId("0a53026963414893")
it.attributes =
mutableMapOf(
"sentry.sdk.name" to
Expand Down
1 change: 1 addition & 0 deletions sentry/src/test/resources/json/sentry_logs.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
{
"timestamp": 1081621443.000000,
"trace_id": "5c1f73d39486827b9e60ceb1fc23277a",
"span_id": "0a53026963414893",
"body": "42e6bd2a-c45e-414d-8066-ed5196fbc686",
"level": "info",
"severity_number": 10,
Expand Down
Loading