Skip to content

Commit

Permalink
Merge 2d60a97 into c5ccd8a
Browse files Browse the repository at this point in the history
  • Loading branch information
adinauer authored Sep 29, 2022
2 parents c5ccd8a + 2d60a97 commit 2a895ac
Show file tree
Hide file tree
Showing 16 changed files with 217 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- Make user segment a top level property ([#2257](https://github.com/getsentry/sentry-java/pull/2257))
- Replace user `other` with `data` ([#2258](https://github.com/getsentry/sentry-java/pull/2258))
- Provide API for attaching custom measurements to transactions ([#2260](https://github.com/getsentry/sentry-java/pull/2260))

## 6.5.0-beta.1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package io.sentry.android.core;

import static io.sentry.protocol.MeasurementValue.NONE_UNIT;

import android.app.Activity;
import android.util.SparseIntArray;
import androidx.core.app.FrameMetricsAggregator;
import io.sentry.ILogger;
import io.sentry.SentryMeasurementUnit;
import io.sentry.protocol.MeasurementValue;
import io.sentry.protocol.SentryId;
import java.util.HashMap;
Expand Down Expand Up @@ -104,9 +103,12 @@ public synchronized void setMetrics(
return;
}

final MeasurementValue tfValues = new MeasurementValue(totalFrames, NONE_UNIT);
final MeasurementValue sfValues = new MeasurementValue(slowFrames, NONE_UNIT);
final MeasurementValue ffValues = new MeasurementValue(frozenFrames, NONE_UNIT);
final MeasurementValue tfValues =
new MeasurementValue(totalFrames, SentryMeasurementUnit.NONE.apiName());
final MeasurementValue sfValues =
new MeasurementValue(slowFrames, SentryMeasurementUnit.NONE.apiName());
final MeasurementValue ffValues =
new MeasurementValue(frozenFrames, SentryMeasurementUnit.NONE.apiName());
final Map<String, @NotNull MeasurementValue> measurements = new HashMap<>();
measurements.put("frames_total", tfValues);
measurements.put("frames_slow", sfValues);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import static io.sentry.android.core.ActivityLifecycleIntegration.APP_START_COLD;
import static io.sentry.android.core.ActivityLifecycleIntegration.APP_START_WARM;
import static io.sentry.android.core.ActivityLifecycleIntegration.UI_LOAD_OP;
import static io.sentry.protocol.MeasurementValue.MILLISECOND_UNIT;

import io.sentry.EventProcessor;
import io.sentry.Hint;
import io.sentry.SentryEvent;
import io.sentry.SentryMeasurementUnit;
import io.sentry.SpanContext;
import io.sentry.protocol.MeasurementValue;
import io.sentry.protocol.SentryId;
Expand Down Expand Up @@ -67,7 +67,8 @@ public SentryEvent process(@NotNull SentryEvent event, @NotNull Hint hint) {
// if appStartUpInterval is null, metrics are not ready to be sent
if (appStartUpInterval != null) {
final MeasurementValue value =
new MeasurementValue((float) appStartUpInterval, MILLISECOND_UNIT);
new MeasurementValue(
(float) appStartUpInterval, SentryMeasurementUnit.MILLISECOND.apiName());

final String appStartKey =
AppStartState.getInstance().isColdStart() ? "app_start_cold" : "app_start_warm";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import io.sentry.Hint
import io.sentry.IHub
import io.sentry.SentryMeasurementUnit
import io.sentry.SentryTracer
import io.sentry.TracesSamplingDecision
import io.sentry.TransactionContext
import io.sentry.android.core.ActivityLifecycleIntegration.UI_LOAD_OP
import io.sentry.protocol.MeasurementValue
import io.sentry.protocol.MeasurementValue.MILLISECOND_UNIT
import io.sentry.protocol.SentryTransaction
import java.util.Date
import kotlin.test.BeforeTest
Expand Down Expand Up @@ -156,7 +156,7 @@ class PerformanceAndroidEventProcessorTest {
val tracer = SentryTracer(context, fixture.hub)
var tr = SentryTransaction(tracer)

val metrics = mapOf("frames_total" to MeasurementValue(1f, MILLISECOND_UNIT))
val metrics = mapOf("frames_total" to MeasurementValue(1f, SentryMeasurementUnit.MILLISECOND.apiName()))
whenever(fixture.activityFramesTracker.takeMetrics(any())).thenReturn(metrics)

tr = sut.process(tr, Hint())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.sentry.Attachment;
import io.sentry.ISpan;
import io.sentry.Sentry;
import io.sentry.SentryMeasurementUnit;
import io.sentry.SpanStatus;
import io.sentry.UserFeedback;
import io.sentry.protocol.SentryId;
Expand All @@ -27,6 +28,7 @@
public class MainActivity extends AppCompatActivity {

private int crashCount = 0;
private int screenLoadCount = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand Down Expand Up @@ -200,8 +202,10 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
protected void onResume() {
super.onResume();
screenLoadCount++;
final ISpan span = Sentry.getSpan();
if (span != null) {
span.setMeasurement("screen_load_count", screenLoadCount, SentryMeasurementUnit.DAY);
span.finish(SpanStatus.OK);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.sentry.samples.spring.boot;

import io.sentry.ISpan;
import io.sentry.Sentry;
import io.sentry.spring.tracing.SentrySpan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -16,12 +18,19 @@ public class PersonService {
private static final Logger LOGGER = LoggerFactory.getLogger(PersonService.class);

private final JdbcTemplate jdbcTemplate;
private int createCount = 0;

public PersonService(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

Person create(Person person) {
createCount++;
final ISpan span = Sentry.getSpan();
if (span != null) {
span.setMeasurement("create_count", createCount);
}

jdbcTemplate.update(
"insert into person (firstName, lastName) values (?, ?)",
person.getFirstName(),
Expand Down
27 changes: 25 additions & 2 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,8 @@ public abstract interface class io/sentry/ISpan {
public abstract fun isFinished ()Z
public abstract fun setData (Ljava/lang/String;Ljava/lang/Object;)V
public abstract fun setDescription (Ljava/lang/String;)V
public abstract fun setMeasurement (Ljava/lang/String;F)V
public abstract fun setMeasurement (Ljava/lang/String;FLio/sentry/SentryMeasurementUnit;)V
public abstract fun setOperation (Ljava/lang/String;)V
public abstract fun setStatus (Lio/sentry/SpanStatus;)V
public abstract fun setTag (Ljava/lang/String;Ljava/lang/String;)V
Expand Down Expand Up @@ -668,6 +670,8 @@ public final class io/sentry/NoOpSpan : io/sentry/ISpan {
public fun isFinished ()Z
public fun setData (Ljava/lang/String;Ljava/lang/Object;)V
public fun setDescription (Ljava/lang/String;)V
public fun setMeasurement (Ljava/lang/String;F)V
public fun setMeasurement (Ljava/lang/String;FLio/sentry/SentryMeasurementUnit;)V
public fun setOperation (Ljava/lang/String;)V
public fun setStatus (Lio/sentry/SpanStatus;)V
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
Expand Down Expand Up @@ -703,6 +707,8 @@ public final class io/sentry/NoOpTransaction : io/sentry/ITransaction {
public fun scheduleFinish ()V
public fun setData (Ljava/lang/String;Ljava/lang/Object;)V
public fun setDescription (Ljava/lang/String;)V
public fun setMeasurement (Ljava/lang/String;F)V
public fun setMeasurement (Ljava/lang/String;FLio/sentry/SentryMeasurementUnit;)V
public fun setName (Ljava/lang/String;)V
public fun setName (Ljava/lang/String;Lio/sentry/protocol/TransactionNameSource;)V
public fun setOperation (Ljava/lang/String;)V
Expand Down Expand Up @@ -1268,6 +1274,21 @@ public final class io/sentry/SentryLevel : java/lang/Enum, io/sentry/JsonSeriali
public static fun values ()[Lio/sentry/SentryLevel;
}

public final class io/sentry/SentryMeasurementUnit : java/lang/Enum {
public static final field DAY Lio/sentry/SentryMeasurementUnit;
public static final field HOUR Lio/sentry/SentryMeasurementUnit;
public static final field MICROSECOND Lio/sentry/SentryMeasurementUnit;
public static final field MILLISECOND Lio/sentry/SentryMeasurementUnit;
public static final field MINUTE Lio/sentry/SentryMeasurementUnit;
public static final field NANOSECOND Lio/sentry/SentryMeasurementUnit;
public static final field NONE Lio/sentry/SentryMeasurementUnit;
public static final field SECOND Lio/sentry/SentryMeasurementUnit;
public static final field WEEK Lio/sentry/SentryMeasurementUnit;
public fun apiName ()Ljava/lang/String;
public static fun valueOf (Ljava/lang/String;)Lio/sentry/SentryMeasurementUnit;
public static fun values ()[Lio/sentry/SentryMeasurementUnit;
}

public class io/sentry/SentryOptions {
public fun <init> ()V
public fun addContextTag (Ljava/lang/String;)V
Expand Down Expand Up @@ -1492,6 +1513,8 @@ public final class io/sentry/SentryTracer : io/sentry/ITransaction {
public fun scheduleFinish ()V
public fun setData (Ljava/lang/String;Ljava/lang/Object;)V
public fun setDescription (Ljava/lang/String;)V
public fun setMeasurement (Ljava/lang/String;F)V
public fun setMeasurement (Ljava/lang/String;FLio/sentry/SentryMeasurementUnit;)V
public fun setName (Ljava/lang/String;)V
public fun setName (Ljava/lang/String;Lio/sentry/protocol/TransactionNameSource;)V
public fun setOperation (Ljava/lang/String;)V
Expand Down Expand Up @@ -1598,6 +1621,8 @@ public final class io/sentry/Span : io/sentry/ISpan {
public fun isSampled ()Ljava/lang/Boolean;
public fun setData (Ljava/lang/String;Ljava/lang/Object;)V
public fun setDescription (Ljava/lang/String;)V
public fun setMeasurement (Ljava/lang/String;F)V
public fun setMeasurement (Ljava/lang/String;FLio/sentry/SentryMeasurementUnit;)V
public fun setOperation (Ljava/lang/String;)V
public fun setStatus (Lio/sentry/SpanStatus;)V
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
Expand Down Expand Up @@ -2444,8 +2469,6 @@ public final class io/sentry/protocol/Gpu$JsonKeys {
}

public final class io/sentry/protocol/MeasurementValue : io/sentry/JsonSerializable, io/sentry/JsonUnknown {
public static final field MILLISECOND_UNIT Ljava/lang/String;
public static final field NONE_UNIT Ljava/lang/String;
public fun <init> (FLjava/lang/String;)V
public fun <init> (FLjava/lang/String;Ljava/util/Map;)V
public fun getUnit ()Ljava/lang/String;
Expand Down
23 changes: 23 additions & 0 deletions sentry/src/main/java/io/sentry/ISpan.java
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,27 @@ ISpan startChild(
*/
@Nullable
Object getData(@NotNull String key);

/**
* Set a measurement without unit.
*
* <p>NOTE: Setting a measurement with the same name on the same transaction multiple times only
* keeps the last value.
*
* @param name the name of the measurement
* @param value the value of the measurement
*/
void setMeasurement(@NotNull String name, float value);

/**
* Set a measurement with specific unit.
*
* <p>NOTE: Setting a measurement with the same name on the same transaction multiple times only
* keeps the last value.
*
* @param name the name of the measurement
* @param value the value of the measurement
* @param unit the unit the value is measured in
*/
void setMeasurement(@NotNull String name, float value, @NotNull SentryMeasurementUnit unit);
}
7 changes: 7 additions & 0 deletions sentry/src/main/java/io/sentry/NoOpSpan.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,11 @@ public void setData(@NotNull String key, @NotNull Object value) {}
public @Nullable Object getData(@NotNull String key) {
return null;
}

@Override
public void setMeasurement(@NotNull String name, float value) {}

@Override
public void setMeasurement(
@NotNull String name, float value, @NotNull SentryMeasurementUnit unit) {}
}
7 changes: 7 additions & 0 deletions sentry/src/main/java/io/sentry/NoOpTransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,11 @@ public void setData(@NotNull String key, @NotNull Object value) {}
public @Nullable Object getData(@NotNull String key) {
return null;
}

@Override
public void setMeasurement(@NotNull String name, float value) {}

@Override
public void setMeasurement(
@NotNull String name, float value, @NotNull SentryMeasurementUnit unit) {}
}
40 changes: 40 additions & 0 deletions sentry/src/main/java/io/sentry/SentryMeasurementUnit.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.sentry;

import java.util.Locale;
import org.jetbrains.annotations.NotNull;

/**
* <a href="https://getsentry.github.io/relay/relay_metrics/enum.DurationUnit.html">Develop Docs</a>
*/
public enum SentryMeasurementUnit {
/** Nanosecond (`"nanosecond"`), 10^-9 seconds. */
NANOSECOND,

/** Microsecond (`"microsecond"`), 10^-6 seconds. */
MICROSECOND,

/** Millisecond (`"millisecond"`), 10^-3 seconds. */
MILLISECOND,

/** Full second (`"second"`). */
SECOND,

/** Minute (`"minute"`), 60 seconds. */
MINUTE,

/** Hour (`"hour"`), 3600 seconds. */
HOUR,

/** Day (`"day"`), 86,400 seconds. */
DAY,

/** Week (`"week"`), 604,800 seconds. */
WEEK,

/** Untyped value without a unit. */
NONE;

public @NotNull String apiName() {
return name().toLowerCase(Locale.ROOT);
}
}
32 changes: 32 additions & 0 deletions sentry/src/main/java/io/sentry/SentryTracer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.sentry;

import io.sentry.protocol.MeasurementValue;
import io.sentry.protocol.SentryId;
import io.sentry.protocol.SentryTransaction;
import io.sentry.protocol.TransactionNameSource;
Expand All @@ -13,6 +14,7 @@
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
Expand Down Expand Up @@ -74,6 +76,7 @@ public final class SentryTracer implements ITransaction {

private final @NotNull Baggage baggage;
private @NotNull TransactionNameSource transactionNameSource;
private final @NotNull Map<String, MeasurementValue> measurements;

public SentryTracer(final @NotNull TransactionContext context, final @NotNull IHub hub) {
this(context, hub, null);
Expand Down Expand Up @@ -104,6 +107,7 @@ public SentryTracer(
final @Nullable TransactionFinishedCallback transactionFinishedCallback) {
Objects.requireNonNull(context, "context is required");
Objects.requireNonNull(hub, "hub is required");
this.measurements = new ConcurrentHashMap<>();
this.root = new Span(context, this, hub, startTimestamp);
this.name = context.getName();
this.hub = hub;
Expand Down Expand Up @@ -360,6 +364,9 @@ public void finish(@Nullable SpanStatus status) {
// if it's an idle transaction which has no children, we drop it to save user's quota
return;
}

transaction.getMeasurements().putAll(measurements);

hub.captureTransaction(transaction, traceContext(), null, profilingTraceData);
}
}
Expand Down Expand Up @@ -506,6 +513,25 @@ public void setData(@NotNull String key, @NotNull Object value) {
return this.root.getData(key);
}

@Override
public void setMeasurement(@NotNull String name, float value) {
if (root.isFinished()) {
return;
}

this.measurements.put(name, new MeasurementValue(value, null));
}

@Override
public void setMeasurement(
@NotNull String name, float value, @NotNull SentryMeasurementUnit unit) {
if (root.isFinished()) {
return;
}

this.measurements.put(name, new MeasurementValue(value, unit.apiName()));
}

public @Nullable Map<String, Object> getData() {
return this.root.getData();
}
Expand Down Expand Up @@ -601,6 +627,12 @@ AtomicBoolean isFinishTimerRunning() {
return isFinishTimerRunning;
}

@TestOnly
@NotNull
Map<String, MeasurementValue> getMeasurements() {
return measurements;
}

private static final class FinishStatus {
static final FinishStatus NOT_FINISHED = FinishStatus.notFinished();

Expand Down
Loading

0 comments on commit 2a895ac

Please sign in to comment.