mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 18:00:02 +01:00
Add local metrics for message processing.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package org.thoughtcrime.securesms.util
|
||||
|
||||
import android.os.SystemClock
|
||||
import org.signal.core.util.ThreadUtil
|
||||
import org.signal.core.util.concurrent.SignalExecutors
|
||||
import org.signal.core.util.logging.Log
|
||||
@@ -8,6 +9,7 @@ import org.thoughtcrime.securesms.database.model.LocalMetricsEvent
|
||||
import org.thoughtcrime.securesms.database.model.LocalMetricsSplit
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* A class for keeping track of local-only metrics.
|
||||
@@ -44,15 +46,17 @@ object LocalMetrics {
|
||||
* @param id A constant that should be unique to this *specific event*. You'll use this same id when calling [split] and [end]. e.g. "message-send-1234"
|
||||
* @param name The name of the event. Does not need to be unique. e.g. "message-send"
|
||||
*/
|
||||
fun start(id: String, name: String) {
|
||||
val time = System.currentTimeMillis()
|
||||
@JvmOverloads
|
||||
fun start(id: String, name: String, timeunit: TimeUnit = TimeUnit.MILLISECONDS) {
|
||||
val time = SystemClock.elapsedRealtimeNanos()
|
||||
|
||||
executor.execute {
|
||||
eventsById[id] = LocalMetricsEvent(
|
||||
createdAt = System.currentTimeMillis(),
|
||||
eventId = id,
|
||||
eventName = name,
|
||||
splits = mutableListOf()
|
||||
splits = mutableListOf(),
|
||||
timeunit = timeunit
|
||||
)
|
||||
lastSplitTimeById[id] = time
|
||||
}
|
||||
@@ -65,13 +69,14 @@ object LocalMetrics {
|
||||
* If an event with the provided ID does not exist, this is effectively a no-op.
|
||||
*/
|
||||
fun split(id: String, split: String) {
|
||||
val time = System.currentTimeMillis()
|
||||
val time = SystemClock.elapsedRealtimeNanos()
|
||||
|
||||
executor.execute {
|
||||
val lastTime: Long? = lastSplitTimeById[id]
|
||||
val splitDoesNotExist: Boolean = eventsById[id]?.splits?.none { it.name == split } ?: true
|
||||
if (lastTime != null && splitDoesNotExist) {
|
||||
eventsById[id]?.splits?.add(LocalMetricsSplit(split, time - lastTime))
|
||||
val event = eventsById[id]
|
||||
event?.splits?.add(LocalMetricsSplit(split, time - lastTime, event.timeunit))
|
||||
lastSplitTimeById[id] = time
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import androidx.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* A nice interface for {@link LocalMetrics} that gives us a place to define string constants and nicer method names.
|
||||
@@ -357,4 +358,80 @@ public final class SignalLocalMetrics {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final class MessageReceive {
|
||||
private static final String NAME_GROUP = "group-message-receive";
|
||||
private static final String NAME_INDIVIDUAL = "individual-message-receive";
|
||||
|
||||
private static final String SPLIT_DECRYPTION = "decryption";
|
||||
private static final String SPLIT_PRE_PROCESS = "pre-process";
|
||||
private static final String SPLIT_GROUPS_PROCESSING = "groups-v2";
|
||||
private static final String SPLIT_DB_INSERT_MEDIA = "media-insert";
|
||||
private static final String SPLIT_DB_INSERT_TEXT = "text-insert";
|
||||
private static final String SPLIT_POST_PROCESS = "post-process";
|
||||
private boolean insertedToDb = false;
|
||||
|
||||
private final String individualMetricId;
|
||||
private final String groupMetricId;
|
||||
|
||||
public static MessageReceive start() {
|
||||
return new MessageReceive();
|
||||
}
|
||||
|
||||
private MessageReceive() {
|
||||
long time = System.currentTimeMillis();
|
||||
individualMetricId = NAME_INDIVIDUAL + time;
|
||||
groupMetricId = NAME_GROUP + time;
|
||||
|
||||
LocalMetrics.getInstance().start(individualMetricId, NAME_INDIVIDUAL, TimeUnit.MICROSECONDS);
|
||||
LocalMetrics.getInstance().start(groupMetricId, NAME_GROUP, TimeUnit.MICROSECONDS);
|
||||
}
|
||||
|
||||
public void onEnvelopeDecrypted() {
|
||||
split(SPLIT_DECRYPTION);
|
||||
}
|
||||
|
||||
public void onPreProcessComplete() {
|
||||
split(SPLIT_PRE_PROCESS);
|
||||
}
|
||||
|
||||
public void onInsertedMediaMessage() {
|
||||
split(SPLIT_DB_INSERT_MEDIA);
|
||||
insertedToDb = true;
|
||||
}
|
||||
|
||||
public void onInsertedTextMessage() {
|
||||
split(SPLIT_DB_INSERT_TEXT);
|
||||
insertedToDb = true;
|
||||
}
|
||||
|
||||
public void onPostProcessComplete() {
|
||||
split(SPLIT_POST_PROCESS);
|
||||
}
|
||||
|
||||
public void onGv2Processed() {
|
||||
split(SPLIT_GROUPS_PROCESSING);
|
||||
}
|
||||
|
||||
private void split(String name) {
|
||||
LocalMetrics.getInstance().split(groupMetricId, name);
|
||||
LocalMetrics.getInstance().split(individualMetricId, name);
|
||||
}
|
||||
|
||||
public void complete(boolean isGroup) {
|
||||
if (!insertedToDb) {
|
||||
LocalMetrics.getInstance().cancel(groupMetricId);
|
||||
LocalMetrics.getInstance().cancel(individualMetricId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isGroup) {
|
||||
LocalMetrics.getInstance().cancel(individualMetricId);
|
||||
LocalMetrics.getInstance().end(groupMetricId);
|
||||
} else {
|
||||
LocalMetrics.getInstance().cancel(groupMetricId);
|
||||
LocalMetrics.getInstance().end(individualMetricId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user