How do I get Google Analytics v4 to report uncaught exceptions (crashes) for my application?

I have been banging my head on the wall for several hours. The v4 docs for Google Analytics provides two different ways to get your application to report uncaught exceptions. I can neither work nor work. In both cases, I see lines like this in LogCat when I throw an uncaught exception in my application (using dummy names for my own code):

08-17 17:33:30.248: V/GAV4(8968): Thread[main,5,main]: Tracking Exception: MyException (@MyClass:myMethod:143) {main} 08-17 17:33:30.248: V/GAV4(8968): Thread[main,5,main]: Dispatch call queued. Dispatch will run once initialization is complete. 08-17 17:33:30.248: V/GAV4(8968): Thread[main,5,main]: Passing exception to original handler. 

... followed by stacktrace for my exception, and then finally:

 08-17 17:33:44.282: I/Process(8968): Sending signal. PID: 8968 SIG: 9 

From LogCat, it looks like GA never sends an exception to Google's servers!

If someone managed to get the fuzzy exceptions reported in their Google Analytics Console, it would be great if they could share with us how they did it, please. I saw other people on SO with such requests (for example, here and here ), but no confirmation reported fuzzy exceptions.

I have screens displayed in the GA console, so I have to do something right. But exceptions are not excluded. I assume that you need to look for them in the Behavior> Failures and Exceptions section, and I set an end date to enable it today (by default it is set yesterday). Finally, in my analytics_global_config.xml I have:

 <integer name="ga_dispatchPeriod">1</integer> 

since otherwise the default value is 1800 seconds, in which case I assume that the exceptions will not be displayed in the GA console for at least 30 minutes after they occur. ga_dryRun also false.

+5
source share
3 answers

As @xitx noted, it looks like there is a bug in later versions of the Google Play Services library installed on people's devices. Because when I ran my existing code on the emulator for a relatively old device (API 9 and presumably started the old Google Play Services library), the alarm did automatically passed to the GA console. Here is what LogCat said when the crash occurred:

 08-31 12:27:59.522: V/GAV4(335): Thread[GAThread,5,main]: Sending hit to store PATH: https: PARAMS: ul=en-us, ht=1409484468454, sr=480x800, a=746864705, sf=100.0, aid=com.redula.vsavings, cid=32da19a1-7e15-4c83-aaa9-f3f1d502b775, av=1.2, v=1, t=exception, an=Savings Organiser, tid=UA-XXXXXXXX, exd=NullPointerException (@HomeActivity:connectToInAppBillingService:202) {main}, _u=.2nKKhAAAL, exf=1, 08-31 12:27:59.622: V/GAV4(335): Thread[GAThread,5,main]: PowerSaveMode initiated. 08-31 12:27:59.652: V/GAV4(335): Thread[GAThread,5,main]: PowerSaveMode terminated. 08-31 12:27:59.652: V/GAV4(335): Thread[GAThread,5,main]: Dispatch running... 08-31 12:27:59.702: V/GAV4(335): Thread[GAThread,5,main]: User-Agent: GoogleAnalytics/3.0 (Linux; U; Android 2.3.1; en-us; sdk Build/GSI11) 08-31 12:27:59.702: V/GAV4(335): Host: ssl.google-analytics.com 08-31 12:27:59.702: V/GAV4(335): GET /collect?ul=en-us&ht=1409484468454&sr=480x800&a=746864705&sf=100.0&aid=com.redula.vsavings&cid=32da19a1-7e15-4c83-aaa9-f3f1d502b775&av=1.2&v=1&t=exception&an=Savings+Organiser&tid=UA-XXXXXXX&exd=NullPointerException+%28%40HomeActivity%3AconnectToInAppBillingService%3A202%29+%7Bmain%7D&_u=.2nKKhAAAL&_v=ma4.0.2&exf=1&qt=11249&z=2 HTTP/1.1 08-31 12:28:00.482: V/GAV4(335): Thread[GAThread,5,main]: sent 1 of 1 hits 08-31 12:28:00.492: V/GAV4(335): Thread[GAThread,5,main]: PowerSaveMode initiated. 08-31 12:32:48.562: I/Process(335): Sending signal. PID: 335 SIG: 9 

And here's what the GA console showed up in a minute or so:

enter image description here

I know that you will only get the first stacktrace line, but now it will be for me. Other people have their own approaches to getting the whole stacktrace (see, for example, @xitx comments above and here ).

Therefore, I plan to use my existing code and wait for Google to submit a fix for its error in a later version of the Google Play Service. My application should work like this: as soon as their fix is ​​released.

For the record, I use this in the tracker XML file (res / xml / app_tracker_config.xml):

 <bool name="ga_reportUncaughtExceptions">true</bool> 

My implementation of getTracker ():

 public class MyApp extends Application { private static Tracker tracker = null; synchronized Tracker getTracker() { if (tracker == null) { GoogleAnalytics analytics = GoogleAnalytics.getInstance(this); analytics.enableAutoActivityReports(this); tracker = analytics.newTracker(R.xml.app_tracker_config); tracker.enableAdvertisingIdCollection(true); } return tracker; } } 

Then in onCreate () for my activity on the main screen, I just do this to initialize GA:

 ((MyApp) getApplication()).getTracker(); 

EDIT (additional information): global configuration file, res / xml / analytics_global_config.xml:

 <?xml version="1.0" encoding="utf-8"?> <resources> <string name="ga_logLevel">verbose</string> <integer name="ga_dispatchPeriod">1</integer> <bool name="ga_dryRun">false</bool> </resources> 

My application manifest refers to this file in this child tag of the application element:

  <meta-data android:name="com.google.android.gms.analytics.globalConfigResource" android:resource="@xml/analytics_global_config" /> 
+7
source

Just add this to your manifest

 <meta-data android:name="com.google.android.gms.analytics.globalConfigResource" android:resource="@xml/tracker.xml" /> 

After that, you should start getting in this logcat:

 V/GAV4﹕ Thread[main,5,main]: Tracking Exception: ArithmeticException (@MyActivity:onResume:111) {main} V/GAV4﹕ Thread[main,5,main]: Dispatch call queued. Dispatch will run once initialization is complete. V/GAV4﹕ Thread[main,5,main]: Passing exception to original handler. 

After restarting the application:

 V/GAV4﹕ Thread[client_id_fetcher,5,main]: Loaded client id from disk. V/GAV4﹕ Thread[main,5,main]: Loading Tracker config values. V/GAV4﹕ Thread[main,5,main]: [Tracker] trackingId loaded: UA-XXXXXXXX-X V/GAV4﹕ Thread[main,5,main]: [Tracker] session timeout loaded: 300000 V/GAV4﹕ Thread[main,5,main]: ExceptionReporter created, original handler is com.android.internal.os.RuntimeInit$UncaughtHandler V/GAV4﹕ Thread[main,5,main]: Uncaught exceptions will be reported to Google Analytics. V/GAV4﹕ Thread[GAThread,5,main]: connecting to Analytics service V/GAV4﹕ Thread[main,5,main]: service connected, binder: android.os.BinderProxy@42175d30 V/GAV4﹕ Thread[main,5,main]: bound to service V/GAV4﹕ Thread[GAThread,5,main]: connect: bindService returned true for Intent { act=com.google.android.gms.analytics.service.START cmp=com.google.android.gms/.analytics.service.AnalyticsService (has extras) } V/GAV4﹕ Thread[main,5,main]: Connected to service I/GAV4﹕ Thread[GAThread,5,main]: No campaign data found. V/GAV4﹕ Thread[GAThread,5,main]: Initialized GA Thread V/GAV4﹕ Thread[GAThread,5,main]: Loaded clientId V/GAV4﹕ Thread[GAThread,5,main]: Loaded clientId V/GAV4﹕ Thread[GAThread,5,main]: putHit called V/GAV4﹕ Thread[GAThread,5,main]: Sending hit to service PATH: https: PARAMS: ul=en-us, ht=1408554996959, sr=720x1184, a=194292074, aid=<app package>, cid=9639b81c-b17a-4c3a-a43e-0c1f43a6d5c1, av=1.5.0.1, v=1, t=exception, an=<app name>, tid=UA-XXXXXXXX-X, exd=SQLiteBindOrColumnIndexOutOfRangeException (@MyApp:onCreate:185) {main}, _u=.nKhAAAL, exf=0 

I am currently using this code in my project (in the Application.onCreate () method), it works fine:

 GoogleAnalytics googleAnalytics = GoogleAnalytics.getInstance(this); applicationPreferences = new ApplicationPreferences(getApplicationContext()); tracker = googleAnalytics.newTracker(R.xml.tracker); tracker.enableExceptionReporting(true); String lastErrorString = applicationPreferences.getLastErrorString(); if (lastErrorString != null) { applicationPreferences.clearLastErrorString(); tracker.send(new HitBuilders.ExceptionBuilder().setDescription(lastErrorString).setFatal(true).build()); } final Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread thread, Throwable throwable) { applicationPreferences.setLastErrorString(Throwables.getStackTraceAsString(throwable)); defaultUncaughtExceptionHandler.uncaughtException(thread, throwable); } }); 

Note: Throwables is a class from guava

Option without Guava, but without a full stacktrace, only the original line number and method included in the report:

 GoogleAnalytics googleAnalytics = GoogleAnalytics.getInstance(this); applicationPreferences = new ApplicationPreferences(getApplicationContext()); tracker = googleAnalytics.newTracker(R.xml.tracker); tracker.enableExceptionReporting(true); String lastErrorString = applicationPreferences.getLastErrorString(); if (lastErrorString != null) { applicationPreferences.clearLastErrorString(); tracker.send(new HitBuilders.ExceptionBuilder().setDescription(lastErrorString).setFatal(true).build()); } final Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread thread, Throwable throwable) { applicationPreferences.setLastErrorString( new StandardExceptionParser(getApplicationContext(), null).getDescription(thread.getName(), throwable) ); defaultUncaughtExceptionHandler.uncaughtException(thread, throwable); } }); 
+1
source

Sorry for the offtopic, but with this problem I switched to using Crashlytics to collect errors, and it is more efficient than GA.

0
source

Source: https://habr.com/ru/post/1200543/


All Articles