Skip to content

Commit 67af913

Browse files
authored
Add session end fields to Crashlytics reports (firebase#1358)
1 parent bbed2eb commit 67af913

File tree

9 files changed

+262
-91
lines changed

9 files changed

+262
-91
lines changed

firebase-crashlytics/src/androidTest/java/com/google/firebase/crashlytics/internal/common/SessionReportingCoordinatorTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,10 @@ public void onUserId_writesUserToReportMetadata() {
328328
public void onSessionsFinalize_finalizesReports() {
329329
final String sessionId = "testSessionId";
330330
reportManager.onBeginSession(sessionId, System.currentTimeMillis());
331-
reportManager.finalizeSessions();
331+
final long endedAt = System.currentTimeMillis();
332+
reportManager.finalizeSessions(endedAt);
332333

333-
verify(reportPersistence).finalizeReports(sessionId);
334+
verify(reportPersistence).finalizeReports(sessionId, endedAt);
334335
}
335336

336337
@Test

firebase-crashlytics/src/androidTest/java/com/google/firebase/crashlytics/internal/model/serialization/CrashlyticsReportJsonTransformTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ private static CrashlyticsReport.Session makeTestSession() {
7373
return Session.builder()
7474
.setGenerator("generator")
7575
.setIdentifier("identifier")
76-
.setStartedAt(0)
76+
.setStartedAt(1L)
77+
.setEndedAt(1L)
78+
.setCrashed(true)
7779
.setApp(makeTestApplication())
7880
.setUser(User.builder().setIdentifier("user").build())
7981
.build();

firebase-crashlytics/src/androidTest/java/com/google/firebase/crashlytics/internal/persistence/CrashlyticsReportPersistenceTest.java

Lines changed: 93 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ public void testLoadFinalizeReports_noReports_returnsNothing() {
7575
@Test
7676
public void testLoadFinalizedReports_reportWithNoEvents_returnsNothing() {
7777
final String sessionId = "testSession";
78+
final long timestamp = System.currentTimeMillis();
7879
reportPersistence.persistReport(makeTestReport(sessionId));
79-
reportPersistence.finalizeReports(sessionId);
80+
reportPersistence.finalizeReports(sessionId, timestamp);
8081
assertTrue(reportPersistence.loadFinalizedReports().isEmpty());
8182
}
8283

@@ -88,12 +89,19 @@ public void testLoadFinalizedReports_reportThenEvent_returnsReportWithEvent() {
8889

8990
reportPersistence.persistReport(testReport);
9091
reportPersistence.persistEvent(testEvent, sessionId);
91-
reportPersistence.finalizeReports("skippedSession");
92+
93+
final long endedAt = System.currentTimeMillis();
94+
95+
reportPersistence.finalizeReports("skippedSession", endedAt);
9296

9397
final List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
9498
assertEquals(1, finalizedReports.size());
9599
final CrashlyticsReport finalizedReport = finalizedReports.get(0);
96-
assertEquals(testReport.withEvents(ImmutableList.from(testEvent)), finalizedReport);
100+
assertEquals(
101+
testReport
102+
.withSessionEndFields(endedAt, false, null)
103+
.withEvents(ImmutableList.from(testEvent)),
104+
finalizedReport);
97105
}
98106

99107
@Test
@@ -107,12 +115,18 @@ public void testLoadFinalizedReports_reportThenMultipleEvents_returnsReportWithM
107115
reportPersistence.persistEvent(testEvent, sessionId);
108116
reportPersistence.persistEvent(testEvent2, sessionId);
109117

110-
reportPersistence.finalizeReports("skippedSession");
118+
final long endedAt = System.currentTimeMillis();
119+
120+
reportPersistence.finalizeReports("skippedSession", endedAt);
111121

112122
final List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
113123
assertEquals(1, finalizedReports.size());
114124
final CrashlyticsReport finalizedReport = finalizedReports.get(0);
115-
assertEquals(testReport.withEvents(ImmutableList.from(testEvent, testEvent2)), finalizedReport);
125+
assertEquals(
126+
testReport
127+
.withSessionEndFields(endedAt, false, null)
128+
.withEvents(ImmutableList.from(testEvent, testEvent2)),
129+
finalizedReport);
116130
}
117131

118132
@Test
@@ -130,22 +144,35 @@ public void testLoadFinalizedReports_reportThenMultipleEvents_returnsReportWithM
130144
reportPersistence.persistEvent(testEvent1, sessionId1);
131145
reportPersistence.persistEvent(testEvent2, sessionId2);
132146

133-
reportPersistence.finalizeReports("skippedSession");
147+
final long endedAt = System.currentTimeMillis();
148+
149+
reportPersistence.finalizeReports("skippedSession", endedAt);
134150

135151
final List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
136152
assertEquals(2, finalizedReports.size());
137153
final CrashlyticsReport finalizedReport1 = finalizedReports.get(1);
138-
assertEquals(testReport1.withEvents(ImmutableList.from(testEvent1)), finalizedReport1);
154+
assertEquals(
155+
testReport1
156+
.withSessionEndFields(endedAt, false, null)
157+
.withEvents(ImmutableList.from(testEvent1)),
158+
finalizedReport1);
139159
final CrashlyticsReport finalizedReport2 = finalizedReports.get(0);
140-
assertEquals(testReport2.withEvents(ImmutableList.from(testEvent2)), finalizedReport2);
160+
assertEquals(
161+
testReport2
162+
.withSessionEndFields(endedAt, false, null)
163+
.withEvents(ImmutableList.from(testEvent2)),
164+
finalizedReport2);
141165
}
142166

143167
@Test
144168
public void testFinalizeReports_capsOpenSessions() throws IOException {
145169
for (int i = 0; i < 10; i++) {
146170
persistReportWithEvent(reportPersistence, "testSession" + i, true);
147171
}
148-
reportPersistence.finalizeReports("skippedSession");
172+
173+
final long endedAt = System.currentTimeMillis();
174+
175+
reportPersistence.finalizeReports("skippedSession", endedAt);
149176

150177
final List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
151178
assertEquals(8, finalizedReports.size());
@@ -157,7 +184,10 @@ public void testFinalizeReports_capsOldestSessionsFirst() throws IOException {
157184
for (int i = 0; i < 16; i++) {
158185
persistReportWithEvent(reportPersistence, "testSession" + format.format(i), true);
159186
}
160-
reportPersistence.finalizeReports("skippedSession");
187+
188+
final long endedAt = System.currentTimeMillis();
189+
190+
reportPersistence.finalizeReports("skippedSession", endedAt);
161191

162192
final List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
163193
assertEquals(8, finalizedReports.size());
@@ -182,11 +212,14 @@ public void testFinalizeReports_skipsCappingCurrentSession() throws IOException
182212
for (int i = 0; i < 16; i++) {
183213
persistReportWithEvent(reportPersistence, "testSession" + i, true);
184214
}
185-
reportPersistence.finalizeReports("testSession5");
215+
216+
final long endedAt = System.currentTimeMillis();
217+
218+
reportPersistence.finalizeReports("testSession5", endedAt);
186219
List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
187220
assertEquals(8, finalizedReports.size());
188221
persistReportWithEvent(reportPersistence, "testSession11", true);
189-
reportPersistence.finalizeReports("testSession11");
222+
reportPersistence.finalizeReports("testSession11", endedAt);
190223
finalizedReports = reportPersistence.loadFinalizedReports();
191224
assertEquals(9, finalizedReports.size());
192225
}
@@ -199,7 +232,8 @@ public void testFinalizeReports_capsReports() throws IOException {
199232
for (int i = 0; i < 10; i++) {
200233
persistReportWithEvent(reportPersistence, "testSession" + i, true);
201234
}
202-
reportPersistence.finalizeReports("skippedSession");
235+
236+
reportPersistence.finalizeReports("skippedSession", 0L);
203237

204238
final List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
205239
assertEquals(4, finalizedReports.size());
@@ -221,7 +255,8 @@ public void testFinalizeReports_whenSettingsChanges_capsReports() throws IOExcep
221255
for (int i = 0; i < 16; i++) {
222256
persistReportWithEvent(reportPersistence, "testSession" + format.format(i), true);
223257
}
224-
reportPersistence.finalizeReports("skippedSession");
258+
259+
reportPersistence.finalizeReports("skippedSession", 0L);
225260
List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
226261
assertEquals(4, finalizedReports.size());
227262
when(settingsMock.getSessionData()).thenReturn(sessionSettingsDataMockDifferentValues);
@@ -230,7 +265,7 @@ public void testFinalizeReports_whenSettingsChanges_capsReports() throws IOExcep
230265
persistReportWithEvent(reportPersistence, "testSession" + i, true);
231266
}
232267

233-
reportPersistence.finalizeReports("skippedSession");
268+
reportPersistence.finalizeReports("skippedSession", 0L);
234269

235270
finalizedReports = reportPersistence.loadFinalizedReports();
236271
assertEquals(8, finalizedReports.size());
@@ -248,7 +283,7 @@ public void testFinalizeReports_removesLowPriorityReportsFirst() throws IOExcept
248283
persistReportWithEvent(reportPersistence, sessionId, priority);
249284
}
250285

251-
reportPersistence.finalizeReports("skippedSession");
286+
reportPersistence.finalizeReports("skippedSession", 0L);
252287

253288
final List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
254289
assertEquals(4, finalizedReports.size());
@@ -267,7 +302,7 @@ public void testFinalizeReports_removesOldestReportsFirst() throws IOException {
267302
persistReportWithEvent(reportPersistence, sessionId, true);
268303
}
269304

270-
reportPersistence.finalizeReports("skippedSession");
305+
reportPersistence.finalizeReports("skippedSession", 0L);
271306

272307
final List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
273308
assertEquals(4, finalizedReports.size());
@@ -297,11 +332,13 @@ public void testLoadFinalizedReports_reportWithUserId_returnsReportWithProperUse
297332
reportPersistence.persistReport(testReport);
298333
reportPersistence.persistEvent(testEvent, sessionId);
299334
reportPersistence.persistUserIdForSession(userId, sessionId);
300-
reportPersistence.finalizeReports("skippedSession");
335+
336+
reportPersistence.finalizeReports("skippedSession", 0L);
301337

302338
final List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
303339
assertEquals(1, finalizedReports.size());
304340
final CrashlyticsReport finalizedReport = finalizedReports.get(0);
341+
assertNotNull(finalizedReport.getSession().getUser());
305342
assertEquals(userId, finalizedReport.getSession().getUser().getIdentifier());
306343
}
307344

@@ -324,13 +361,15 @@ public void testLoadFinalizedReports_reportWithUserId_returnsReportWithProperUse
324361
reportPersistence.persistUserIdForSession(userId1, sessionId1);
325362
reportPersistence.persistUserIdForSession(userId2, sessionId2);
326363

327-
reportPersistence.finalizeReports("skippedSession");
364+
reportPersistence.finalizeReports("skippedSession", 0L);
328365

329366
final List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
330367
assertEquals(2, finalizedReports.size());
331368
final CrashlyticsReport finalizedReport1 = finalizedReports.get(1);
369+
assertNotNull(finalizedReport1.getSession().getUser());
332370
assertEquals(userId1, finalizedReport1.getSession().getUser().getIdentifier());
333371
final CrashlyticsReport finalizedReport2 = finalizedReports.get(0);
372+
assertNotNull(finalizedReport2.getSession().getUser());
334373
assertEquals(userId2, finalizedReport2.getSession().getUser().getIdentifier());
335374
}
336375

@@ -342,7 +381,8 @@ public void testDeleteFinalizedReport_removesReports() {
342381

343382
reportPersistence.persistReport(testReport);
344383
reportPersistence.persistEvent(testEvent, sessionId);
345-
reportPersistence.finalizeReports("skippedSession");
384+
385+
reportPersistence.finalizeReports("skippedSession", 0L);
346386

347387
assertEquals(1, reportPersistence.loadFinalizedReports().size());
348388

@@ -359,7 +399,8 @@ public void testDeleteFinalizedReport_withWrongSessionId_doesNotRemoveReports()
359399

360400
reportPersistence.persistReport(testReport);
361401
reportPersistence.persistEvent(testEvent, sessionId);
362-
reportPersistence.finalizeReports("skippedSession");
402+
403+
reportPersistence.finalizeReports("skippedSession", 0L);
363404

364405
assertEquals(1, reportPersistence.loadFinalizedReports().size());
365406

@@ -382,7 +423,7 @@ public void testDeleteAllReports_removesAllReports() {
382423
reportPersistence.persistEvent(testEvent1, sessionId1);
383424
reportPersistence.persistEvent(testEvent2, sessionId2);
384425

385-
reportPersistence.finalizeReports("skippedSession");
426+
reportPersistence.finalizeReports("skippedSession", 0L);
386427

387428
assertEquals(2, reportPersistence.loadFinalizedReports().size());
388429

@@ -410,14 +451,19 @@ public void testPersistEvent_keepsAppropriateNumberOfMostRecentEvents() throws I
410451
reportPersistence.persistEvent(testEvent3, sessionId);
411452
reportPersistence.persistEvent(testEvent4, sessionId);
412453
reportPersistence.persistEvent(testEvent5, sessionId);
413-
reportPersistence.finalizeReports("skippedSession");
454+
455+
final long endedAt = System.currentTimeMillis();
456+
457+
reportPersistence.finalizeReports("skippedSession", endedAt);
414458

415459
final List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
416460
assertEquals(1, finalizedReports.size());
417461
final CrashlyticsReport finalizedReport = finalizedReports.get(0);
418462
assertEquals(4, finalizedReport.getSession().getEvents().size());
419463
assertEquals(
420-
testReport.withEvents(ImmutableList.from(testEvent2, testEvent3, testEvent4, testEvent5)),
464+
testReport
465+
.withSessionEndFields(endedAt, false, null)
466+
.withEvents(ImmutableList.from(testEvent2, testEvent3, testEvent4, testEvent5)),
421467
finalizedReport);
422468
}
423469

@@ -448,14 +494,19 @@ public void testPersistEvent_whenSettingsChanges_keepsAppropriateNumberOfMostRec
448494
reportPersistence.persistEvent(testEvent3, sessionId);
449495
reportPersistence.persistEvent(testEvent4, sessionId);
450496
reportPersistence.persistEvent(testEvent5, sessionId);
451-
reportPersistence.finalizeReports("skippedSession");
497+
498+
long endedAt = System.currentTimeMillis();
499+
500+
reportPersistence.finalizeReports("skippedSession", endedAt);
452501

453502
final List<CrashlyticsReport> finalizedReports = reportPersistence.loadFinalizedReports();
454503
assertEquals(1, finalizedReports.size());
455504
final CrashlyticsReport finalizedReport = finalizedReports.get(0);
456505
assertEquals(4, finalizedReport.getSession().getEvents().size());
457506
assertEquals(
458-
testReport.withEvents(ImmutableList.from(testEvent2, testEvent3, testEvent4, testEvent5)),
507+
testReport
508+
.withSessionEndFields(endedAt, false, null)
509+
.withEvents(ImmutableList.from(testEvent2, testEvent3, testEvent4, testEvent5)),
459510
finalizedReport);
460511

461512
when(settingsMock.getSessionData()).thenReturn(sessionSettingsDataMockDifferentValues);
@@ -479,23 +530,28 @@ public void testPersistEvent_whenSettingsChanges_keepsAppropriateNumberOfMostRec
479530
reportPersistence.persistEvent(testEvent8, sessionId2);
480531
reportPersistence.persistEvent(testEvent9, sessionId2);
481532
reportPersistence.persistEvent(testEvent10, sessionId2);
482-
reportPersistence.finalizeReports("skippedSession");
533+
534+
endedAt = System.currentTimeMillis();
535+
536+
reportPersistence.finalizeReports("skippedSession", endedAt);
483537

484538
final List<CrashlyticsReport> finalizedReports2 = reportPersistence.loadFinalizedReports();
485539
assertEquals(2, finalizedReports2.size());
486540
final CrashlyticsReport finalizedReport2 = finalizedReports2.get(0);
487541
assertEquals(8, finalizedReport2.getSession().getEvents().size());
488542
assertEquals(
489-
testReport2.withEvents(
490-
ImmutableList.from(
491-
testEvent3,
492-
testEvent4,
493-
testEvent5,
494-
testEvent6,
495-
testEvent7,
496-
testEvent8,
497-
testEvent9,
498-
testEvent10)),
543+
testReport2
544+
.withSessionEndFields(endedAt, false, null)
545+
.withEvents(
546+
ImmutableList.from(
547+
testEvent3,
548+
testEvent4,
549+
testEvent5,
550+
testEvent6,
551+
testEvent7,
552+
testEvent8,
553+
testEvent9,
554+
testEvent10)),
499555
finalizedReport2);
500556
}
501557

firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/CrashlyticsController.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ public Task<Void> call() throws Exception {
397397
// We've fatally crashed, so write the marker file that indicates a crash occurred.
398398
crashMarker.create();
399399

400-
long timestampSeconds = time.getTime() / 1000;
400+
long timestampSeconds = getTimestampSeconds(time);
401401
reportingCoordinator.persistFatalEvent(ex, thread, timestampSeconds);
402402
writeFatal(thread, ex, timestampSeconds);
403403

@@ -648,7 +648,7 @@ void writeNonFatalException(final Thread thread, final Throwable ex) {
648648
@Override
649649
public void run() {
650650
if (!isHandlingException()) {
651-
long timestampSeconds = time.getTime() / 1000;
651+
long timestampSeconds = getTimestampSeconds(time);
652652
reportingCoordinator.persistNonFatalEvent(ex, thread, timestampSeconds);
653653
doWriteNonFatal(thread, ex, timestampSeconds);
654654
}
@@ -802,7 +802,7 @@ boolean finalizeSessions(int maxCustomExceptionEvents) {
802802
* class.
803803
*/
804804
private void doOpenSession() throws Exception {
805-
final long startedAtSeconds = new Date().getTime() / 1000;
805+
final long startedAtSeconds = getCurrentTimestampSeconds();
806806
final String sessionIdentifier = new CLSUUID(idManager).toString();
807807

808808
Logger.getLogger().d("Opening a new session with ID " + sessionIdentifier);
@@ -860,7 +860,7 @@ private void doCloseSessions(int maxCustomExceptionEvents, boolean includeCurren
860860

861861
closeOpenSessions(sessionBeginFiles, offset, maxCustomExceptionEvents);
862862

863-
reportingCoordinator.finalizeSessions();
863+
reportingCoordinator.finalizeSessions(getCurrentTimestampSeconds());
864864
}
865865

866866
/**
@@ -1196,6 +1196,14 @@ private static void gzip(@NonNull byte[] bytes, @NonNull File path) throws IOExc
11961196
}
11971197
}
11981198

1199+
private static long getCurrentTimestampSeconds() {
1200+
return getTimestampSeconds(new Date());
1201+
}
1202+
1203+
private static long getTimestampSeconds(Date date) {
1204+
return date.getTime() / 1000;
1205+
}
1206+
11991207
/** Removes dashes in the Crashlytics session identifier to conform to Firebase constraints. */
12001208
private static String makeFirebaseSessionIdentifier(String sessionIdentifier) {
12011209
return sessionIdentifier.replaceAll("-", "");
@@ -1586,7 +1594,7 @@ private void synthesizeSessionFile(
15861594
Logger.getLogger().d("Collecting SessionStart data for session ID " + sessionId);
15871595
writeToCosFromFile(cos, sessionBeginFile);
15881596

1589-
cos.writeUInt64(4, new Date().getTime() / 1000);
1597+
cos.writeUInt64(4, getCurrentTimestampSeconds());
15901598
cos.writeBool(5, hasFatal);
15911599

15921600
cos.writeUInt32(11, ANALYZER_VERSION);

0 commit comments

Comments
 (0)