I am developing an android app. My app gets crashed often. I want to save the logcat messages in sd card while the apps gets crashed to find the root cause. Is ther any way to do this?
A few ideas which might help you step toward fully automated crash log gathering. We have yet to roll a full system here, we've had enough luck with just grabbing devices after they've crashed or asking for more info from our QA group, but:
ACRA is relatively easy to implement, and even if you don't implement it, the source is on github for you to poke around in.
The related question Android crash reporting library (pre Froyo) has a number of links and solutions, including android-remote-stacktrace, the aforementioned ACRA, Android-Error-Reporter, and other commercial solutions.
Some devices capture the crash output automatically, you can grab it via adb pull /data/log/dumpstate_app_native.txt.gz or similar -- the paths should appear in logcat. These tend to be overwritten with each crash, though. (If anyone can answer whether this is a manufacturer-specific feature or something that appeared in some version of android's core, I'd love to know!)
You can get a logcat app, e.g. aLogCat or many others, that you can install on your device.
TestFlight is going into beta on Android side; they have crash reporting on the iOS side and should on the Android side too, and there are various other lovely benefits to using their services -- and integration is really easy in our experience.
If you're rolling your own inside your app, you need the READ_LOGS and WRITE_EXTERNAL_STORAGE manifest permissions (even for local builds), then you can use the logging API or a regular File.copy or even a system call off to logcat itself. There are a bunch of options and examples in the "Related" links to the side of this question:
Stream android logcat output to an sd card
How to redirect my log output from logcat to the SD-Card on an android device?
...and so on.
Hopefully this helped.
Reading your own logcat messages is covered by other questions.
how can i access logcat file on device
Read logcat programmatically within application
In order to do this when your app crashes you need to install an defaultUncaughtExceptionHandler.
Either on your activity on create or your application on create. Add the following code.
final Thread.UncaughtExceptionHandler oldUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable throwable) {
// DO your error handling here.
// Write your log cat, or write your exception stack trace here.
// Get rid of this line if you don't want a popup letting you know that your app has crashed.
oldUncaughtExceptionHandler.uncaughtException(thread,throwable);
}
});
Related
I am trying to diagnose an issue in an app I have written. The issue is a sporadic one, and occurs only under real-world conditions: in the field, away from my PC, and when I’m in the middle of something else, with no resources to spare for immediate debugging. Therefore, my best bet is collecting and analyzing log data.
Unfortunately, by the time I realize the issue has struck again and get around to debugging it, any log data has already rotated out of the Android log as I frequently have other chatty apps running at the same time. Increasing the size of the log buffer has not helped (either Android does not honor it or other apps are still too chatty) so I have abandoned this route.
For this reason, I am now considering having my app log to a separate text file in addition to the regular log.
Now I could easily double every call like
Log.i(TAG, "something happened");
adding another call that writes the same thing to the log file—but that does not seem very elegant to me.
Another option would be to replace all calls to Log with a wrapper that writes the event both to the Android log and the log file.
Question: Does the Android API provide a built-in mechanism for this, i.e. telling Log to write its data to the default log and a text file at the same time? Or do I need to code this by myself?
Edit:
Assumptions:
I know where in my code I need to generate log output (which can happen anywhere, which may or may not involve an exception) and what I want to be written to the log.
Getting log data from the device to my PC is also not a concern (one-man show, I just plug my phone into my PC and transfer the log file).
If you know the current Android API has no built-in mechanism to achieve what I want, then ”no, Android does not support this” is a perfectly acceptable answer. In that case the solution is clear—I would fall back to the wrapper function. I am specifically not looking for a different approach to the problem.
After doing some more research, it seems the Android API does not provide a standard way to do this. There are two possible workarounds:
Mirror output at the source
System.out and System.err output, which is written to the console in desktop systems, writes to the log on Android. These two can be redirected into any PrintStream of your choice, which would give you all Java console output. You can subclass PrintStream to duplicate its input, feeding it into the default stream as well as into a file of your choice.
Create a class which exposes the same methods as android.util.Log. In each method, call through to the respective android.util.Log method and additionally log the data to a file. If you call your class Log (but with a different package name, e.g. org.example.Log), then all you need to do is replace imports of android.util.Log with an import of your class, and any Log method calls will go to your class.
Caveats: This will only give you data explicitly logged by your code (i.e. for which you have the source files), as well as anything that goes to System.out or System.err. It will not include log output from JAR libraries (if you cannot modify their source code), nor any output generated by the system (such as stack traces from default exception handlers) or by other processes (some of which may be system processes and report conditions related to your process).
Read the logs from the command line
This article explains how to read the logs from within Android. In a nutshell:
Android includes a command line utility called logcat on the device, which will give you a continuous feed of log messages until stopped. (Try it by adb shelling into your device and running it. It has a bunch of command-line options to control its behavior. Not sure if it is present on all distributions, though.)
Launch this command via Runtime.getRuntime().exec("logcat"), then obtain the input stream of the process returned. This will give you an input stream of log messages.
According to the article, your app needs the android.permission.READ_LOGS permission to read logs.
I have read statements that certain versions of Android (4.2 was mentioned) do not allow this permission to be granted to non-system apps, though. According to my own tests, behavior without this permissions differ: Anbox will return the full logcat, while LineageOS (tested on 15.1) will only show log entries from the app which called it (including previous instances, presumably everything associated with the same Linux user). This can be a limitation or a welcome filter feature. YMMV.
logcat conveniently has a command line option, -f, to specify an output file. I tried
Runtime.getRuntime().exec("logcat -f " + absolutePathToLogFile);
and logcat keeps logging as long as the app’s process runs. Killing the app (by clicking the X in the title bar on Anbox) apparently also terminated the child process.
Now you can either run this code when your app starts up, or you can turn this functionality into a separate app which starts on boot and continuously collects logs for all apps.
Caveats: This may fill up your storage space quickly if you have some chatty apps running (which is why entries rotate out of the logcat so quickly in the first place). It is recommended to make log mirroring configurable (e.g. via Preferences) and/or ensure old files are deleted regularly. Also, if you keep the logcat process running until your app terminates, you will not be able to access the file over MTP as there is no easy way to run the media scanner (if you scan the file while it is still written to, it will appear truncated over MTP until another media scan runs).
You have not specified if some exception are thrown but you don't handle.
In case, take a look at this answer:
Android Handling Unhandled Exception
If you must look at a bunch of variables and objects, I'd suggest two choices:
Write a copy of your logs on a file. When your problem occurs, just ask the user to send the file to you. This is ideal during tests with self-aware users.
Obtain statistics about usage, like commercial software do. Just log user operations and send the data to your server (you would need one for this). This is the most transparent way to do remote logging.
In the case of writing log to a file, you can read and write what you want in internal memory (inside the app's sandbox) or external memory (in this case, write permission is required and explicit permission must have been granted at runtime if you are targeting Android 6 and above).
In my limited experience on a handful of Android devices, if an app crashes with an unhandled exception then that exception's written to the log. However I've come across a Samsung i8160 that doesn't. Other i8160s with various ROMs do. In fact, from boot, it doesn't log anything. It originated on eBay so the history is unclear, but rather than assuming it's an odd ROM and flashing something else I figured it was worth persisting in case the problem arises again elsewhere.
In researching, the first thing to try was to 'dial' *#*#2846579#*#* but this isn't recognised- it just tries to really dial that. There's a shorter *#9900# that does pop up a menu, but that only lets me dump the log and other info to files in /data/log for export. Since logging isn't up from boot, that doesn't export much.
Initially, /dev/log doesn't exist. One suggestion to fix this was to try logcat-enable from a shell. This isn't found. Another suggestion was to manually load the logging module by running insmod /lib/modules/logger.ko from a rooted shell. This brings logging up, but when an app crashes, all logcat outputs is
I/dumpstate( 8074): begin
I/dumpstate( 8074): done
I've found the dumpstate files, which include the logcat output, but there also it just notes creation of the dumps, not the exception that caused it.
As well as starting the module, I'm assuming somewhere there's some configuration determining what actions to take when an app crashes, and here it's not set to dump the exception and stack trace to the log because whoever did it figured logging wouldn't be running anyway. But I can't find anything like this. Does anyone have any ideas on how to progress further?
Some apps have a "report" function inbuilt in case their app crashes. When you choose report on the ANR message, usually a log is created for sending it to the developer. Maybe you can get an app to crash and catch that log (or maybe make your own one)
When testing on a device in Android Studio you get an awful lot of output in the logcat.
I'm only interested in the output for the app I'm developing. I can see just this, after running, by opening the Devices section and manually selecting my apps process. Problem is, it's pretty tedious to do this every time I run my app, which seems to be the case.
Is there a way to get it to remember this setup?
How about a way to get it to stop reporting anything after I'm done with my app or it's crashed ? (otherwise my app specific stuff gets buried so quickly by output from other proccesses on my phone)
I'm open to other ways of filtering the logcat too, however I couldn't think of a way to set up filters so that I would get my tagged Log messages AND other exceptions I wasn't expecting.
Any suggestions?
Normally this is done by default, but if not,
in logcat, the green plus sign, when you click it you get a dialog, fill the byApplicationName with your package name, and also your filter name with something, now you can filter your output according to your app
with that beeing said, sometimes you don't get the filter column info (application name) in logcat at all (blank), here (and I my self don't know the cause of it) just forget it for a while and retry again
I am using HTC One X.
There are some system application that has too many logs.
Because of that, I am able to see my application log only for some seconds. After some time, my logs are being remove from buffer since too many new logs from other application.
Can i disable log by using the tag.
Firstly, you cannot stop other applications from logging! Probably some apps more than others log too extensively causing an overflow. What you could try to do is
Force stop some apps so that thier logging activity is reduced(less chance it might reduce).
Secondly, as Rasel suggets,
Use DDMS features like filtering logs using application name, package name, TAG's etc. and pause logging.
In this way you will get a snapshot of your logs. Hope this helps!
Can you help me understand how I should debug this errors? What information would you get from this stack trace that might help you understand what is wrong with this code?
I assume andy_lockscreen is not my concern as it doesn't have anything to do with my app.
However what is the meaning of the errors with tag TiApplication and TiHttpClient?
How can I filter to see only errors and traces regarding my app?
I am developing android application using titanium
Thank you,
Ryan
UnkonwnHost means whatever is trying to connect to something online is unable to connect. Either the online content is down (unlikely given that it is google maps) or the device doesn't have a suffecient internet connection, or something else is blocking the connection (iptables perhaps, DroidWall will cause this type of error if you havn't white listed the application attempting to connect)
You can make a filter by clicking the Green "+" that is in the pane just off to the left of the screenshot you provided. Type in the Tag that you are using when you make Log statements within your app. That will narrow down the list to only Logs coming from your application.