新しく導入されたInProcess
ホスティングモデルをASP.NET Core 2.2
で次のように使用する場合:
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
Serilog
はログをファイルに書き込みません。しかし、<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
から.csproj
を削除すると、すべてが期待どおりに機能します。
Serilog
クラスのProgram
構成は次のとおりです。
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
に書き込まれていることを意味します(関連する権限が設定されていること)。
この回避策については、 このGitHubの問題 で詳しく説明されています。これは、正しい現在のディレクトリを設定するためのヘルパークラス( CurrentDirectoryHelpers
)を提供します。 SetCurrentDirectory
staticメソッドはPInvokeを使用して、アプリケーションがIIS内から実行されているかどうかを判断し、実行されている場合は、完全なアプリケーションパスに従って現在のディレクトリを設定します。このアプローチは次のようになります。
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
}
}
}
}
.NetCoreバージョンをアップグレードしてみてください。この問題は2.2.3で修正されたようです。