调用 UseWindowsService 时未创建日志文件

No log file created when calling UseWindowsService

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

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

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>();
            });
}
{
  "AllowedHosts": "*"
}

到目前为止,当我从 Visual Studio 或 windows 资源管理器 运行 网络 api 时,一切正常:文件 logs.txt 已创建正如预期的那样,网络 api 还活着。

但是,当我为 运行 应用程序创建 windows 服务时:

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

尽管网络 api 运行 很好,但没有创建日志文件。

以下是我尝试过的一些方法:

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

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.ProcessPath or Environment.ApplicationDirectory