Cross Platform Logging in Xamarin

user3430360 picture user3430360 · Mar 17, 2014 · Viewed 10.7k times · Source

I am looking for either a logging utility such as NLog, Log4Net, etc... that will allow me to log in my Xamarin.Andriod, Xamarin.IOS, and a Xamarin.PCL project. All of the loggers I have looked at so far are not supported in the PCL projects for various reasons (most around File IO). Are there any solutions available to support logging in a cross platform fashion including PCL projects? If none, how have you implemented logging in PCL's (design patterns, etc...)?

Thanks

Answer

SKall picture SKall · Mar 17, 2014

You would want to use dependency injection if there are no PCL loggers. The following is just a concept (although it does work) with two sample implementations (Android Log & SQLite database).

Abstracted interface close to Android's Log class: https://github.com/sami1971/SimplyMobile/blob/master/Core/SimplyMobile.Core/Logging/ILogService.cs

Android specific implementation, a wrapper around Log class: https://github.com/sami1971/SimplyMobile/blob/master/Android/SimplyMobile.Android/Logging/LogService.cs

PCL implementation for database logging with a dependency to CRUD provider: https://github.com/sami1971/SimplyMobile/blob/master/Core/SimplyMobile.Core/Data/DatabaseLog.cs

CRUD provider wrapper for SQLite.Net.Async PCL compatible library (available for iOS, Android & WP8): https://github.com/sami1971/SimplyMobile/blob/master/Core/Plugins/Data/SimplyMobile.Data.SQLiteAsync/SQLiteAsync.cs

CRUD provider wrapper for ServiceStack.OrmLite (available for iOS & Android): https://github.com/sami1971/SimplyMobile/blob/master/Core/Plugins/SimplyMobile.Data.OrmLite/OrmLite.cs

At the application level use IoC container to register the services you want to use. Example is for WP8 but to use it for iOS and Android you would only need to change the ISQLitePlatform.

  DependencyResolver.Current.RegisterService<ISQLitePlatform, SQLitePlatformWP8>()
       .RegisterService<IJsonSerializer, SimplyMobile.Text.ServiceStack.JsonSerializer>()
       .RegisterService<IBlobSerializer>(t => t.GetService<IJsonSerializer>().AsBlobSerializer())
       .RegisterService<ILogService>(t =>
                new DatabaseLog(
                    new SQLiteAsync(
                        t.GetService<ISQLitePlatform>(), 
                        new SQLiteConnectionString(
                            Path.Combine(ApplicationData.Current.LocalFolder.Path, "device.log"),
                            true,
                            t.GetService<IBlobSerializer>())
                    )));

Using the Android Log-wrapper of course would be much simpler since it doesn't have any dependencies:

DependencyResolver.Current.RegisterService<ILogService, LogService>();