I have a BaseActivity that I use as a parent for all my Activities. I'd like to log Activity events (onCreate(), onStart(), onResume(), etc.) to Crashlytics, so when a crash happens, I know what the user was doing and what Activities were currently alive. I added the following code to all the methods that I want to log:
CrashlyticsCore.getInstance().log(getClass().getSimpleName() + ".onResume()");
I'm wondering if it's a good idea to do it. Are the logs only sent when a crash happens? Will I not spam the server and produce unnecessary network calls for the users? Perhaps there's a better method of implementing bread crumbs with Crashlytics?
As the name subtly suggests, Crashlytics will only trigger a report (and send a log) after a crash, and will only contain up to 64kb of log history as stated in the docs: "To make sure that sending crash reports has the smallest impact on your user’s devices, Crashlytics logs have a maximum size of 64 KB. When a log exceeds 64 KB, the earliest logged values will be dropped in order to maintain this threshold."
If you ask my personal opinion, it's not good practice or useful to log every onCreate, onResume. A Crashlytics report will already contain the stacktrace giving you insight on the error.
If you have caught exceptions and want to log those, you can do so as explain here, by calling Crashlytics.logException(e);. Again only 8 of these will be stored: "For any individual app session, only the most recent 8 logged exceptions are stored".
Related
I'm trying to debug an application on a Galaxy S7, and it's almost impossible to get a useful log because the device spams the same log call hundreds of thousands of times in a few seconds:
07-31 10:49:33.962: D/NetworkStatsCollection(3838): getHistory:mUID 10158 isVideoCallUID: false
This pushes the useful log calls out of the log stack before I can read them or even copy and paste them.
I've used filters for years on my previous Android devices to only see the calls that are relevant to me, but the problem is that this only seems to control what is shown in Monitor rather than limiting is actually being processed as a log call.
Is it possible to completely block certain calls?
Use logcat --prune command to set up white and black lists of processes.
From https://developer.android.com/studio/command-line/logcat.html :
You provide a mixed content of <white> and ~<black> list entries, where or can be a UID, UID/PID or /PID. With guidance from the logcat statistics (logcat -S), one can consider adjustments to the white and black lists for purposes such as:
Give the highest longevity to specific logging content through UID selections.
Blacklist who (UID) or what (PID) is consuming these resources to help increase the logspan so you can have more visibility into the problems you are diagnosing.
By default the logging system automatically blacklists the worst offender in the log statistics dynamically to make space for new log messages. Once it has exhausted the heuristics, the system prunes the oldest entries to make space for the new messages.
Adding a whitelist protects your Android Identification number (AID), which becomes the processes' AID and GID from being declared an offender, and adding a blacklist helps free up space before the worst offenders are considered. You can choose how active the pruning is, and you can turn pruning off so it only removes content from the oldest entries in each log buffer.
Did you try next setting for the logcat?
I'm building an app that sometimes crashes, I want to know that it crashed in the next time I opened it so I can suggest to the user some post-crash options.
How can I detect the crash?
Also I want to be able to save the user's work before it crashes, I means real time detection of crash, can I do it without knowing where it crashed?
You will need to know where it crashed in order to set the try/catch blocks in the right place to, er, catch the crash and save the data or whatever you have in mind.
This is known as "graceful" termination if you want to consider it in more detail.
Unfortunately neither Java destructor/finalize methods nor lifecycle methods such as onDestroy are anywhere near as robust as try/catch blocks so I'm afraid that is your only option, and how many of us deal with exception prevention. No-one would wittingly provide a user experience that crashes, much less with loss of their data.
Take a took at the ACRA library. You can configure it so whenever a crash happens you can control it and even send the crash log by email
You can use try/catch blocks, then send details on the Exception in your catch.
There are implement UncaughtExceptionHandler as mentioned in these answers and write crash report in some file or use it another way.
ACRA is already mentioned.
However for paid version, I found BugSnag is very good at this.
Or if you want to take the extra mile, try AppSee.
AppSee even has video recording session of how the crash happens. It is from tapping that button on the second list, the menu button or even when the user slides left in your viewpager.
Android supports various log levels, Verbose, Debug, Info, Warn and Error. I understand how the logging levels work; I'm more interested in the typical output expected for a given level.
For example, when developing an application I might be curious when a certain method is doing something (this often tends to be for debugging purposes). I'll look through the logs to make sure the methods are being called in an expected order, if the network response is what I think it should be, if the parsers finds the right information, etc.
Why would some one use Verbose vs Debug vs Info?
From the perspective of a developer, for a first, second, or third party application aren't all logs for debugging purposes? (assuming devs don't stare a logs for fun... I'm not that sadistic)
From the perspective of a consumer, when the s*** hits the fan and they need to contact customer support because their super important / business critical application isn't working a developer uses the log for debugging purposes.
The only reason I could see for using verbose or info is perhaps metrics gathering / data warehouse related operations. If so, why use verbose vs info.
Not sure If I'm overcomplicating this or if the android framework is...
I basically follow what Tomasz Nurkiewicz has to say when considering logging level:
ERROR – something terribly wrong had happened, that must be investigated immediately. No system can tolerate items logged on this level. Example: NPE, database unavailable, mission critical use case cannot be continued.
WARN – the process might be continued, but take extra caution. Example: “Application running in development mode” or “Administration console is not secured with a password”. The application can tolerate warning messages, but they should always be justified and examined.
INFO – Important business process has finished. In ideal world, administrator or advanced user should be able to understand INFO messages and quickly find out what the application is doing. For example if an application is all about booking airplane tickets, there should be only one INFO statement per each ticket saying “[Who] booked ticket from [Where] to [Where]“. Other definition of INFO message: each action that changes the state of the application significantly (database update, external system request).
DEBUG – Developers stuff.
VERBOSE – Very detailed information, intended only for development. You might keep trace messages for a short period of time after deployment on production environment, but treat these log statements as temporary, that should or might be turned-off eventually. The distinction between DEBUG and VERBOSE is the most difficult, but if you put logging statement and remove it after the feature has been developed and tested, it should probably be on VERBOSE level.
My most favorite level is WTF(2.2+) which is supposed to stand for "What a Terrible Failure", for situations that should never happen.
I normally use "info" for simple messages.
I'm working on an app that is recording data via Bluetooth, but it intermittently crashes after hours of collecting data (making it hard to track down the bug).
The logcat output isn't very helpful:
http://i.imgur.com/EalnX.png
There are no exceptions thrown and no clues for what caused the process to be terminated.
How can I figure out what went wrong? Is there an exception being thrown that isn't being shown by logcat? How can I track this bug down?
Signal 9 is SIGKILL, which will terminate a process immediately (no handlers inside the process will run). From the log line, the process is killing itself, so its not an external agent that is issuing the SIGKILL.
My guess (and its really a guess) is that the memory management code running inside your process (as part of the infrastructure, not code that you wrote) is deciding that you've exhausted some resource and the only recourse is to die. I would expect there to be more messages before this point is reached in the log, so it may be worth browsing the log history to see if there are useful warnings from the process before this point.
The line immediately before this is a GC log, which implies that some sort of memory resource is running low. But it looks like the heaps are not full, so failing allocations seems unlikely. You can still get allocation failures if the object being allocated was too large to fit on the heap, or fragmentation prevented it from being allocated. I'd expect to see more relevant log messages in this case, though.
I think capturing more of the log (perhaps filtering it by your app's PID if necessary) will help you make progress.
In my case there was no warnings or any clues in the log.
Eventually I found that my problem was that one of the activities I was going into (lets say Activity X) was registering to a broadcast receiver but never unregistered from it.
Therefor by closing the activity (Activity X) and coming back to it caused registering Again to the same broadcast receiver - which caused the mess!
Simply adding unregisterReceiver(mybroadcast); (in Activity X) solved it.
(I added mine to onDestroy. make sure you unregister in the right location).
And if you are super desperate I recommend seeing this slide share which explains Android crash debugging your errors.
this problem happens when using RXjava and not implement the onError callback method
I've released my second game project on the Android Market this week, and immediately had multiple 1-star reports due to force closes. I tested it on many handsets and many emulators with zero issues. I'm completely at a loss for how to proceed and looking for advice.
I use Thread.setDefaultUncaughtExceptionHandler to intercept and report uncaught exceptions, then close gracefully. The people reporting force closes aren't getting to any of that, even though it is the first thing set in the application's main task constructor, and everything is wrapped in try/catches throughout. They are also reporting that there is no "Send Report" option in the force close popup (providing the Developer Console error reports), so I have absolutely no way of knowing what the problem is.
Uses Android 2.0, with android:minSdkVersion="5". Only Permission required is INTERNET.
(on Android market as 'Fortunes of War FREE' if you want to test)
I'm a bit surprised about the missing "Send report" button. What API level did you build the game with? I usually build the level with your minimum API level to make sure you're not using any API calls beyond that, but then switch back to the highest API level so you can use functionality like "install to SD".
I'm sure there's at least one user who wrote you a mail. Can you ask them to install LogCollector and mail you the log?
Btw, in general, I wouldn't use Thread.setDefaultUncaughtExceptionHandler so there IS the option to send a report. (It's ominously missing in your case, but normally, it should be there.)
Btw btw, the exception handler applies to the current thread. If you have an OpenGL app, maybe the crash happens in the GL thread?
I'm not sure if I understood you correctly, but as far as I know Android only shows that report dialog if you use its default UncaughtExceptionHandler.
Try this:
In your UncaughtExceptionHander's constructor, call Thread.getDefaultUncaughtExceptionHandler and save the returned object in a variable (let's call it defaultHandler). In your Handler's uncaughtException() do the things you want to do, and then call defaultHandler.uncaughtException() afterwards.
Maybe something you should know:
In my experience, your Context isn't functional anymore at uncaughtException(). So, you can't send broadcasts, etc anymore.
By the way, if you really wrapped everything in try/catch, that could be the reason why error reporting doesn't work as expected? :P
Good luck
Tom
Perhaps the force closes are caused by stalls, rather than exceptions. Users may not notice the difference. This kind of problem can occur more often if users have CPU hogging services running at the same time as your application, which explains why you're not seeing the issue in your testing.
Permission Internet sounds a lot like you try to transfer data from the net, which is very fast in your local LAN, but all of a sudden becomes slow (and time consuming) when people try this over their GSM connections.
If you then do the data transfer in the UI thread, this one is blocked and the system detects the block - but then this should end up in a "Did not respond" -- but then I've seen one user report an error with in the market on my app that was such a slow down cause.