.Net Core 6工作服务在作为Windows服务运行时无法写入日志

3

我使用C#/.Net Core 6(Visual Studio 2022)创建了一个Worker Service。

如果通过Visual Studio运行或直接从Windows资源管理器/PowerShell启动,它将按预期写入日志文件。但是,当安装为Windows服务时,它不会创建或写入日志文件。

以下是我的program.cs:

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
    .MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Information)
    .Enrich.FromLogContext()
    .WriteTo.File("./logs/log-.txt", rollingInterval:RollingInterval.Day)
    .CreateBootstrapLogger();

try
{
    Log.Information("Starting the Service");

    IHost host = Host.CreateDefaultBuilder(args)
        .UseWindowsService()
        .ConfigureAppConfiguration((hostContext, configBuilder) =>
        {
            configBuilder
                //.SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .AddJsonFile($"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{Environment.MachineName}.json", true, true)
                .Build();
        })
        .UseSerilog((context, services, configuration) => configuration
            .ReadFrom.Configuration(context.Configuration)
            .ReadFrom.Services(services)
            .Enrich.FromLogContext())
        .ConfigureServices((hostContext, services) =>
        {
            ... 
        })
        .Build();

    
    await host.RunAsync();
}
catch (Exception ex)
{
    Log.Fatal(ex, "There was a problem starting the service");
}
finally
{
    Log.Information("Service successfully stopped");

    Log.CloseAndFlush();
}

我有一个appsettings.json文件:

  "Serilog": {
    "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Sinks.Debug" ],
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "WriteTo": [
      { "Name": "Console" },
      {
        "Name": "File",
        "Args": {
          "path": ".\\logs\\log-.txt",
          "rollingInterval": "Day"
        }
      }
    ],
    "Enrich": [ "FromLogContext" ]
  }

如果我包含“SetBasePath”部分,服务将无法启动(尽管它仍然可以通过Visual Studio运行)。
我正在使用Target Framework = net6.0,Deployment Mode = Framework Dependent,Target runtime = win-x64从Visual Studio发布服务。
注意:我在Program.cs中创建了一个Logger,因为我想记录服务的启动、停止/崩溃。

2
检查日志文件夹的文件权限,并确保服务运行的帐户可以写入该日志文件夹。 - dcp
2
你确定你在正确的文件夹中查找吗?你配置了Serilog使用相对路径。这是相对于运行进程的工作目录而不是二进制文件位置的路径。服务由svchost进程执行。你的日志很可能在System32中。最好使用基于配置设置的绝对路径。 - Panagiotis Kanavos
一个服务默认使用没有环境变量的系统账户。使用一个有环境的用户账户(或服务账户)启动服务。 - jdweng
如前所述,在服务中检查权限(将其更改为以管理员用户身份登录进行测试),您是否也尝试将.UseWindowsService()移动到.Build()之前?我通常会尽可能将其放在链的最后,但这只是我的个人偏好。 - Netferret
@PanagiotisKanavos 是的,我的日志文件最终都要在System32中结束!我现在已经向appSettings添加了一个设置,只是遗憾我看不到如何在program.cs中实现启动和停止的日志记录。 - GordonS
2个回答

2

正如其他人所指出的那样,服务运行时的工作目录与进程位置不同。我喜欢使用的一个老技巧是将工作目录设置为进程的二进制目录:

(参考链接)
Environment.CurrentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

0
在我的情况下,我只需将 Deployment mode 更改为 Self-Contained,并选择 Produce single file。虽然它会创建一个大文件,但现在编译器会将所有依赖的库嵌入一个单独的文件中。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接