在 MvvmCross 中使用 serilog 的 ForContext

问题描述

我正在使用 xamarin MvvmCross 并将 serilog 配置为记录器。 我正在尝试将自定义变量添加到在上下文中传递它们的模板,但我不知道该怎么做。

这是我的 serilog 配置:

var local = Application.Context.GetExternalFilesDir("").AbsolutePath;
string path = Path.Combine(local,"my_log.txt");

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Verbose()
    .Writeto.File(path,rollingInterval: RollingInterval.Day,outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss zzz} {myCustomVar} [{Level:u3}] {Message:lj}")
    .CreateLogger();

在我的 viewmodel 中,我试图记录一条消息:

using (_logProvider.OpenMappedContext("myCustomVar","varValue"))
            {
                _log.Info("Good Morning");
            }

输出到 my_log.txt 的行不包含“myCustomVar”的值。

我发现让它工作的唯一方法是完全绕过 MvvmCross 并编写一个直接调用 serilog 的自定义记录器,如下所示:

    public interface ILogService
    {
        void LogMessage(string message);
    }

和安卓实现:

public class LogService : ILogService
    {
        public void LogMessage(string message)
        {
            Log.ForContext("myCustomVar","varValue")
                        .information(message);
        }
    }

有没有一种方法可以访问 serilog 的高级功能,例如使用 MvvmCross/IMvx 日志抽象层在上下文中传递变量?

解决方法

您需要 connect Serilog and MvvmCross together 才能使其工作,并且您还需要 enrich with properties from the log context,因为 MvvmCross 集成的实现方式(它们不调用 ForContext,而是他们叫PushProperty)。

覆盖平台项目的 GetDefaultLogProviderType 中的 Setup.cs

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

并从您创建的 Serilog 记录器创建一个 IMvxLogProvider

protected override IMvxLogProvider CreateLogProvider()
{
    var local = Application.Context.GetExternalFilesDir("").AbsolutePath;
    string path = Path.Combine(local,"my_log.txt");

    Log.Logger = new LoggerConfiguration()
      .MinimumLevel.Verbose()
      .Enrich.FromLogContext()
      .WriteTo.File(path,rollingInterval: RollingInterval.Day,outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss zzz} {myCustomVar} [{Level:u3}] {Message:lj}")
      .CreateLogger();

      return base.CreateLogProvider();
}