问题描述
如果我在ASP.NET Core 2.2
中使用新引入的InProcess
托管模型,如下所示:
If I use newly introduced InProcess
hosting model in ASP.NET Core 2.2
as follows:
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
Serilog
不会将日志写入文件.但是如果我从.csproj
中删除<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
,一切都会按预期进行.
Serilog
does not write log to file. but if I remove <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
from .csproj
everything works as expected.
我在Program
类中的Serilog
配置如下:
public class Program
{
public static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information() // Set the minimun log level
.WriteTo.File("Logs\\log-.txt", rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7) // this is for logging into file system
.CreateLogger();
try
{
Log.Information("Starting web host");
CreateWebHostBuilder(args).Build().Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logging => { logging.ClearProviders(); }) // clearing all other logging providers
.UseSerilog(); // Using serilog
}
请专家提出任何想法!
推荐答案
如对问题本身的注释中所建议,在使用InProcess
托管模型运行时,该应用程序的当前目录与OutOfProcess
不同托管模式.对于InProcess
,此目录是IIS本身的位置-例如, C:\Program Files\IIS Express
,这意味着您的日志文件正在写入C:\Program Files\IIS Express\Logs\log-.txt
(假设已设置相关权限).
As suggested in the comments on your question itself, when running using the InProcess
hosting model, the current directory for the application is different to the OutOfProcess
hosting model. For InProcess
, this directory is the location of IIS itself - e.g. C:\Program Files\IIS Express
, which means that your log files are being written to C:\Program Files\IIS Express\Logs\log-.txt
(assuming that the relevant permissions are set).
有关此问题的解决方法,请参见此GitHub问题,其中提供了帮助程序类( CurrentDirectoryHelpers
)来设置正确的当前目录. SetCurrentDirectory
静态方法使用PInvoke,确定应用程序是否从IIS中运行,如果是,它将根据完整的应用程序路径设置当前目录.使用这种方法看起来像这样:
A workaround for this is detailed in this GitHub issue, which provides a helper class (CurrentDirectoryHelpers
) for setting the correct current directory. The SetCurrentDirectory
static method uses PInvoke, determining whether or not the application is running from within IIS and if it is, it sets the current directory according to the full application path. Using this approach looks like this:
public class Program
{
public static void Main(string[] args)
{
CurrentDirectoryHelpers.SetCurrentDirectory();
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information() // Set the minimun log level
.WriteTo.File("Logs\\log-.txt", rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7) // this is for logging into file system
.CreateLogger();
...
}
}
为完整起见,这里的CurrentDirectoryHelpers
:
using System;
namespace SampleApp
{
internal class CurrentDirectoryHelpers
{
internal const string AspNetCoreModuleDll = "aspnetcorev2_inprocess.dll";
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[System.Runtime.InteropServices.DllImport(AspNetCoreModuleDll)]
private static extern int http_get_application_properties(ref IISConfigurationData iiConfigData);
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
private struct IISConfigurationData
{
public IntPtr pNativeApplication;
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.BStr)]
public string pwzFullApplicationPath;
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.BStr)]
public string pwzVirtualApplicationPath;
public bool fWindowsAuthEnabled;
public bool fBasicAuthEnabled;
public bool fAnonymousAuthEnable;
}
public static void SetCurrentDirectory()
{
try
{
// Check if physical path was provided by ANCM
var sitePhysicalPath = Environment.GetEnvironmentVariable("ASPNETCORE_IIS_PHYSICAL_PATH");
if (string.IsNullOrEmpty(sitePhysicalPath))
{
// Skip if not running ANCM InProcess
if (GetModuleHandle(AspNetCoreModuleDll) == IntPtr.Zero)
{
return;
}
IISConfigurationData configurationData = default(IISConfigurationData);
if (http_get_application_properties(ref configurationData) != 0)
{
return;
}
sitePhysicalPath = configurationData.pwzFullApplicationPath;
}
Environment.CurrentDirectory = sitePhysicalPath;
}
catch
{
// ignore
}
}
}
}
这篇关于在ASP.NET Core 2.2中使用InProcess托管模型时,Serilog不会将日志写入文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!