调用 UseWindowsService 时未创建日志文件
No log file created when calling UseWindowsService
我按照 Serilog instructions 向我的应用程序添加了一个非常基本的日志文件。
我可以通过以下方式重现它:
- 使用默认参数 Visual Studio 创建了一个新的
ASP.NET Core Web Api
:.NET 5,无身份验证,为 HTTPS 配置,启用 OpenAPI 支持
- 安装了
Serilog.AspNetCore
包
- 安装了
Microsoft.Extensions.Hosting.WindowsServices
包(所以我可以调用 UseWindowsService()
扩展方法)
- 编辑我的
Program.cs
class 如下:
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 中删除了日志记录部分:
{
"AllowedHosts": "*"
}
到目前为止,当我从 Visual Studio 或 windows 资源管理器 运行 网络 api 时,一切正常:文件 logs.txt
已创建正如预期的那样,网络 api 还活着。
但是,当我为 运行 应用程序创建 windows 服务时:
sc.exe create TestService binPath="path\to\WebApplication1.exe"
尽管网络 api 运行 很好,但没有创建日志文件。
以下是我尝试过的一些方法:
- 更改了用户 运行使用我自己的帐户使用服务 => 没有变化
- 删除了对
UseWindowsService()
的调用 => 网络 api 没有启动
- 使用了另一个提供程序 (NLog) => 相同的行为:没有创建日志文件
- 在
UseWindowsService()
和 UseSerilog()
之间切换调用 => 无变化
- 在
ConfigureWebHostDefaults()
之后调用 UseWindowsService()
和 UseSerilog()
(按顺序排列)=> 无变化
我做错了什么?可能整个 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
我按照 Serilog instructions 向我的应用程序添加了一个非常基本的日志文件。
我可以通过以下方式重现它:
- 使用默认参数 Visual Studio 创建了一个新的
ASP.NET Core Web Api
:.NET 5,无身份验证,为 HTTPS 配置,启用 OpenAPI 支持 - 安装了
Serilog.AspNetCore
包 - 安装了
Microsoft.Extensions.Hosting.WindowsServices
包(所以我可以调用UseWindowsService()
扩展方法) - 编辑我的
Program.cs
class 如下:
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 中删除了日志记录部分:
{
"AllowedHosts": "*"
}
到目前为止,当我从 Visual Studio 或 windows 资源管理器 运行 网络 api 时,一切正常:文件 logs.txt
已创建正如预期的那样,网络 api 还活着。
但是,当我为 运行 应用程序创建 windows 服务时:
sc.exe create TestService binPath="path\to\WebApplication1.exe"
尽管网络 api 运行 很好,但没有创建日志文件。
以下是我尝试过的一些方法:
- 更改了用户 运行使用我自己的帐户使用服务 => 没有变化
- 删除了对
UseWindowsService()
的调用 => 网络 api 没有启动 - 使用了另一个提供程序 (NLog) => 相同的行为:没有创建日志文件
- 在
UseWindowsService()
和UseSerilog()
之间切换调用 => 无变化 - 在
ConfigureWebHostDefaults()
之后调用UseWindowsService()
和UseSerilog()
(按顺序排列)=> 无变化
我做错了什么?可能整个 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