Serilog Net Core 3.1 不创建任何日志文件

Posted

技术标签:

【中文标题】Serilog Net Core 3.1 不创建任何日志文件【英文标题】:Serilog Net Core 3.1 not create any log files 【发布时间】:2020-04-25 20:40:45 【问题描述】:

我在 .NET Core 3.1 项目中使用 Serilog 进行日志管理。 本项目部署在IIS下的windows服务器上。此外,我有一个文件服务器可用于存储日志文件。 IIS 用户在此文件服务器上具有读取和写入权限,因为已经有其他 Web 应用程序登录此服务器。 服务器在它们之间是可见且可访问的。

我通过以下方式实现了 Serilog:

public class Program 

        public static void Main(string[] args)
        
            CreateHostBuilder(args).Build().Run();
        

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args) 
                .ConfigureWebHostDefaults(webBuilder =>
                
                    webBuilder.UseStartup<Startup>();
                    webBuilder.UseIISIntegration();
                )
                .ConfigureAppConfiguration((context, builder) =>
                
                    // Here I recover the configuration correctly
                    var configuration = GetConfiguration();
                )
                .UseSerilog((hostingContext, loggerConfiguration) => 
                
                     // hostingContext.Configuration.GetLogOuput() is a custom extension methods.
                     var pathLogFile = Path.Combine(hostingContext.Configuration.GetLogOutput(), hostingContext.HostingEnvironment.ApplicationName, "concurrentFlat.json");

                    if (hostingContext.HostingEnvironment.IsDevelopment())
                    
                        loggerConfiguration
                          .MinimumLevel.Debug()
                          .Enrich.FromLogContext()
                          .Enrich.WithMachineName()
                          .Enrich.WithEnvironmentUserName()
                          .Enrich.WithProcessId()
                          .Enrich.WithProcessName()
                          .Enrich.WithThreadId()
                          .Enrich.WithProperty("ApplicationName", hostingContext.HostingEnvironment.ApplicationName)
                          .Enrich.WithProperty("Environment", hostingContext.HostingEnvironment.EnvironmentName)
                          .WriteTo.Console()
                          .WriteTo.File(
                              path: pathLogFile,
                              formatter: new CompactJsonFormatter(),
                              rollOnFileSizeLimit: true,
                              fileSizeLimitBytes: 10000000
                          );
                    
                    else
                    
                        loggerConfiguration
                             .MinimumLevel.Information()
                             .Enrich.FromLogContext()
                             .Enrich.WithMachineName()
                             .Enrich.WithEnvironmentUserName()
                             .Enrich.WithProcessId()
                             .Enrich.WithProcessName()
                             .Enrich.WithThreadId()
                             .Enrich.WithProperty("ApplicationName", hostingContext.HostingEnvironment.ApplicationName)
                             .Enrich.WithProperty("Environment", hostingContext.HostingEnvironment.EnvironmentName)
                             .WriteTo.File(
                                 path: pathLogFile,
                                 formatter: new CompactJsonFormatter(),
                                 rollOnFileSizeLimit: true,
                                 fileSizeLimitBytes: 10000000
                             );
                    
                );

使用开发配置,一切正常,当我尝试模拟应用程序的行为时,总是在我的本地机器上,在生产环境中(将环境变量 ASPNETCORE_ENVIRONMENT 设置为生产),行为是预期的。 此方法:“hostingContext.Configuration.GetLogOutput()”从环境变量中读取文件服务器的路径。我已经验证它是正确的,但没有创建任何文件。

这是我使用 .NET Core ILoggger 接口的代码 sn-p:

using Microsoft.Extensions.Logging;

public class FooController : Controller

    private readonly ILogger<FooController> _logger;

    public FooController(ILogger<FooController> logger) 
    
        _logger = logger;
    

    public async Task<IActionResult> Get() 
    
        _logger.LogError("Test Error log");
         return Ok();
    

您知道为什么不在文件服务器上创建日志文件吗?

提前致谢

【问题讨论】:

"IIS 用户对该文件服务器有读写权限",哪个用户?请具体。 是一个临时创建的用户,在两台服务器上都具有写入和读取权限。他是一个预先存在的用户。 【参考方案1】:

我已经测试了您的代码,并且看起来运行良好。所以,你可以检查下面的列表,看看有没有和我的不同,

    版本
  <ItemGroup>
    <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
    <PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.3" />
    <PackageReference Include="Serilog.Enrichers.Process" Version="2.0.1" />
    <PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" />
    <PackageReference Include="Serilog.Extensions.Logging.File" Version="2.0.0" />
  </ItemGroup>
    使用普通日志路径替换为 pathLogFile 变量进行测试
public static class CustomConfigurationExtension

    public static string GetLogOutput(this IConfiguration config) => "log";
  
    为不同环境(DevelopmentProduction 等)设置简单的 appsettings.json 路径以进行测试

Startup.cs

.ConfigureHostConfiguration(config =>

    config.SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production".json", optional: true)
        .AddEnvironmentVariables();
)
    使用此 appsetting.json 进行测试

appsettings.json


  "Serilog": 
    "MinimumLevel": 
      "Default": "Information",
      "Override": 
        "Microsoft": "Warning",
        "System": "Warning"
      
    
  ,
  "AllowedHosts": "*"

上面的大多数示例我只是按照 github 中的 serilog EarlyInitializationSample。这是我测试的全部内容。希望有所帮助。

程序.cs

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        
            webBuilder.UseStartup<Startup>();
            webBuilder.UseIISIntegration();
        )
        .ConfigureHostConfiguration(config =>
        
            config.SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production".json", optional: true)
                .AddEnvironmentVariables();
        )
        .UseSerilog((hostingContext, loggerConfiguration) =>
        
            var pathLogFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                hostingContext.Configuration.GetLogOutput(), 
                hostingContext.HostingEnvironment.ApplicationName,
                "concurrentFlat.json"
            );

            if (hostingContext.HostingEnvironment.IsDevelopment())
            
                loggerConfiguration
                  .MinimumLevel.Debug()
                  .Enrich.FromLogContext()
                  .Enrich.WithMachineName()
                  .Enrich.WithEnvironmentUserName()
                  .Enrich.WithProcessId()
                  .Enrich.WithProcessName()
                  .Enrich.WithThreadId()
                  .Enrich.WithProperty("ApplicationName", hostingContext.HostingEnvironment.ApplicationName)
                  .Enrich.WithProperty("Environment", hostingContext.HostingEnvironment.EnvironmentName)
                  .WriteTo.Console()
                  .WriteTo.File(
                      path: pathLogFile,
                      rollingInterval: RollingInterval.Day,
                      formatter: new CompactJsonFormatter(),
                      rollOnFileSizeLimit: true,
                      fileSizeLimitBytes: 10000000
                  );
            
            else
            
                loggerConfiguration
                     .MinimumLevel.Information()
                     .Enrich.FromLogContext()
                     .Enrich.WithMachineName()
                     .Enrich.WithEnvironmentUserName()
                     .Enrich.WithProcessId()
                     .Enrich.WithProcessName()
                     .Enrich.WithThreadId()
                     .Enrich.WithProperty("ApplicationName", hostingContext.HostingEnvironment.ApplicationName)
                     .Enrich.WithProperty("Environment", hostingContext.HostingEnvironment.EnvironmentName)
                     .WriteTo.File(
                         path: pathLogFile,
                         formatter: new CompactJsonFormatter(),
                         rollOnFileSizeLimit: true,
                         fileSizeLimitBytes: 10000000
                     );
            
        );

【讨论】:

以上是关于Serilog Net Core 3.1 不创建任何日志文件的主要内容,如果未能解决你的问题,请参考以下文章

更改调试字体颜色 - Serilog C# .NET Core 3.1 Jetbrains Rider Mac OSX

创建返回 Serilog LoggerConfiguration 的方法(Asp.Net Core 2.0)

在 ASP.NET Core 6.0 中使用 Serilog

在 ASP.NET Core 中使用 Serilog 使用 Fluentd 将日志写入 Elasticsearch

C# ASP.NET Core Serilog 添加类名和方法到日志

在带有数据库的 ASP.NET Core 5.0 应用程序中使用 Serilog 实现日志记录