Add local metrics for message processing.

This commit is contained in:
Clark
2023-07-11 18:00:01 -04:00
committed by Clark Chen
parent 8fc03a67b9
commit ac4d8679a1
10 changed files with 129 additions and 36 deletions

View File

@@ -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
}
}

View File

@@ -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);
}
}
}
}