在 MvvmCross 中使用 serilog 的 ForContext

Using serilog´s ForContext in MvvmCross

我正在使用 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);
    }

和 android 实施:

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

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

您需要 connect Serilog and MvvmCross together for it to work, and you also need to enrich with properties from the log context 因为 MvvmCross 集成的实现方式(他们不调用 ForContext,而是调用 PushProperty)。

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

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();
}