Serilog 记录器正在复制每个日志行

din*_*tom 2 c# serilog

我正在尝试新的 Azure v12 SDK 并使用 Serilog 将项目记录到控制台(它是一个 .Net 5 控制台应用程序)

每个 Log.Logger 行都在控制台上复制自身,但不在日志文件中。我试图找出为什么会发生这种情况。

控制台截图 控制台日志记录

日志文件截图 日志文件记录

这是我在 Program.cs 中的 Serilog 设置

private static IHost AppStartup(string logFilepath)
    {
        var builder = new ConfigurationBuilder();
        ConfigSetup(builder);

        // defining Serilog configs
        Log.Logger = new LoggerConfiguration()
            .ReadFrom.Configuration(builder.Build())
            .Enrich.FromLogContext()
            .WriteTo.Console()
            .WriteTo.Seq("https://localhost:5341/")
            .WriteTo.File(logFilepath, rollingInterval: RollingInterval.Day)
            .CreateLogger();

        // Initiated the dependency injection container 
        var host = Host.CreateDefaultBuilder()
            .ConfigureServices((context, services) => {
                services.AddLogging(m => m.AddSerilog(Log.Logger));
                services.AddTransient<IAzureService, AzureService.AzureService>();
                services.AddTransient<BlobServiceManager>();
            }).Build();
        //this line is duplicating as well!
        Log.Logger.Information($"{DateTime.Now}: Serilog logger created for LoadCurrencyDataAndProcess");
        return host;
    }
Run Code Online (Sandbox Code Playgroud)

这是方法中的代码。(我已经单步执行了代码,并且确信当 Log.Logger 行执行时,它在控制台中进行了两次打印,代码没有运行两次)

public void ListContainers(BlobServiceClient blobServiceClient)
{
    try
    {
        Log.Logger.Information($"From containers collection");
        var containers = blobServiceClient.GetBlobContainers();
           
        foreach (var container in containers)
        {
        //Also tried just Log.Information here, it produced same result
            Log.Logger.Information($"Container name: {container.Name}");
        }
    }
    catch (RequestFailedException e)
    {
        Log.Logger.Error($"{DateTime.Now}: An error occurred trying to retrieve containers from {_service.StorageClient.AccountName} with error message {e.Message}");
           
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我在 appsettings.json 中对 Serilog 的配置

 "Serilog": {
"Using": [],
"MinimumLevel": {
  "Default": "Information",
  "Override": {
    "Microsoft": "Warning",
    "System": "Warning"
  }
},
"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
"WriteTo": [
  { "Name": "Console" },
  {
    "Name": "ApplicationInsights",
    "Args": {
      "restrictedToMinimumLevel": "Information",
      "telemetryConverter": "Serilog.Sinks.ApplicationInsights.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights"
    }
  },
  {
    "Name": "File",
    "Args": {
      "path": "C:\\Users\\Logs\\CurrencyData\\currencydataprocessingtotablestorage.txt",
      "outputTemplate": "{Timestamp:G} :: Message:=={Message}{NewLine:1} Exception:=={Exception:1}"
    }
  },
  {
    "Name": "Seq",
    "Args": {
      "serverUrl": "https://localhost:5341/"
      //or 8081
     }
   }
 ]
}
Run Code Online (Sandbox Code Playgroud)

这不是一个主要问题,我只是想了解为什么会发生这种情况,以确保我的日志记录设置正确。(我是 Serilog 的新手)

Phi*_*Ape 8

您都在您的LoggerConfiguration和 您的中指定了接收器appsettings.json

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(builder.Build())
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .WriteTo.Seq("https://localhost:5341/")
    .WriteTo.File(logFilepath, rollingInterval: RollingInterval.Day)
    .CreateLogger();
Run Code Online (Sandbox Code Playgroud)
"WriteTo": [
  { "Name": "Console" },
  {
    ...
  },
  {
    "Name": "File",
    ...
  },
  {
    "Name": "Seq",
    ...
  }
 ]
Run Code Online (Sandbox Code Playgroud)

接收器只能配置在一处。我建议删除所有WriteTo语句并仅使用配置文件,因为它更灵活,如果需要,您可以稍后在生产使用中通过配置删除接收器。

所以只需删除这些行:

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(builder.Build())
    .Enrich.FromLogContext()
    //.WriteTo.Console()
    //.WriteTo.Seq("https://localhost:5341/")
    //.WriteTo.File(logFilepath, rollingInterval: RollingInterval.Day)
    .CreateLogger();
Run Code Online (Sandbox Code Playgroud)

  • 这两个调用没有区别。`Log.Information()` 只是 `Log.Logger.Information()` 的包装调用。所以你可以使用 Log.Information() 因为它更短。 (3认同)
  • 使用 Log.Information 或 Log.Logger.Information 有什么区别? (2认同)