Xamarin Insights: Effective Events

Xamarin Insights is a mobile crash reporting & analytics service that's perfect for C# applications, both for Xamarin and .NET. I think it's amazing because its features make it invaluable for making sure your users are getting the best experience when using your software (and I'm not only saying that because I lead development on it πŸ˜€).

A large part of this is the in-built crash reporting, which automatically captures and sends both native (iOS/Android) and managed (C#) crashes to the service for easy viewing. This allows you, as the developer, to quickly see what issues your users are facing with a new or existing release. It gives you a chance to fix these issues and roll out a new release before a bad experience becomes a bad review!

However, in addition to allowing you to see how well (or bad) your app is doing with regards to crashes, another huge feature in Insights for building a superb experience for your users is Events.

Events give you the power to get an insight into the behaviour of your users and your app at a wider scale. With events, you can track the occurrence of any action in your app, how long it took, and what properties were associated with it.

Events can be very simple or unbelievably powerful. The rest of this post explores the events feature, explaining how best to use them, some common pitfalls, and how they can be used to gain useful insight into your app.

Anatomy of an Event

I think the easiest way to explain an event is to imagine what it looks like when the app is sending it to the Insight service:

{
  "timestamp": 1454273651260,
  "name": "Play Song",
  "duration": 2342,                                    // Optional
  "properties": {                                      // Optional
     "Artist": "Perturbator",
     "Album": "Dangerous Days",
     "Song": "Hard Wired (feat. Isabella Goloversic)"
  }
}

As you can see, an event is very simple. While this simplicity on the surface hides some powerful features, the goal was always to allow developers to very easily add support for events in any part of their app, keeping the API clean and concise.

Both duration and properties are optional, so at it's very basic, and event just needs a name and the timestamp of when it occurred.

Measuring Occurrence

Tracking an event in Insights produces two automatic side-effects:

  1. The event is logged with the user, available to view via the users or issues page for any session.
  2. The event name is logged with the time and date, and used for counting it's occurrence across all users. These results are displayed on the Events page in the Insights Dashboard.

To track an event and have it's occurrence counted, you simple call the Track method:

public void PlaySong(SongDetails details) {
    // actually play the song above
    Insights.Track("Play Song");
}

Once you navigate to the Events page on the Dashboard, you'll be able to see your `Play Song` event in the list, and selecting it will give you a chart tracking hourly or daily occurrence:

Xamarin Insights Event Count Chart

The Events page allows you to see trends across the last 24hrs, 7days, or 30 days

Choosing an Event Name

Choosing a good event name is one of the most important things to do to get the most out of Insights. A good event name is one that has a low cardinality, is descriptive of a single action or task, and is concise. For example:

πŸ‘ "Play Song"
πŸ‘ "Refresh Item List"
πŸ‘ "Add To Cart"

A bad event name is the opposite of the above guidelines. The most common mistake by developers is to put data that is perfect for an event property, into the event name itself:

❌ "Play Song: Michael Jackson"
❌ "Refresh Item List: 524ms"
❌ "Login: jellybeans@goodfud.com"

All the above bad examples are very unique and, in that, you lose the value of events completely. The extra data contained in the event name should be instead be transformed into duration or added as properties to the event.

Measuring Durations

For certain types of events, it's very useful to also measure duration. Some examples are:

  • How long did it take a user to complete a level?
  • How long did an REST API call take?
  • How long is the video that the user is playing?

Individually these questions are interesting, but when the data they produce is combined across all your users, you now have the average duration it's taking people to complete a level, the average time a call to your backend is taking, or whether your app's users like to mostly play short, medium, or long videos.

Plotted across time, you can quickly spot trends between day or night, weekdays or weekends, and track differences between deployments of API servers.

Tracking the time taken for an event is easy using the IDisposable API:

public SongCover DownloadCover(SongDetails details) {
    SongCover cover = defaultCover;
    using (var handle = Insights.TrackTime("DownloadCover")) {
        // The time taken in this block is automatically counted
        try {
            cover = await ApiServer.DownloadCover(details.id);
        } catch (Exception e) {
            Logger.Warning(e);
        }
    }
    return cover;
}

Alternatively, to have more control over the starting and stopping of the timer, you can do the following:
public SongCover DownloadCover(SongDetails details) {
    var handle = Insights.TrackTime("DownloadCover");
    handle.Start();

    SongCover cover = defaultCover;
    try {
        cover = await ApiServer.DownloadCover(details.id);
        handle.Stop(); // Only time successful calls
    } catch (Exception e) {
        Logger.Warning(e);
    }
    return cover;
}

By using the `TrackTime` API, the Insights service will automatically give you the benefits of the simpler `Track` API (i.e occurrence counts), but will also now show you an average duration chart:

Xamarin Insights Event Mean Duration Chart

The TrackTime API measures time in milliseconds

Adding Properties

As events are usually a consequence of an action, they almost always have some associated metadata. For example, if you're tracking every time a song is played in your app, the metadata would be details about the song played. If you're tracking adding items to a shopping cart, you could produce an "Item Added To Cart" event for each item, with the item's details as metadata.

Both the Insights.Track and Insights.TrackTime APIs allow you to attach this metadata to an event via a dictionary of data (type Dictionary<string, string>):

{
    Insights.Track("Song Played", new Dictionary <string,string>{
        {"Artist", details.Name},
        {"Album", details.Album},
        {"Title", details.Title},
        {"Genre", details.Genre}
    });

    // OR
    Insights.TrackTime("Download Cover", new Dictionary <string,string>{
        {"Cover Id", details.CoverId},
        {"Backend Store", details.StoreId}
    });
}

Once the Xamarin Insight service receives these properties, it makes them available in two key ways:

User Event Streams

When viewing a particular user's sessions or a crash they experienced, events with properties give an insight into what they were doing in your application:

Xamarin Insights User Event Stream

Events are presented with their properties in the order they occurred

Application Event Statistics

On the Events page, below the occurrence and duration charts, events with properties will get a special table view that shows the most popular values of each property, and their statistics:

Xamarin Insights Event Properties Chart

Values of each property of an event are grouped together and statistics generated across them all

Conclusion

As you can see, Xamarin Insights provides some valuable features on top of the crash-reporting, and events especially can be a simple way to start extracting more data from your app and how it's used.

Over the coming months, the Insights Dashboard will get many more features around the the Events page, so be sure to keep a look out for those! If you have features you'd like to see or any questions regarding events, let us know and the team and I will be happy to help!