Automatic error reports / phoning home

As usual, when I put a game out on the showcase theres always a few fatal crash bugs, where the description tends to be “it crashed”, or if someone is feeling helpful, a stacktrace. Usually fixing these requires asking for a complete log of the console out, or adding extra diagnostic code and getting someone to rerun it and post the results.

I’d like to make the whole process faster/easier, so problems can be found and nailed quicker. Practically that means getting the complete console/log messages and any exception traces back without having to ask the user. (Previous attempts when I’ve specifically generated a log file, while helpful, usually mean that no-one actually bothers to include it unless requested multiple times).

So the problem seems to break down into:

  1. Actually returning the log/error report.
    Obvious answer is emailing it to an address specifically for this purpose. However the only library to do this is the JavaMail API, which IIRC needs to be manually installed on the users pc before use. Not really practical.
    Alternatively they could be ftp-ed onto a server using an ftp user specifically for this (IIRC I should be able to allow the user no read access and write-only access to the specific sub dir). I’m currently looking into FtpBean ( http://www.geocities.com/SiliconValley/Code/9129/javabean/ftpbean/ ) for this, which is nice and tiny and pure java, so can be bundled with the app easily.

  2. What to tell the user about the error reports.
    I know some people don’t like apps ‘phoning home’ without telling them, and can in some cases get your app labled as spyware. However most errors happen on display creation, so I don’t get a chance to tell the user that it might send an error log. How should this be handled? Maybe just a bit of text on the webpage where you download the app would be good enough, but frankly most people don’t read those and they’re going to be surprised when their firewall starts detecting connections.

  3. Identifying the user who filed the report.
    If someone gets a crash, and then posts a message like “it didn’t work”, it would be nice to figure out which log corrresponds to that person. However, I don’t want to include the username they’re logged in with (or similar), as then I’d be sending non-anon info in the error report. Maybe timestamps would be good enough on their own? I could ask the user to type in a username/id/something, but again most crashes happen before display init, so that could be tricky.

Opinions?

You get away with a lot, if your game is still in beta (superb example: Google).

If you don’t want the firewall nagging, use Sys.openURL(String) in LWJGL and pass
the exception (or entire log?) as an HTTP GET argument, with some wicked character-
conversion so that nobody knows what just has been sent, and then your PHP script
(or whatever) does the storing in a fancy MySQL database, while the page redirects
the user to the Support page.

  1. Actually returning the log/error report.
    Like Riven suggested. I used this too for logging errors, posting error logs to a php script… works great, it’s simple and effective (having no firewall issues neither).

  2. What to tell the user about the error reports.
    Well my games are webbased, so if the error happens on display creation I communicate with javascript to popup an error window. Maybe you can do something similar with standard Java functionality that doesnt rely on ogl or anything; if an error occurs fall through and popup a jframe or whatever, with a message that something went wrong. You could even embed an question in this jframe whether they’d like to help you out by clicking ok and aut. sending you the stacktrace…

  3. Identifying the user who filed the report.
    Don’t know how much of an issue it would be to send username/error log (as long as the error log only contains technical details related to the bug). Anyways you could always ask this in your error popup, kinda like microsoft does with program crashes in XP.

Standard approach with three is to generate a “unique personalised code” and display to the user, i.e. generate a random number * Integer.MAX_VALUE and ask them to “quote it in all correspondence”.

this assumes you can at least get SOME message to them - even if only the last line of a console output (although in that case, highly highly recommended to precede with 25 blank lines and 5 lines of equals signs so that it shows up as “a message” ;))

I was just looking up the JDIC project after clilian & SonOfCain were talking about it and found an interesting API that can send an email from the user’s default mail program. Check out the API docs:

https://jdic.dev.java.net/nonav/documentation/javadoc/jdic/org/jdesktop/jdic/desktop/Desktop.html

or the general JDIC site: https://jdic.dev.java.net/

I haven’t used it, but it looks like the method you could use to email any exceptions to your email address would be:

Message message = new Message();
message.setBody(exception.getMessage());
ArrayList list = new ArrayList(1);
list.add(“game_bug_email@google.com”);
message.setToAddress(list);
Desktop.mail(message);

Seems a lot easier than other options (in theory).

Keith

Problem with that is it doesn’t “send” for you. It simply populates the data in the default mail client in a “compose mail” screen, but they have to click “Send”. So you’d be showing them exactly what is being sent which can be a good or bad thing.

I have a project http://jcommon.dev.java.net that has a JException class that will graphically display an exception and you can e-mail the ability to click “Send E-Mail” that will e-mail the contents of the exception and several other details to a provided address. Also, the JCommon API has a lot of convenience features for sending e-mail. If that’s too proprietary for you, you could use the JavaMail API. However, if you’re using e-mail you’ll likely run into the problem mentioned above about firewalls. Best way to send data without worrying about it is via a URL. Simply using the HttpURLConnection and send everything in the POST data. What riven suggests is bad because GET has a size limitation on it and there are a lot of crazy character conversion things you’ve got to worry about.

well… bad… bad… and the character-conversion is a joke, just convert it to hexadecimal and put a % in front of it (and vice versa).

I think the size-limitation is not that important for a few exceptions. Using POST is slightly better, but GET isn’t that bad.

GET can be very bad if you’re dealing with something variable such as a stack trace that could be five lines or five thousand lines. Not trying to be argumentative though. We agree that POST is better so lets just get along. :wink:

Ahh that sucks. I’ve been trying to get JDIC working to see what would happen but its a pain to build. They are asking me to un-jar, rejar, sign & webstart 3 different files!

I suppose I could get java.awt.Robot tto click ‘send’!

Cool, I’ll check out both. I’ve already looked into JavaMail API and it can’t be used easily, it needs to be manually installed. I know nothing about how to recieve ‘post’ or ‘get’ data so I’ll have to check out your JException class.

Thanks,
Keith

For the one with JCommon it is extremely easy:

SMTPClientSession session = new SMTPClientSession("somewhere.com", 25);
SMTPClientSession.sendMessage(session, "from address", "to address", "message");

sendMessage will return a boolean value if it was successfully sent.

There are many more complex features if you choose to use them though. Take a look at the API for further information.

Wouldn’t that require an open SMTP relay or embedded your credential in the code?

Kev

It requires an SMTP server running on somehere.com that accepts mail for “to address”. I imagine that you could substitue these values for your ISP’s smtp server for the email address you are using. What would be even nicer of course, this being an SMTP client and all, is that you dns lookup the MX records for the server you are trying to talk too, and talk to those, then you don’t have to specify an SMTP server at all. As long as “from address” is valid, any bounces will work anyway.

Endolf

Ah I see, learn something new every day. Isn’t that bleady awful :slight_smile:

Kev

Actually, that would be a relatively easy feature to add. That class was actually used on my e-mail server I wrote a while back, but at that point it had already done and MX record lookup for the destination and that was specifically passed to it. I decided to break it up like that because I expected most uses of this class to be for company-specific applications on an intranet that could be passed the internal mail server address to send messages to.

If you’re really interested in using the API I would be happy to add the functionality, but if you’re just trashing the class without any intent to use it I’ll leave it as-is. :wink:

@kevglass, so you hang out around here but you don’t come back to the jME forums? There are some issues with the CloneImportExport class and I keep appealing to you for help but they seem to fall on deaf ears. :wink:

Oh there are, be right over.

EDIT: Isn’t that bleady awful wasn’t aimed at your code but at myself. I’d actually just remarked to Endolf on IM (after he gave me a full explanation) how much I liked the mail in idea.

EDIT2: Incidently you cheeky little frog (for want of a better word), where did anyone appeal to me? No PM, no mail - just because you incorrectly thought I was having a go at your code (which I wasn’t) no need to start trying to imply crap.

Kev

[quote]cheeky little frog
[/quote]
hehe, I’m considering changing my nickname to that. :slight_smile:

Wasn’t trying to imply anything, no need to be offended I was just joking with you. As far as appeals I responded in the message you looked at linking to the proper message in the forum. I got no beef with you, I was just giving a hard time for disapearing…sorry, I expect people know by now that the majority of my posts have a certain amount of comedic implications and without that understanding I can appear a jerk. You can pretty much assume I’m joking about practically anything I say. :wink:

…I do really like “cheeky little frog” though…that’s better than “jME Whipping Boy”. :o

Sunsett, I like the sound of your JCommons API! I’ve been looking for such an easy way to send email (spammer that I am ;)). I’ve got a shedload of things to do but I’m going to give it a spin by monday.

Cheers,
Keith

CommanderKeith,

Let me know what you think. It’s my personal repository of classes I’ve designed over the years that have been useful and generic enough to share between projects but not large enough (or important enough) to warrant their own project.

BTW, my other nick is darkfrog (if “cheeky little frog” wasn’t a good tip-off). :stuck_out_tongue: