Skip to content

Commit 621c085

Browse files
authored
Merge pull request #3598 from dimagi/udate-file-encryption-time-tracing
Update file encryption time perf tracing
2 parents fdea70b + a396b26 commit 621c085

6 files changed

Lines changed: 71 additions & 20 deletions

File tree

app/src/org/commcare/android/logging/ForceCloseLogger.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ private static void sendToServerOrStore(Throwable exception) {
6262
ForceCloseLogEntry entry = new ForceCloseLogEntry(exceptionText);
6363

6464
try {
65-
DeviceReportWriter reportWriter = new DeviceReportWriter(streamToWriteErrorTo);
65+
DeviceReportWriter reportWriter = new DeviceReportWriter(streamToWriteErrorTo, true);
6666
reportWriter.addReportElement(new ForceCloseLogSerializer(entry));
6767
// TEMPORARILY write this in the old format as well, until HQ starts parsing the new one
6868
reportWriter.addReportElement(new AndroidLogSerializer<ForceCloseLogEntry>(entry));

app/src/org/commcare/google/services/analytics/CCPerfMonitoring.kt

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package org.commcare.google.services.analytics
22

33
import com.google.firebase.perf.FirebasePerformance
44
import com.google.firebase.perf.metrics.Trace
5-
import org.apache.commons.io.FilenameUtils
65
import org.commcare.android.logging.ReportingUtils
76
import org.javarosa.core.services.Logger
87

@@ -31,14 +30,15 @@ object CCPerfMonitoring {
3130
const val ATTR_MAP_MARKERS = "num_markers"
3231
const val ATTR_MAP_POLYGONS = "num_polygons"
3332
const val ATTR_MAP_GEO_POINTS = "num_geo_points"
34-
33+
const val ATTR_FILE_KEYSTORE_ENCRYPTED = "file_keystore_encrypted"
34+
const val ATTR_CC_APP = "cc_app"
3535

3636
fun startTracing(traceName: String): Trace? {
3737
try {
3838
val trace = FirebasePerformance.getInstance().newTrace(traceName)
39-
trace.putAttribute(CCAnalyticsParam.CCHQ_DOMAIN, ReportingUtils.getDomain())
40-
trace.putAttribute(CCAnalyticsParam.CC_APP_ID, ReportingUtils.getAppId())
41-
trace.putAttribute(CCAnalyticsParam.CC_APP_NAME, ReportingUtils.getAppName())
39+
trace.putAttribute(ATTR_CC_APP,
40+
ReportingUtils.getDomain() + "|" + ReportingUtils.getAppId() + "|" + ReportingUtils.getAppName()
41+
)
4242
trace.putAttribute(CCAnalyticsParam.USERNAME, ReportingUtils.getUser())
4343
trace.start()
4444
return trace
@@ -49,19 +49,26 @@ object CCPerfMonitoring {
4949
}
5050

5151
fun stopTracing(trace: Trace?, attrs: MutableMap<String, String>?) {
52+
if (trace == null) return
5253
try {
53-
attrs?.forEach { (key, value) -> trace?.putAttribute(key, value) }
54-
trace?.stop()
54+
attrs?.forEach { (key, value) -> trace.putAttribute(key, value) }
55+
trace.stop()
5556
} catch (exception: Exception) {
56-
Logger.exception("Error stopping perf trace: ${trace?.name?: "Unknown trace"}", exception)
57+
Logger.exception("Error stopping perf trace: ${trace.name}", exception)
5758
}
5859
}
5960

60-
fun stopFileEncryptionTracing(trace: Trace?, fileSizeBytes: Long, fileName: String) {
61+
fun stopFileEncryptionTracing(
62+
trace: Trace?,
63+
fileSizeBytes: Long,
64+
fileExtension: String,
65+
keystoreEncrypted: Boolean
66+
) {
6167
try {
6268
val attrs: MutableMap<String, String> = HashMap()
6369
attrs[ATTR_FILE_SIZE_BYTES] = fileSizeBytes.toString()
64-
attrs[ATTR_FILE_TYPE] = FilenameUtils.getExtension(fileName)
70+
attrs[ATTR_FILE_TYPE] = fileExtension
71+
attrs[ATTR_FILE_KEYSTORE_ENCRYPTED] = keystoreEncrypted.toString()
6572
stopTracing(trace, attrs)
6673
} catch (e: java.lang.Exception) {
6774
Logger.exception("Failed to stop tracing: $TRACE_FILE_ENCRYPTION_TIME", e)

app/src/org/commcare/logging/DeviceReportWriter.java

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
import android.os.Build;
44

5+
import com.google.common.io.CountingOutputStream;
6+
import com.google.firebase.perf.metrics.Trace;
7+
58
import org.commcare.AppUtils;
69
import org.commcare.CommCareApplication;
710
import org.commcare.android.javarosa.DeviceReportRecord;
11+
import org.commcare.google.services.analytics.CCPerfMonitoring;
812
import org.commcare.models.database.SqlStorage;
913
import org.javarosa.core.model.User;
1014
import org.javarosa.core.model.utils.DateUtils;
@@ -17,6 +21,8 @@
1721
import java.util.ArrayList;
1822
import java.util.Date;
1923

24+
import static org.commcare.utils.FileUtil.XML_EXTENSION;
25+
2026
/**
2127
* This class generates and serializes a device report to either a byte array
2228
* or to a file as designated by a log record
@@ -27,18 +33,34 @@ public class DeviceReportWriter {
2733
public static final String XMLNS = "http://code.javarosa.org/devicereport";
2834

2935
private final XmlSerializer serializer;
30-
private final OutputStream os;
36+
private final CountingOutputStream countingOutputStream;
3137
private final ArrayList<DeviceReportElement> elements = new ArrayList<>();
38+
private final boolean encryptionWithKeystore;
39+
private final boolean skipPerfTracing;
3240

3341
public DeviceReportWriter(DeviceReportRecord record) throws IOException {
34-
this(record.openOutputStream());
42+
this(record.openOutputStream(), record.shouldUseKeystoreKey(), false);
3543
}
3644

37-
public DeviceReportWriter(OutputStream outputStream) throws IOException {
38-
os = outputStream;
45+
/**
46+
* Constructor for in-memory report generation where the output stream is a ByteArrayOutputStream and no file
47+
* encryption occurs. When skipTracing is true, file encryption performance tracing is omitted
48+
*/
49+
public DeviceReportWriter(OutputStream outputStream, boolean skipPerfTracing) throws IOException {
50+
this(outputStream, false, skipPerfTracing);
51+
}
52+
53+
private DeviceReportWriter(
54+
OutputStream outputStream,
55+
boolean keystoreEncrypted,
56+
boolean skipPerfTracing
57+
) throws IOException {
58+
countingOutputStream = new CountingOutputStream(outputStream);
59+
encryptionWithKeystore = keystoreEncrypted;
60+
this.skipPerfTracing = skipPerfTracing;
3961

4062
serializer = new KXmlSerializer();
41-
serializer.setOutput(os, "UTF-8");
63+
serializer.setOutput(countingOutputStream, "UTF-8");
4264
serializer.setPrefix("", XMLNS);
4365

4466
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@@ -50,6 +72,10 @@ public void addReportElement(DeviceReportElement element) {
5072
}
5173

5274
public void write() throws IllegalArgumentException, IllegalStateException, IOException {
75+
Trace trace = null;
76+
if (!skipPerfTracing) {
77+
trace = CCPerfMonitoring.INSTANCE.startTracing(CCPerfMonitoring.TRACE_FILE_ENCRYPTION_TIME);
78+
}
5379
try {
5480
serializer.startDocument("UTF-8", null);
5581
serializer.startTag(XMLNS, "device_report");
@@ -80,7 +106,13 @@ public void write() throws IllegalArgumentException, IllegalStateException, IOEx
80106
serializer.endDocument();
81107
} finally {
82108
try {
83-
os.close();
109+
CCPerfMonitoring.INSTANCE.stopFileEncryptionTracing(
110+
trace,
111+
countingOutputStream.getCount(),
112+
XML_EXTENSION,
113+
encryptionWithKeystore
114+
);
115+
countingOutputStream.close();
84116
} catch (IOException e) {
85117
}
86118
}

app/src/org/commcare/models/database/HybridFileBackedSqlStorage.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import com.google.firebase.perf.metrics.Trace;
77

8+
import org.apache.commons.io.FilenameUtils;
89
import org.commcare.CommCareApplication;
910
import org.commcare.google.services.analytics.CCPerfMonitoring;
1011
import org.commcare.interfaces.AppFilePathBuilder;
@@ -345,7 +346,12 @@ private void writeStreamToFile(ByteArrayOutputStream bos, String filename,
345346
e.printStackTrace();
346347
}
347348
}
348-
CCPerfMonitoring.INSTANCE.stopFileEncryptionTracing(trace, bos.size(), filename);
349+
CCPerfMonitoring.INSTANCE.stopFileEncryptionTracing(
350+
trace,
351+
bos.size(),
352+
FilenameUtils.getExtension(filename),
353+
false
354+
);
349355
}
350356
}
351357

app/src/org/commcare/models/encryption/EncryptionIO.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.google.firebase.perf.metrics.Trace;
44

5+
import org.apache.commons.io.FilenameUtils;
56
import org.commcare.google.services.analytics.CCPerfMonitoring;
67
import org.commcare.util.LogTypes;
78
import org.commcare.utils.EncryptionKeyAndTransform;
@@ -45,7 +46,12 @@ public static void encryptFile(String sourceFilePath, String destPath, SecretKey
4546
int fileSize = is.available();
4647
StreamsUtil.writeFromInputToOutputNew(is, os);
4748

48-
CCPerfMonitoring.INSTANCE.stopFileEncryptionTracing(trace, fileSize, sourceFilePath);
49+
CCPerfMonitoring.INSTANCE.stopFileEncryptionTracing(
50+
trace,
51+
fileSize,
52+
FilenameUtils.getExtension(sourceFilePath),
53+
false
54+
);
4955
}
5056

5157
public static OutputStream createFileOutputStreamWithKeystore(

app/src/org/commcare/tasks/SaveToDiskTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ private void writeXmlToStream(ByteArrayPayload payload, OutputStream output) thr
269269
StreamsUtil.writeFromInputToOutput(is, output);
270270
} finally {
271271
output.close();
272-
CCPerfMonitoring.INSTANCE.stopFileEncryptionTracing(trace, payload.getLength(), XML_EXTENSION);
272+
CCPerfMonitoring.INSTANCE.stopFileEncryptionTracing(trace, payload.getLength(), XML_EXTENSION, false);
273273
}
274274
}
275275

0 commit comments

Comments
 (0)