Forum Xamarin.Forms

how to get context as attachment for crashes into appcenter?

batmacibatmaci DEMember ✭✭✭✭✭

there is this nice article regarding how to log better as attachment on crashes. But i dont understand, if he is using wrong wording in the article. According to the Appcenter design, Crash is "uncaught /unhandled exception" exists the app. How is it possible to implement this code piece in the article for crashes? According to my knowledge till today we arent able to catch unhandled exceptions. So where to place this code?

https://devblogs.microsoft.com/appcenter/give-your-crashes-a-context-through-logs-attachments/

Crashes.GetErrorAttachments = report =>
{
var compressedLogs = LoggerFactory.GetCompressedLogs();
return new[] { ErrorAttachmentLog.AttachmentWithBinary(compressedLogs.ToArray(), “logs.zip”, “application/x-zip-compressed”), };
};

public static MemoryStream GetCompressedLogs()
{
Stream compressedLogs = null;
Task.Run(async () => compressedLogs = await _logManager.GetCompressedLogs()).Wait();
return (MemoryStream)compressedLogs;
}

Answers

  • batmacibatmaci DEMember ✭✭✭✭✭

    ok, just found. it was documented here. it is quite interesting advanced usage actually. I dont why i didnt see it till today. @JohnHardman are you using this? any experience? i know that you are quite active crash handling :)

    https://docs.microsoft.com/en-us/appcenter/sdk/crashes/xamarin#add-attachments-to-a-crash-report

  • JohnHardmanJohnHardman GBUniversity admin

    @batmaci said:
    @JohnHardman are you using this? any experience? i know that you are quite active crash handling :)

    I haven't migrated to AppCenter yet. As I implement comprehensive exception handling, I expect to be using Crashes.TrackError in my exception handling code, probably passing a Dictionary as an argument, with the Dictionary containing my additional info. I'll implement the stuff for unhandled exceptions too, but it's very rare for an unhandled exception to bubble up out of my code, even during development. Despite preferring the Dictionary option, I wouldn't rule out using the option to zip up something larger and send that, but I suspect I wouldn't do so often.

  • LuiCLuiC USMember ✭✭

    Adding properties to an error event is easy, but the limited number of values you can add and the very limited length of text that each property can hold mean that they're only suitable for short, simple values.
    Using attachments will allow you to pass a lot more data which might be necessary to understand what is going wrong.

    I've not yet started using attachments but I've hit limitations on the data length... so might consider attachments in some specific cases.

  • JohnHardmanJohnHardman GBUniversity admin

    @LuiC said:
    Adding properties to an error event is easy, but the limited number of values you can add and the very limited length of text that each property can hold mean that they're only suitable for short, simple values.
    Using attachments will allow you to pass a lot more data which might be necessary to understand what is going wrong.

    I've not yet started using attachments but I've hit limitations on the data length... so might consider attachments in some specific cases.

    Exactly, but it would be unusual to need to send much information on top of what TrackError would already provide. My own exception handling code includes the ability to capture all sorts of application and environment state, but in the 4 or 5 years since I implemented that, I've never actually needed any of that state information to investigate an exception. I might put some conditional compilation in my exception handling code so that I don't normally carry the overhead of capturing and reporting that additional state. If I find during future development (including beta testing) that there is some horrible problem then I could use the conditional compilation to build that support back in. For that additional state, the zip option is a good one, but otherwise the Dictionary is enough. Of course, your experience may differ, particularly if you manipulate complex data and need to send a dataset with an exception report.

  • batmacibatmaci DEMember ✭✭✭✭✭
    edited February 18

    I am using Dictionary on handled exceptions but as @LuiC said, char length is limited to 64 chars I believe. When you want to pass json object, it truncates. I work with json objects sometimes long repeated list. So it doesnt mostly fit to my requirements.
    Beside that my question was actually for crashes. Appcenter doesnt support dictionary for crashes (if they didnt release new version). So for unhandled crashes, you are down to one option if you need more information as it was stated in the blog post.
    I will test something like within OnStart of the app.xaml.cs on separate thread.

    if(await Crashes.HasCrashedInLastSessionAsync())
    {
       Crashes.GetErrorAttachments = report =>
    {
    var compressedLogs = LoggerFactory.GetCompressedLogs();
    return new[] { ErrorAttachmentLog.AttachmentWithBinary(compressedLogs.ToArray(), “logs.zip”, “application/x-zip-compressed”), };
    };
    
    public static MemoryStream GetCompressedLogs()
    {
    Stream compressedLogs = null;
    Task.Run(async () => compressedLogs = await _logManager.GetCompressedLogs()).Wait();
    return (MemoryStream)compressedLogs;
    }
    }
    

    interesting annotation in the documentation is for HasCrashedInLastSessionAsync check "This method must only be used after Crashes has been started, it will always return false before start." What does that mean i dont understand? do we have a method called AfterCrash or can we know if user was returned from crash ?

  • JohnHardmanJohnHardman GBUniversity admin
    edited February 18

    @batmaci said:
    I am using Dictionary on handled exceptions but as @LuiC said, char length is limited to 64 chars I believe. When you want to pass json object, it truncates. I work with json objects sometimes long repeated list. So it doesnt mostly fit to my requirements.

    Yes, if you need to report the dataset itself, then the Dictionary will not suffice.

    @batmaci said:
    Beside that my question was actually for crashes.

    Yes, we were digressing :-)

    @batmaci said:
    interesting annotation in the documentation is for HasCrashedInLastSessionAsync check "This method must only be used after Crashes has been started, it will always return false before start." What does that mean i dont understand? do we have a method called AfterCrash or can we know if user was returned from crash ?

    I assume that means that you must have called AppCenter.Start() before using HasCrashedInLastSessionAsync, but the documentation page at https://docs.microsoft.com/en-us/appcenter/sdk/crashes/xamarin is pretty ambiguous.

  • batmacibatmaci DEMember ✭✭✭✭✭
    Haha ok I misunderstood the sentence, I thought after crashes app has been started. Anyhow I will keep you posted with my testing results. Cheers
  • NMackayNMackay GBInsider, University admin

    I've done this recently and it works well, let me know if you have any issues

  • NMackayNMackay GBInsider, University admin

    Remember to set the override before you initialise app center

     protected override async void OnInitialized()
            {
                InitializeComponent();
    
                // Crash Event handlers have to be setup before initializing app center
                Container.Resolve<ICrashesService>();
                AppCenter.Start(idString, typeof(Analytics), typeof(Crashes));
    
  • batmacibatmaci DEMember ✭✭✭✭✭

    @NMackay did you use Metrolog or similar like mentioned in the article above? I think that OnInitialized is prism specific. is it similar to OnStart?

  • NMackayNMackay GBInsider, University admin
    edited February 23

    Probably for vanilla Forms this would happen in the constructor of App.xaml.cs

    You have to hookup the callbacks before starting AppCenter wherever you decide to do it.

    Current project uses nLog, I can't share the implementation as it's client code.

    Remember, the attachment limit for the file is 7MB so I'd recommend zipping the log.

  • batmacibatmaci DEMember ✭✭✭✭✭

    isnt Nlog adding extra weigh to your app size? nuget package seems to be to large comparing to metrolog. Metrolog claims to be the light weight version of the Nlog. I will try Nlog also to see difference.
    Looks like article above is incomplete doesnt tell how exactly the logs are retrieved using Metrolog. at least from where in the platform specific implementation. I always get path null exception. I raised the question to appcenter support and metrolog issues. I will update once i get an answer.

  • batmacibatmaci DEMember ✭✭✭✭✭

    I checked deeper into the metrologs and understood how it works and now it is clear what it meant in the article above. I thought that Post writer meant by attaching logs as Appcenter logs but actually he means that we should log ourself using metrolog or nlog. So basically we should log every possible action of user under the MetroLog default folder path and once crash occurs, you zip those last collected logs and send as attachment to the appcenter.
    Does it make sense? Do pro apps log user actions like that? Been long time but hockeyapp had something integrated i believe if i am not mistaken and you could ask user to post.
    @NMackay are you doing this way if i may ask? Does it add more stress on the app for user if we log every important action?

  • NMackayNMackay GBInsider, University admin

    @batmaci said:
    I checked deeper into the metrologs and understood how it works and now it is clear what it meant in the article above. I thought that Post writer meant by attaching logs as Appcenter logs but actually he means that we should log ourself using metrolog or nlog. So basically we should log every possible action of user under the MetroLog default folder path and once crash occurs, you zip those last collected logs and send as attachment to the appcenter.
    Does it make sense? Do pro apps log user actions like that? Been long time but hockeyapp had something integrated i believe if i am not mistaken and you could ask user to post.
    @NMackay are you doing this way if i may ask? Does it add more stress on the app for user if we log every important action?

    "Does it add more stress on the app for user if we log every important action?"

    Not really, we log important user journeys in the log, we also use analytics in AppCenter for this purpose. IMHO Xamarin Insights was far better at this than AppCenter but that's crying over spilt milk. The local logs are useful for fault diagnosis, what was happening before the crash etc. We use nLog, you'll have to zip the latest log file though and attach as the limit is 7MB (well I'd recommend this approach).

Sign In or Register to comment.