Every application need some kind of logging or monitoring system. Monitoring can be used for tracing errors and exceptions, for analyzing of app usage, for finding hard-to-trace bugs in “production environment”, for storing some other runtime data interested for later analysis, and similar.
In general and very commonly, .NET desktop apps use some kind of local text file storage for this purpose. The most used log frameworks for .NET ecosystem are: NLog, log4net, Elmah (asp.net), Serilog, Windows EventLog. If you develop desktop .NET application you will most likely sooner or latter include one of those log frameworks into your application.
On mobile applications (and lately also on other types of apps), more commonly approach of using tracing and diagnostic is by some cloud based tools, like Visual Studio App Center. I wrote a blog post about this here: https://www.jenx.si/2019/08/24/app-center-and-wpf.
Nevertheless, today I will show how to use NLog in Xamarin Forms applications.
Adding NLog to Xamarin Forms application
First, In Visual Studio 2019 I create empty Xamarin Forms application targeting Android and iOS.
Secondly, I update all my NuGets to the latest version. Then I install the latest version of NLog NuGet to all my project (shared project and platform-specific projects).
Now, I have the following situation:
Next, I need to add NLog.config
to the platform-specific projects. This file defines behavior of NLog logger. Basically, this file defines location of log files, targets (log sinks), format of output messages and other configuration settings.
Thus, NLog.config
file is crucial part when integrating NLog logging framework into any .NET application. You can find more information how to tune-up NLog.config file here: https://github.com/nlog/nlog/wiki.
Here, you can see my NLog.config configuration.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd" autoReload="true" throwExceptions="false" internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log"> <targets> <target xsi:type="File" name="fileTarget" fileName="${specialfolder:folder=MyDocuments}/logs/${shortdate}.log.csv" archiveFileName="${specialfolder:folder=MyDocuments}/logs/archive.{#}.log.csv" archiveEvery="Day" archiveNumbering="Rolling" maxArchiveFiles="7" concurrentWrites="true" keepFileOpen="false"> <layout xsi:type="CsvLayout" delimiter="Tab" quoting="Nothing" withHeader="true"> <column name="time" layout="${longdate:universalTime=true}" /> <column name="threadid" layout="${threadid}" /> <column name="level" layout="${level:upperCase=true}" /> <column name="callsite" layout="${callsite:includeSourcePath=true}" /> <column name="message" layout="${message}" /> <column name="stacktrace" layout="${callsite:includeSourcePath=true}" /> <column name="exception" layout="${exception:format=ToString}" /> </layout> </target> </targets> <rules> <logger name="*" writeTo="fileTarget" /> </rules> </nlog> |
For Android I put NLog.config file in Assets folder and set file property Build Action to AndroidAsset, e.g.:
For iOS this file needs to be on the root folder and marked as Content, e.g.:
That’s basically it. To test if everything works, I created one simple page with button and put some log procedure inside onclick event.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="Jenx.XForms.Nlog.NLogPage" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:d="http://xamarin.com/schemas/2014/forms/design" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <ContentPage.Content> <StackLayout> <Label HorizontalOptions="CenterAndExpand" Text="Welcome to jenx.si Xamarin Forms NLog demo!" VerticalOptions="CenterAndExpand" /> <Button Clicked="LogEventButton_Clicked" Text="Log" /> </StackLayout> </ContentPage.Content> </ContentPage> |
Visually, the page looks very minimalistic:
Code related to this page is simple, LogEventButton_Clicked
event handler handles button click event and writes Info log.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
using NLog; using System; using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace Jenx.XForms.Nlog { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class NLogPage : ContentPage { public NLogPage() { InitializeComponent(); } private void LogEventButton_Clicked(object sender, EventArgs e) { var logger = LogManager.GetCurrentClassLogger(); logger.Info("Jenx.si was here"); } } } |
If I start my apps (iOS and Android), my log files are created in apps sandbox on my smartphones/simulators. Let’s check it out.
Checking logs
Android
For Android I use my device to test the app. I can use adb.exe to observe my smartphone nlog records:
iOS
I am using iOS Simulator to test my app. iOS Simulator use host OS file system (macOS) for application storage.
One way to find where iOS simulator puts iOS Device and app files is by putting breakpoint in the app and in immediate window display physical location of SpecialFolder.Personal
folder location:
Environment.GetFolderPath(Environment.SpecialFolder.Personal);
Then, on my hosting Mac computer I simply move to that location and check log folder with NLog files inside, e.g.:
Conclusion
In this blog post I presented simple example of usage of NLog in Xamarin Forms (Android, iOS) applications.
Presented case is the very basic usage, but you can quickly extend this example to more production-ready code, like by introduction of logging service, dependency injection, using of different targets (console, mail…) and so on.
Although, I am a big fan of cloud based logging, diagnostics and analytics systems (like, for example, App Center Diagnostics and Analytics) in some cases local logging can be very useful.
You can find source code accompanying this blog post here: https://github.com/josipx/Jenx.XForms.Nlog.
Cheers and happy coding.