Logging to elmah.io from Xamarin
Warning
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="4.0.30-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.
Open the MainActivity.cs
file and add the following using
statements:
using System;
using Elmah.Io.Xamarin;
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"),
});
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.
Open the Main.cs
file and add the following using
statements:
using System;
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"),
});
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.
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
methods available in the Elmah.Io.Xamarin
namespace:
try
{
// Code that may break
}
catch (Exception e)
{
// Log the exception with the Log extension method:
e.Log();
// or use the Log method on ElmahIoXamarin:
ElmahIoXamarin.Log(e);
}
Breadcrumbs
Breadcrumbs can be a great help when needing to figure out how a user ended up with an error. To log breadcrumbs, you can use the AddBreadcrumb
method on ElmahIoXamarin
. The following is a sample for Android which will log breadcrumbs on interesting events:
public class MainActivity : AppCompatActivity, BottomNavigationView.IOnNavigationItemSelectedListener
{
public override void OnBackPressed()
{
ElmahIoXamarin.AddBreadcrumb("OnBackPressed", DateTime.UtcNow, action: "Navigation");
base.OnBackPressed();
}
protected override void OnPause()
{
ElmahIoXamarin.AddBreadcrumb("OnPause", DateTime.UtcNow);
base.OnPause();
}
// ...
public bool OnNavigationItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Resource.Id.navigation_home:
ElmahIoXamarin.AddBreadcrumb("Navigate to Home", DateTime.UtcNow, action: "Navigation");
textMessage.SetText(Resource.String.title_home);
return true;
case Resource.Id.navigation_dashboard:
ElmahIoXamarin.AddBreadcrumb("Navigate to Dashboard", DateTime.UtcNow, action: "Navigation");
textMessage.SetText(Resource.String.title_dashboard);
return true;
case Resource.Id.navigation_notifications:
ElmahIoXamarin.AddBreadcrumb("Navigate to Notifications", DateTime.UtcNow, action: "Navigation");
textMessage.SetText(Resource.String.title_notifications);
return true;
}
return false;
}
}
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="5.*" />
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.
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;
}
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