Skip to content

Commit 470f637

Browse files
committed
Clean up and clarify Crashlytics logging.
Made some log messages clearer and easier to understand, also reduced noise by changing the log level on existing logs to: E: Unexpected/error state, not recoverable. Crashlytics will not function. W: Unexpected/error state, but recoverable. D: SDK lifecycle logs ("what" is happening). - Unix-style "no news is good news" logging, if something goes wrong, it will appear in W or E logs. V: Finer-grained logging ("how" things are happening). - "Success" logs, as well as logging of internally-stored values (e.g. current mapping file ID) are logged at this level. Also modified a few logs to *only* print in an error case.
1 parent ddf2654 commit 470f637

18 files changed

+102
-93
lines changed

firebase-crashlytics-ndk/src/main/java/com/google/firebase/crashlytics/ndk/CrashpadController.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public boolean initialize(String sessionId) {
5555
initSuccess = nativeApi.initialize(crashReportPath, context.getAssets());
5656
}
5757
} catch (IOException e) {
58-
Logger.getLogger().e("Error initializing CrashlyticsNdk", e);
58+
Logger.getLogger().e("Error initializing Crashlytics NDK", e);
5959
}
6060
return initSuccess;
6161
}
@@ -82,12 +82,14 @@ public SessionFiles getFilesForSession(String sessionId) {
8282
final File sessionFileDirectoryForMinidump = new File(sessionFileDirectory, "pending");
8383

8484
Logger.getLogger()
85-
.d("Minidump directory: " + sessionFileDirectoryForMinidump.getAbsolutePath());
85+
.v("Minidump directory: " + sessionFileDirectoryForMinidump.getAbsolutePath());
8686

8787
File minidump = getSingleFileWithExtension(sessionFileDirectoryForMinidump, ".dmp");
8888

8989
Logger.getLogger()
90-
.d("Minidump " + (minidump != null && minidump.exists() ? "exists" : "does not exist"));
90+
.v(
91+
"Minidump file "
92+
+ (minidump != null && minidump.exists() ? "exists" : "does not exist"));
9193

9294
final SessionFiles.Builder builder = new SessionFiles.Builder();
9395
if (sessionFileDirectory != null

firebase-crashlytics-ndk/src/main/java/com/google/firebase/crashlytics/ndk/FirebaseCrashlyticsNdk.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ public boolean hasCrashDataForSession(@NonNull String sessionId) {
5050
@Override
5151
public boolean openSession(String sessionId) {
5252
final boolean initSuccess = controller.initialize(sessionId);
53-
Logger.getLogger()
54-
.i("Crashlytics NDK initialization " + (initSuccess ? "successful" : "FAILED"));
53+
if (!initSuccess) {
54+
Logger.getLogger().w("Failed to initialize Crashlytics NDK for session " + sessionId);
55+
}
5556
return initSuccess;
5657
}
5758

firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/CrashlyticsAnalyticsListener.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.google.firebase.analytics.connector.AnalyticsConnector.AnalyticsConnectorListener;
2121
import com.google.firebase.crashlytics.internal.Logger;
2222
import com.google.firebase.crashlytics.internal.analytics.AnalyticsEventReceiver;
23+
import java.util.Locale;
2324

2425
/**
2526
* Crashlytics listener for Firebase Analytics events. Processes incoming events and passes those
@@ -46,7 +47,10 @@ public void setBreadcrumbEventReceiver(@Nullable AnalyticsEventReceiver receiver
4647

4748
@Override
4849
public void onMessageTriggered(int id, @Nullable Bundle extras) {
49-
Logger.getLogger().d("Received Analytics message: " + id + " " + extras);
50+
Logger.getLogger()
51+
.v(
52+
String.format(
53+
Locale.US, "Analytics listener received message. ID: %d, Extras: %s", id, extras));
5054

5155
if (extras == null) {
5256
return;

firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ public class FirebaseCrashlytics {
9292

9393
if (analyticsConnector != null) {
9494
// If FA is available, create a logger to log events from the Crashlytics origin.
95-
Logger.getLogger().d("Firebase Analytics is available.");
9695
final CrashlyticsOriginAnalyticsEventLogger directAnalyticsEventLogger =
9796
new CrashlyticsOriginAnalyticsEventLogger(analyticsConnector);
9897

@@ -107,7 +106,7 @@ public class FirebaseCrashlytics {
107106
subscribeToAnalyticsEvents(analyticsConnector, crashlyticsAnalyticsListener);
108107

109108
if (analyticsConnectorHandle != null) {
110-
Logger.getLogger().d("Firebase Analytics listener registered successfully.");
109+
Logger.getLogger().d("Registered Firebase Analytics listener.");
111110
// Create the event receiver which will supply breadcrumb events to Crashlytics
112111
final BreadcrumbAnalyticsEventReceiver breadcrumbReceiver =
113112
new BreadcrumbAnalyticsEventReceiver();
@@ -132,7 +131,8 @@ public class FirebaseCrashlytics {
132131
// Set the blocking analytics event logger for Crashlytics.
133132
analyticsEventLogger = blockingAnalyticsEventLogger;
134133
} else {
135-
Logger.getLogger().d("Firebase Analytics listener registration failed.");
134+
Logger.getLogger()
135+
.w("Could not register Firebase Analytics listener; a listener is already registered.");
136136
// FA is enabled, but the listener was not registered successfully.
137137
// We cannot listen for breadcrumbs.
138138
breadcrumbSource = new DisabledBreadcrumbSource();
@@ -142,7 +142,7 @@ public class FirebaseCrashlytics {
142142
}
143143
} else {
144144
// FA is entirely unavailable. We cannot listen for breadcrumbs or send events.
145-
Logger.getLogger().d("Firebase Analytics is unavailable.");
145+
Logger.getLogger().d("Firebase Analytics is not available.");
146146
breadcrumbSource = new DisabledBreadcrumbSource();
147147
analyticsEventLogger = new UnavailableAnalyticsEventLogger();
148148
}
@@ -161,7 +161,7 @@ public class FirebaseCrashlytics {
161161

162162
final String googleAppId = app.getOptions().getApplicationId();
163163
final String mappingFileId = CommonUtils.getMappingFileId(context);
164-
Logger.getLogger().d("Mapping file ID is: " + mappingFileId);
164+
Logger.getLogger().v("Mapping file ID is: " + mappingFileId);
165165

166166
final UnityVersionProvider unityVersionProvider = new ResourceUnityVersionProvider(context);
167167

@@ -170,11 +170,11 @@ public class FirebaseCrashlytics {
170170
appData =
171171
AppData.create(context, idManager, googleAppId, mappingFileId, unityVersionProvider);
172172
} catch (PackageManager.NameNotFoundException e) {
173-
Logger.getLogger().e("Could not retrieve app info, initialization failed.", e);
173+
Logger.getLogger().e("Error retrieving app package info.", e);
174174
return null;
175175
}
176176

177-
Logger.getLogger().d("Installer package name is: " + appData.installerPackageName);
177+
Logger.getLogger().v("Installer package name is: " + appData.installerPackageName);
178178

179179
final ExecutorService threadPoolExecutor =
180180
ExecutorUtils.buildSingleThreadExecutorService("com.google.firebase.crashlytics.startup");
@@ -282,7 +282,7 @@ public static FirebaseCrashlytics getInstance() {
282282
*/
283283
public void recordException(@NonNull Throwable throwable) {
284284
if (throwable == null) { // Users could call this with null despite the annotation.
285-
Logger.getLogger().w("Crashlytics is ignoring a request to log a null exception.");
285+
Logger.getLogger().v("A null value was passed to recordException. Ignoring.");
286286
return;
287287
}
288288
core.logException(throwable);

firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/analytics/BlockingAnalyticsEventLogger.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,23 +51,25 @@ public BlockingAnalyticsEventLogger(
5151
@Override
5252
public void logEvent(@NonNull String name, @Nullable Bundle params) {
5353
synchronized (latchLock) {
54-
Logger.getLogger().d("Logging Crashlytics event to Firebase");
54+
Logger.getLogger()
55+
.v("Logging event " + name + " to Firebase Analytics with params " + params);
5556
this.eventLatch = new CountDownLatch(1);
5657
this.callbackReceived = false;
5758

5859
baseAnalyticsEventLogger.logEvent(name, params);
5960

60-
Logger.getLogger().d("Awaiting app exception callback from FA...");
61+
Logger.getLogger().v("Awaiting app exception callback from Analytics...");
6162
try {
6263
if (eventLatch.await(timeout, timeUnit)) {
6364
callbackReceived = true;
64-
Logger.getLogger().d("App exception callback received from FA listener.");
65+
Logger.getLogger().v("App exception callback received from Analytics listener.");
6566
} else {
6667
Logger.getLogger()
67-
.d("Timeout exceeded while awaiting app exception callback from FA listener.");
68+
.w("Timeout exceeded while awaiting app exception callback from Analytics listener.");
6869
}
6970
} catch (InterruptedException ie) {
70-
Logger.getLogger().d("Interrupted while awaiting app exception callback from FA listener.");
71+
Logger.getLogger()
72+
.e("Interrupted while awaiting app exception callback from Analytics listener.");
7173
}
7274

7375
this.eventLatch = null;

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ static Architecture getValue() {
158158
String arch = Build.CPU_ABI;
159159

160160
if (TextUtils.isEmpty(arch)) {
161-
Logger.getLogger().d("Architecture#getValue()::Build.CPU_ABI returned null or empty");
161+
Logger.getLogger().v("Architecture#getValue()::Build.CPU_ABI returned null or empty");
162162
return UNKNOWN;
163163
}
164164

@@ -195,7 +195,7 @@ public static synchronized long getTotalRamInBytes() {
195195
// leave in this handling since we don't know for certain it isn't.
196196
bytes = convertMemInfoToBytes(result, "GB", BYTES_IN_A_GIGABYTE);
197197
} else {
198-
Logger.getLogger().d("Unexpected meminfo format while computing RAM: " + result);
198+
Logger.getLogger().w("Unexpected meminfo format while computing RAM: " + result);
199199
}
200200
} catch (NumberFormatException e) {
201201
Logger.getLogger().e("Unexpected meminfo format while computing RAM: " + result, e);
@@ -606,7 +606,7 @@ public static String resolveUnityEditorVersion(Context context) {
606606
final int id = CommonUtils.getResourcesIdentifier(context, UNITY_EDITOR_VERSION, "string");
607607
if (id != 0) {
608608
version = context.getResources().getString(id);
609-
Logger.getLogger().d("Unity Editor version is: " + version);
609+
Logger.getLogger().v("Unity Editor version is: " + version);
610610
}
611611
return version;
612612
}

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

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,7 @@ synchronized void handleUncaughtException(
165165
@NonNull final Throwable ex) {
166166

167167
Logger.getLogger()
168-
.d(
169-
"Crashlytics is handling uncaught "
170-
+ "exception \""
171-
+ ex
172-
+ "\" from thread "
173-
+ thread.getName());
168+
.d("Handling uncaught " + "exception \"" + ex + "\" from thread " + thread.getName());
174169

175170
// Capture the time that the crash occurs and close over it so that the time doesn't
176171
// reflect when we get around to executing the task later.
@@ -258,7 +253,7 @@ private Task<Boolean> waitForReportAction() {
258253
}
259254

260255
Logger.getLogger().d("Automatic data collection is disabled.");
261-
Logger.getLogger().d("Notifying that unsent reports are available.");
256+
Logger.getLogger().v("Notifying that unsent reports are available.");
262257
unsentReportsAvailable.trySetResult(true);
263258

264259
// If data collection gets enabled while we are waiting for an action, go ahead and send the
@@ -289,7 +284,7 @@ boolean didCrashOnPreviousExecution() {
289284
return sessionId != null && nativeComponent.hasCrashDataForSession(sessionId);
290285
}
291286

292-
Logger.getLogger().d("Found previous crash marker.");
287+
Logger.getLogger().v("Found previous crash marker.");
293288
crashMarker.remove();
294289

295290
return Boolean.TRUE;
@@ -302,7 +297,7 @@ Task<Boolean> checkForUnsentReports() {
302297
// and 2) when there's a fatal crash. So no new reports will become available while the app is
303298
// running.
304299
if (!checkForUnsentReportsCalled.compareAndSet(false, true)) {
305-
Logger.getLogger().d("checkForUnsentReports should only be called once per execution.");
300+
Logger.getLogger().w("checkForUnsentReports should only be called once per execution.");
306301
return Tasks.forResult(false);
307302
}
308303
return unsentReportsAvailable.getTask();
@@ -321,11 +316,11 @@ Task<Void> deleteUnsentReports() {
321316
Task<Void> submitAllReports(Task<AppSettingsData> appSettingsDataTask) {
322317
if (!reportingCoordinator.hasReportsToSend()) {
323318
// Just notify the user that there are no reports and stop.
324-
Logger.getLogger().d("No reports are available.");
319+
Logger.getLogger().v("No crash reports are available to be sent.");
325320
unsentReportsAvailable.trySetResult(false);
326321
return Tasks.forResult(null);
327322
}
328-
Logger.getLogger().d("Unsent reports are available.");
323+
Logger.getLogger().v("Crash reports are available to be sent.");
329324

330325
return waitForReportAction()
331326
.onSuccessTask(
@@ -339,14 +334,14 @@ public Task<Void> then(@Nullable Boolean send) throws Exception {
339334
@Override
340335
public Task<Void> call() throws Exception {
341336
if (!send) {
342-
Logger.getLogger().d("Reports are being deleted.");
337+
Logger.getLogger().v("Deleting cached crash reports...");
343338
deleteFiles(listAppExceptionMarkerFiles());
344339
reportingCoordinator.removeAllReports();
345340
unsentReportsHandled.trySetResult(null);
346341
return Tasks.forResult(null);
347342
}
348343

349-
Logger.getLogger().d("Reports are being sent.");
344+
Logger.getLogger().d("Sending cached crash reports...");
350345

351346
// waitForReportAction guarantees we got user permission.
352347
boolean dataCollectionToken = send;
@@ -367,7 +362,7 @@ public Task<Void> then(@Nullable AppSettingsData appSettingsData)
367362
if (appSettingsData == null) {
368363
Logger.getLogger()
369364
.w(
370-
"Received null app settings, cannot send reports during app startup.");
365+
"Received null app settings at app startup. Cannot send cached reports");
371366
return Tasks.forResult(null);
372367
}
373368
logAnalyticsAppExceptionEvents();
@@ -414,7 +409,7 @@ public void run() {
414409
final String currentSessionId = getCurrentSessionId();
415410
if (currentSessionId == null) {
416411
Logger.getLogger()
417-
.d("Tried to write a non-fatal exception while no session was open.");
412+
.w("Tried to write a non-fatal exception while no session was open.");
418413
return;
419414
}
420415
reportingCoordinator.persistNonFatalEvent(
@@ -526,18 +521,18 @@ boolean finalizeSessions() {
526521
backgroundWorker.checkRunningOnThread();
527522

528523
if (isHandlingException()) {
529-
Logger.getLogger().d("Skipping session finalization because a crash has already occurred.");
524+
Logger.getLogger().w("Skipping session finalization because a crash has already occurred.");
530525
return Boolean.FALSE;
531526
}
532527

533-
Logger.getLogger().d("Finalizing previously open sessions.");
528+
Logger.getLogger().v("Finalizing previously open sessions.");
534529
try {
535530
doCloseSessions(true);
536531
} catch (Exception e) {
537532
Logger.getLogger().e("Unable to finalize previously open sessions.", e);
538533
return false;
539534
}
540-
Logger.getLogger().d("Closed all previously open sessions");
535+
Logger.getLogger().v("Closed all previously open sessions.");
541536

542537
return true;
543538
}
@@ -577,7 +572,7 @@ private void doCloseSessions(boolean skipCurrentSession) {
577572
List<String> sortedOpenSessions = reportingCoordinator.listSortedOpenSessionIds();
578573

579574
if (sortedOpenSessions.size() <= offset) {
580-
Logger.getLogger().d("No open sessions to be closed.");
575+
Logger.getLogger().v("No open sessions to be closed.");
581576
return;
582577
}
583578

@@ -588,7 +583,7 @@ private void doCloseSessions(boolean skipCurrentSession) {
588583
// data when we aren't including current.
589584
finalizePreviousNativeSession(mostRecentSessionIdToClose);
590585
if (!nativeComponent.finalizeSession(mostRecentSessionIdToClose)) {
591-
Logger.getLogger().d("Could not finalize native session: " + mostRecentSessionIdToClose);
586+
Logger.getLogger().w("Could not finalize native session: " + mostRecentSessionIdToClose);
592587
}
593588
}
594589

@@ -627,7 +622,7 @@ private static File[] ensureFileArrayNotNull(File[] files) {
627622
// endregion
628623

629624
private void finalizePreviousNativeSession(String previousSessionId) {
630-
Logger.getLogger().d("Finalizing native report for session " + previousSessionId);
625+
Logger.getLogger().v("Finalizing native report for session " + previousSessionId);
631626
NativeSessionFileProvider nativeSessionFileProvider =
632627
nativeComponent.getSessionFileProvider(previousSessionId);
633628
File minidumpFile = nativeSessionFileProvider.getMinidumpFile();
@@ -643,7 +638,7 @@ private void finalizePreviousNativeSession(String previousSessionId) {
643638
final File nativeSessionDirectory = new File(getNativeSessionFilesDir(), previousSessionId);
644639

645640
if (!nativeSessionDirectory.mkdirs()) {
646-
Logger.getLogger().d("Couldn't create native sessions directory");
641+
Logger.getLogger().w("Couldn't create directory to store native session files, aborting.");
647642
return;
648643
}
649644

@@ -673,7 +668,7 @@ private void doWriteAppExceptionMarker(long eventTime) {
673668
try {
674669
new File(getFilesDir(), APP_EXCEPTION_MARKER_PREFIX + eventTime).createNewFile();
675670
} catch (IOException e) {
676-
Logger.getLogger().d("Could not write app exception marker.");
671+
Logger.getLogger().w("Could not create app exception marker file.", e);
677672
}
678673
}
679674

@@ -772,7 +767,7 @@ private Task<Void> logAnalyticsAppExceptionEvents() {
772767
Long.parseLong(markerFile.getName().substring(APP_EXCEPTION_MARKER_PREFIX.length()));
773768
events.add(logAnalyticsAppExceptionEvent(timestamp));
774769
} catch (NumberFormatException nfe) {
775-
Logger.getLogger().d("Could not parse timestamp from file " + markerFile.getName());
770+
Logger.getLogger().w("Could not parse timestamp from file " + markerFile.getName());
776771
}
777772
markerFile.delete();
778773
}
@@ -782,9 +777,10 @@ private Task<Void> logAnalyticsAppExceptionEvents() {
782777

783778
private Task<Void> logAnalyticsAppExceptionEvent(long timestamp) {
784779
if (firebaseCrashExists()) {
785-
Logger.getLogger().d("Skipping logging Crashlytics event to Firebase, FirebaseCrash exists");
780+
Logger.getLogger().v("Skipping logging Crashlytics event to Firebase, FirebaseCrash exists");
786781
return Tasks.forResult(null);
787782
}
783+
Logger.getLogger().d("Logging app exception event to Firebase Analytics");
788784
final ThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
789785
return Tasks.call(
790786
executor,

0 commit comments

Comments
 (0)