【问题标题】:No log file created when calling UseWindowsService调用 UseWindowsService 时未创建日志文件
【发布时间】:2021-10-15 03:07:33
【问题描述】:

我按照Serilog instructions 向我的应用程序添加了一个非常基本的日志文件。

我可以通过以下方式重现它:

  • 使用 Visual Studio 创建了一个新的ASP.NET Core Web Api,默认参数为:.NET 5,无身份验证,配置为 HTTPS,启用 OpenAPI 支持
  • 安装了Serilog.AspNetCore
  • 安装了Microsoft.Extensions.Hosting.WindowsServices 包(所以我可以调用UseWindowsService() 扩展方法)
  • 将我的Program.cs 类编辑如下:
public class Program
{
    public static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Information()
            .WriteTo.File("logs.txt", rollingInterval: RollingInterval.Day)
            .CreateLogger();

        try
        {
            Log.Information("Starting Web Host");
            CreateHostBuilder(args).Build().Run();
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host terminated unexpectedly");
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .UseSerilog()
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}
  • 从 app.settings 中删除了 Logging 部分:
{
  "AllowedHosts": "*"
}

到目前为止,当我从 Visual Studio 或 Windows 资源管理器运行 Web api 时,一切正常:文件 logs.txt 已按预期创建,并且 Web api 处于活动状态。

但是,当我创建一个 Windows 服务来运行应用程序时:

sc.exe create TestService binPath="path\to\WebApplication1.exe"

尽管 web api 运行良好,但没有创建日志文件。

这是我尝试过的一些事情:

  • 更改了使用我自己的帐户运行服务的用户 => 没有变化
  • 删除了对UseWindowsService() 的调用 => web api 没有启动
  • 使用了另一个提供程序 (NLog) => 相同的行为:未创建日志文件
  • UseWindowsService()UseSerilog() 之间切换呼叫 => 没有变化
  • ConfigureWebHostDefaults() 之后调用UseWindowsService()UseSerilog()(按两个顺序)=> 没有变化

我做错了什么?可能整个 run as a windows service 部分不是将我的 Web api 作为服务运行的最佳方式吗?

【问题讨论】:

    标签: c# serilog asp.net-core-5.0


    【解决方案1】:

    Serilog 故障排除的第一条规则是启用SelfLog 并查看 Serilog 接收器抛出了哪些错误消息。


    很可能是权限问题(即帐户无权写入您尝试写入的文件夹)。

    .WriteTo.File("logs.txt", ...) 写入当前工作目录,在 Windows 服务的情况下通常意味着 %WINDIR%\System32 - 我确定它不是您想要存储日志的地方。

    因此,您需要更明确地说明要将日志写入的路径,并确保它指向用于运行服务的帐户将具有写入权限的文件夹。

    一种常见的模式是在配置文件中定义路径(例如appSettings.json)并检索它。

    如果您希望写入 Windows 服务二进制文件所在的同一个文件夹,现在一种可靠的方法是使用 Process.GetCurrentProcess().MainModule?.FileName (1)。例如:

    var startupPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule?.FileName);
    var logFilePath = Path.Combine(startupPath, "logs.txt");
    
    Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Information()
        .WriteTo.File(logFilePath, rollingInterval: RollingInterval.Day)
        .CreateLogger();
    

    (1) 在未来的 .NET 版本中,您将能够使用 Environment.ProcessPathEnvironment.ApplicationDirectory

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 2016-01-27
    相关资源
    最近更新 更多