We all love logging stuff in our Android apps to debug and keep track of the state our app is in. But what about in Production? How will you be able to find out what caused your app to be in a weird and unexpected state? Crash reporting libraries can help but up to some extent. It is very difficult to reproduce a bug just with the help of a crash report. Stacktrace won’t give you all the steps user took to generate that crash. The point is, having access to production logs can be of huge help when reproducing weird bugs or just for the study of user behavior. But how can we access logs from devices of our customers?
We have quite a few options that will help us attain our goal.
Hyperlog-Android — It is a library that helps you store logs in a local database and then you can push those logs to a remote server on a regular interval or set up a push notification trigger. Hyperlog has its pros and cons. On plus side, we don’t have to use third-party service to store logs for us. On the other hand, we will have to implement remote API endpoint to accept logs from devices and for that we need to have our own server. Also, we won’t be getting any real-time logs.
Papertrail — Its real-time, searchable and reactable(we can setup slack hooks) logs. It accepts connections via TCP and UDP. But how do we send logs from Android app to Papertrail app? If you look at official docs they’ll suggest you can use either logback-syslog4j or logback-android libraries and both of these libraries require you to add some configuration files in your app which is not much fun.
Papertrail-timber — You might already be familiar with Timber. But for those who don’t know what Timber is…
A logger with a small, extensible API which provides utility on top of Android’s normal Log class.
Papertrail-timber gives you an already configured Timber Tree that you can just plant in Timber and ready to go.
val tree = PapertrailTree.Builder()
.system("Android")
.program("Papertrail")
.logger("My-App")
.host(BuildConfig.PAPERTRAIL_HOST)
.port(BuildConfig.PAPERTRAIL_PORT)
// send logs to papertrail with priority Log.INFO and above
.priority(Log.INFO)
.build()
Timber.plant(tree)
Do’s and don’ts of logging
I would really like to share my experience about what to log and what to avoid but I think this topic deserves its own article. So keep an eye on future articles. :)
In short, avoid logging any confidential information such as passwords or credit card numbers etc. If you need to track user journey throughout your app then logging lifecycle methods would be of great help.
Another thing that you can do to see if you have enough information in your logs to make sense of things later on, is to try sending a release build with all the log setup done to your QA/Testing team and monitor the logs while they test the app. Analyse those logs and see for yourself if you can understand the steps they went through while testing.
Reiterate and Improve
Of course like everything in life, you won’t get it right on the first try. So keep doing to those iterations and improving your logging skills.
Thank you for taking your time to read this article. If you have any questions, suggestions on how to improve this articles, please feel free to contact me on twitter :)