Search code examples
c#xamarin.formsmvvmcrossnlog

Xamarin MvvmCross how to use NLog for IMvxLogProvider?


I followed Diagnostic & Logging and install NLog.Config nuget package to Android & iOS project.

on Android project, Setup.cs

public override MvxLogProviderType GetDefaultLogProviderType() => MvxLogProviderType.NLog;

On Xamarin.Forms project,

private static readonly IMvxLog _logger = Mvx.IoCProvider.Resolve<IMvxLogProvider>().GetLogFor<CanvasContainer>();

_logger.Debug($"startScale: {startScale}, currentScale: {currentScale}");

I checked _logger is not null.

Also, I changed NLog.config's Build Action to Embedded Resource.

Here is Android Project's NLog.config,

<?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"
      internalLogFile="c:\temp\nlog-internal.log">

  <targets>
    
    <target xsi:type="File" 
            name="FileTarget" 
            fileName="${specialfolder:folder=MyDocuments}/logs/${shortdate}.log" 
            layout="${longdate}|${level:uppercase=true}|${logger}|${message}" />
    
    <target xsi:type="ColoredConsole"
            name="ConsoleTarget"
            encoding="utf-8"
            layout="${longdate}|${level:uppercase=true}|${logger}|${message}"
            useDefaultRowHighlightingRules="true" />
    
  </targets>

  <rules>
    <logger name="*" minlevel="Debug" writeTo="FileTarget" />
    <logger name="*" minlevel="Debug" writeTo="ConsoleTarget" />
  </rules>
</nlog>

Is there anything wrong with this set up? I can not find sample or tutorial for this...


Solution

  • Think you need to help NLog when having NLog.config as Embedded Resource:

        public override MvxLogProviderType GetDefaultLogProviderType() => MvxLogProviderType.NLog;
        
        protected override IMvxLogProvider CreateLogProvider()
        {
          var nlogConfigFile = GetEmbeddedResourceStream(myAssembly, "NLog.config");
          if (nlogConfigFile != null)
          {
            var xmlReader = System.Xml.XmlReader.Create(nlogConfigFile);
            NLog.LogManager.Configuration = new XmlLoggingConfiguration(xmlReader, null);
          }
          return base.CreateLogProvider();
        }
    
        private static Stream GetEmbeddedResourceStream(Assembly assembly, string resourceFileName)
        {
          var resourcePaths = assembly.GetManifestResourceNames()
            .Where(x => x.EndsWith(resourceFileName, StringComparison.OrdinalIgnoreCase))
            .ToList();
          if (resourcePaths.Count == 1)
          {
            return assembly.GetManifestResourceStream(resourcePaths.Single());
          }
          return null;
        }
    

    See also: https://github.com/NLog/NLog/wiki/Explicit-NLog-configuration-loading#loading-nlog-configuration-from-xamarin-resource