Build status NuGet Samples

Logging to elmah.io from Xamarin

The Xamarin integration for elmah.io is currently in prerelease.

Integrating Xamarin with elmah.io is done by installing the Elmah.Io.Xamarin NuGet package:

Install-Package Elmah.Io.Xamarin -IncludePrerelease
dotnet add package Elmah.Io.Xamarin --prerelease
<PackageReference Include="Elmah.Io.Xamarin" Version="3.0.8-pre" />
paket add Elmah.Io.Xamarin

For each platform (Android and iOS) you will need to set up elmah.io as illustrated in the following sections. The code is the same for both Xamarin and Xamarin.Forms.

Android

Open the MainActivity.cs file and add the following using statements:

using Elmah.Io.Xamarin;
using System.Threading.Tasks;

Locate the OnCreate method and add the following code before all other lines:

ElmahIoXamarin.Init(new ElmahIoXamarinOptions
{
    ApiKey = "API_KEY",
    LogId = new Guid("LOG_ID"),
});
AndroidEnvironment.UnhandledExceptionRaiser += (sender, e) =>
{
    e.Exception.Log();
    e.Handled = true;
};
TaskScheduler.UnobservedTaskException += (sender, e) =>
{
    e.Exception.Log();
    e.SetObserved();
};

Replace API_KEY with your API key (Where is my API key?) and LOG_ID (Where is my log ID?) with the log Id of the log you want to log to.

Calling the Init method will initialize elmah.io. For more configuration options see the Additional configuration section. The code then subscribes to the UnhandledExceptionRaiser and UnobservedTaskException events which will log any exceptions to elmah.io using the Log method.

iOS

Open the Main.cs file and add the following using statements:

using System;
using System.Threading.Tasks;
using Elmah.Io.Xamarin;

Locate the Main method and add the following code after the call to UIApplication.Main:

ElmahIoXamarin.Init(new ElmahIoXamarinOptions
{
    ApiKey = "API_KEY",
    LogId = new Guid("LOG_ID"),
});
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
    (e.ExceptionObject as Exception).Log();
};
TaskScheduler.UnobservedTaskException += (sender, e) =>
{
    e.Exception.Log();
    e.SetObserved();
};

Replace API_KEY with your API key (Where is my API key?) and LOG_ID (Where is my log ID?) with the log Id of the log you want to log to.

Calling the Init method will initialize elmah.io. For more configuration options see the Additional configuration section. The code then subscribes to the UnhandledException and UnobservedTaskException events which will log any exceptions to elmah.io using the Log method.

Log exceptions manually

Once the ElmahIoXamarin.Init method has been configured during initialization of the app, any exception can be logged manually using the Log method available in the Elmah.Io.Xamarin namespace:

try
{
    // Code that may break
}
catch (Exception e)
{
    e.Log();
}

Additional configuration

Besides the mandatory properties ApiKey and LogId the ElmahIoXamarinOptions provide a range of other configuration parameters.

Application

The elmah.io integration for Xamarin will automatically use the package name for the Application field. To override this you can set the application name in settings:

ElmahIoXamarin.Init(new ElmahIoXamarinOptions
{
    // ...
    Application = "MyApp"
});

Version

The elmah.io integration for Xamarin will automatically use the package version for the Version field. To override this you can set the version string in settings:

ElmahIoXamarin.Init(new ElmahIoXamarinOptions
{
    // ...
    Version = "1.0.2"
});

Decorating all messages

All log messages logged through this integration can be decorated with the OnMessage action:

ElmahIoXamarin.Init(new ElmahIoXamarinOptions
{
    // ...
    OnMessage = msg =>
    {
        msg.Source = "Custom source";
    }
});

Filtering log messages

Log messages can be filtered directly on the device to avoid specific log messages from being sent to elmah.io with the OnFilter function:

ElmahIoXamarin.Init(new ElmahIoXamarinOptions
{
    // ...
    OnFilter = msg => msg.Title.Contains("foo")
});

This code will automatically ignore all log messages with the text foo in the title.

Handling errors

You may want to handle the scenario where the device cannot communicate with the elmah.io API. You can use the OnError action:

ElmahIoXamarin.Init(new ElmahIoXamarinOptions
{
    // ...
    OnError = (msg, ex) =>
    {
        // Do something with ex
    }
});

Legacy integration

If you prefer you can configure elmah.io manually without the use of the Elmah.Io.Xamarin package. This is not the recommended way to integrate with elmah.io from Xamarin and this approach will be discontinued.

Start by installing the Elmah.Io.Client NuGet package:

Install-Package Elmah.Io.Client
dotnet add package Elmah.Io.Client
<PackageReference Include="Elmah.Io.Client" Version="3.*" />
paket add Elmah.Io.Client

If you are targeting a single platform, you can install the package directly in the startup project. If you are targeting multiple platforms, you can either install the package in all platform-specific projects or a shared project.

Additional steps will vary from platform to platform.

Android

Locate your main activity class and look for the OnCreate method. Here, you'd want to set up event handlers for when uncaught exceptions happen:

protected override void OnCreate(Bundle savedInstanceState)
{
    // ...

    AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser;
    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
    TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

    // ... LoadApplication(new App()); etc.
}

Next, implement a method that can log an exception to elmah.io:

private void LogExceptionToElmahIo(Exception exception)
{
    if (exception == null) return;

    if (elmahIoClient == null)
    {
        elmahIoClient = ElmahioAPI.Create("API_KEY");
    }

    var packageInfo = PackageManager.GetPackageInfo(PackageName, PackageInfoFlags.MetaData);

    var baseException = exception?.GetBaseException();
    var errorMessage = baseException?.Message ?? "Unhandled exception";
    try
    {
        elmahIoClient.Messages.Create("LOG_ID", new CreateMessage
        {
            Data = exception?.ToDataList(),
            DateTime = DateTime.UtcNow,
            Detail = exception?.ToString(),
            Severity = "Error",
            Source = baseException?.Source,
            Title = errorMessage,
            Type = baseException?.GetType().FullName,
            Version = packageInfo.VersionName,
            Application = packageInfo.PackageName,
        });
    }
    catch (Exception inner)
    {
        Android.Util.Log.Error("elmahio", inner.Message);
    }

    // Log to Android Device Logging.
    Android.Util.Log.Error("crash", errorMessage);
}

Replace API_KEY with your API key (Where is my API key?) and LOG_ID (Where is my log ID?) with the log Id of the log you want to log to.

Finally, implement the three event handlers that we added in the first step:

private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
    LogExceptionToElmahIo(e.Exception);
    e.SetObserved();
}

private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    LogExceptionToElmahIo(e.ExceptionObject as Exception);
}

private void AndroidEnvironment_UnhandledExceptionRaiser(object sender, RaiseThrowableEventArgs e)
{
    LogExceptionToElmahIo(e.Exception);
    e.Handled = true;
}

iOS

Locate your main application class and look for the Main method. Here, you'd want to set up event handlers for when uncaught exceptions happen:

static void Main(string[] args)
{
    // ...

    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
    TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
}

Next, implement a method that can log an exception to elmah.io:

private static void LogExceptionToElmahIo(Exception exception)
{
    if (exception == null) return;

    if (elmahIoClient == null)
    {
        elmahIoClient = ElmahioAPI.Create("API_KEY");
    }

    var baseException = exception?.GetBaseException();
    elmahIoClient.Messages.Create("LOG_ID", new CreateMessage
    {
        Data = exception?.ToDataList(),
        DateTime = DateTime.UtcNow,
        Detail = exception?.ToString(),
        Severity = "Error",
        Source = baseException?.Source,
        Title = baseException?.Message ?? "Unhandled exception",
        Type = baseException?.GetType().FullName,
    });
}

Replace API_KEY with your API key (Where is my API key?) and LOG_ID (Where is my log ID?) with the log Id of the log you want to log to.

Finally, implement the two event handlers that we added in the first step:

private static void TaskScheduler_UnobservedTaskException(
    object sender, UnobservedTaskExceptionEventArgs e)
{
    LogExceptionToElmahIo(e.Exception);
    e.SetObserved();
}

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    LogExceptionToElmahIo(e.ExceptionObject as Exception);
}


This article was brought to you by the elmah.io team. elmah.io is the best error management system for .NET web applications. We monitor your website, alert you when errors start happening and help you fix errors fast.

See how we can help you monitor your website for crashes Monitor your website