Don’t like reading? Check out the site: https://touchtrack.co
We’ve been banging away on client apps for the last few months, and during that time slowing pulling together a testing framework that should significantly help app developers building complex client/server apps in the field. As those client apps wound down, we tossed a little paint on the front, did some private-invite iterations, and bam! Touch Track!
We’re in a public beta period. Sign up free. Check things out. Please give feedback. We will be cleaning up the web site and help docs over the next few weeks.
What is it? It is an issue and crash reporting platform for the Android O/S. It also provides remote version updates to test users, to facilitate and manage field beta testing.
The first question, of course. Why?
There are several products out there that provide crash reports for mobile applications. They all pretty much do the same thing. Stack traces. Don’t get me wrong. Stack traces are awesome! However, with stack traces you generally have no real context about what happened before the error. That context can prove extremely useful in helping to debug issues.
Most mobile developers are coming from a web development background, and I think we’re all a little too used to the assumptions you can make in that realm:
- The user probably won’t lose their connection
- The user probably has plenty of memory
- If a phone call comes in, it probably won’t shut down their browser
- Most, or all, processing happens on the server.
- You pretty much never deal with more than one thread (Ajax does not count, and if you don’t know why, you should learn)
With mobile apps, a whole lot of stuff happens far away from your server. A whole lot of bad things can happen while your app is running. Your resources are constrained, and for the Android world, the number of different devices is pretty much out of control.
Some bugs are obvious and easy to reproduce from stack trace info. Many bugs happen on one user’s device because they have some weird data or setup. Occasionally you’ll get a bug that only happens in some weird Thread collision situation. They all share some important properties.
- They don’t fix themselves.
- They’ll happen again
I guess some personal stories are in order. Clients shall not be named for obvious reasons.
Went to visit a client with our latest awesome build of their app. The president comes out. I’ve only talked to him once, and was pretty excited to show things off. He logs in. Boom! App crash. Tries again. Crash again. Sounds horrible, right! Worked out great. Since we had the crash report available, took a couple minutes to figure out they had a special account type of internal people only that we didn’t know about. Oops.
For another app, we got a report that “some users’ data gets mangled”. One user submitted an issue report, with screenshot. Not only did we see the issue they were talking about, but we got to look at what was going back and forth to the server, and point to an error in the server response.
Just FYI, there’s an absolute rule in all user app coding. The client side is always the broken part, until you prove otherwise. Especially as a consultant. You’re ALWAYS wrong, till you can demonstrate something else is going on (or you figure out that you are wrong, but then you know, which is good).
More info, demo videos, and sign up can be found on the website: https://touchtrack.co
Right now, free. We need feedback and thoughts from the community. Eventually? There will almost certainly be a free version for light users. This may not include some extra feature, and/or not keep data for more than a certain time period. Users who sign up in the near future can keep free accounts (unless they’re doing something EXTREMELY heavy. We’ll talk).
We have a special logging class that mimics the standard Android Log (mostly). You send your log statements to this class, and it will call the regular Log class, as well as add the log statements to our internal buffer.
Its a rolling buffer. Old entries are eventually removed. We cap the total memory size, as well as the total number of entries, to keep memory usage flat. You can tweak this as needed.
We have 2 special logging levels. User Activity, and System Info. User Activity is intended for use when the user does “something”. That can be opening a new Activity, clicking a button, selecting something in a spinner. Whatever. Logging these activities is very useful in helping you figure out what’s happening. You can log these activities to standard log levels, but we added ‘ua’. In the web application, we display these rows in a special highlight, which makes it easy to see and trace what the user is doing, interleaved with what’s happening behind the scenes.
We also added System Info. This is a special log level for memory and drive space logging. You can turn on periodic memory usage and/or drive space usage logging. This can be particularly useful for apps that push resource constraint boundaries. These rows are also shown with special highlighting so they’re easy to spot.
A special helper class called “UserActionLog” was added as well. It provides helper methods to call for different user actions, as well as custom View.OnClickListener (and similar) implementations. These will call the user action logs when the associated views are clicked.
The main interaction class is IssueReporter. This class allows you to add files that will be kept in a timed buffer. Files older than a minute or so are dropped (configurable). Size limits and disk usage protection mechanisms are also in place to make sure we don’t fill up the drive. Better to not have the files than actually CAUSE issues.
Adding files is really useful to help figure out what’s going on between client and server. Log XML, Json, Sqlite databases, whatever is useful. Be reasonable, of course. Huge I/O copies, and uploading lots of data, isn’t great. However, as long as you’re careful, this stuff can be critical.
Standard file formats will be displayed inline in the webapp report. you can see the log statements, then the associated data file, all in one place. See the following example:
Currently json, xml, txt, png, and jpegs can be displayed inline. Anything else, you’ll get a download link. Coming soon, we’ll (maybe) be adding the ability to navigate Sqlite databases right in the web app.
Default Exception Handler
Turn on the default exception handler to catch crashes. You can supply a callback to the default exception handler that will let you attach files and other interesting stuff at the time of the crash (don’t go crazy, though. Your app just died).
Instead of contacting the server immediately, we push the error report to a service to handle the upload. The service needs to run in a different process so the upload can happen while the main app is allowed to crash on its own.
(By the way, if there’s some mysterious issue reporting facility we’re not using, please let us know)
Add custom fields to your report. Just simple name/value pairs. Easy.
We look at the stack trace and try to group the same exceptions together, to avoid uploading unnecessary data. 300 reports about the same bug are pointless. We do count them when the come in, though.
Beta Testing Management
This part is still in flux, but the basics are sorted out. You can upload APK files to the server, and configure version settings to tell it how to operate on the user’s phone. Apps in testing can query for updates and prompt the user to install. Once you move to production, you can turn this off remotely. You can also disable the testing/tracking features once you’re in a fairly stable state (although user-initiated reports still get sent).
Soon to be added:
– Beta invite lists. Add emails of users to be sent invites to betas.
– Direct download/install link. Email your users on your own with this link, and they can install directly from their phone.
– Usage activity reporting.