简体   繁体   English

在 ASP.NET Core 2.2 中使用 InProcess 托管模型时,Serilog 不会将日志写入文件

[英]Serilog does not write log to file while using InProcess hosting model in ASP.NET Core 2.2

If I use newly introduced InProcess hosting model in ASP.NET Core 2.2 as follows:如果我在ASP.NET Core 2.2使用新引入的InProcess托管模型,如下所示:

<PropertyGroup>
  <TargetFramework>netcoreapp2.2</TargetFramework>
  <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>

Serilog does not write log to file. Serilog不会将日志写入文件。 but if I remove <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> from .csproj everything works as expected.但是如果我从.csproj删除<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>一切正常。

My Serilog configuration in the Program class as follows:我在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 
}

Any thought from the expert please!请高手给点意见!

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.正如对您的问题本身的评论所建议的那样,使用InProcess托管模型运行时,应用程序的当前目录与OutOfProcess托管模型不同。 For InProcess , this directory is the location of IIS itself - eg 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).对于InProcess ,此目录是 IIS 本身的位置 - 例如C:\\Program Files\\IIS Express ,这意味着您的日志文件正在写入C:\\Program Files\\IIS Express\\Logs\\log-.txt (假设相关权限设置)。

A workaround for this is detailed in this GitHub issue , which provides a helper class ( CurrentDirectoryHelpers ) for setting the correct current directory.此 GitHub 问题 中详细介绍了此问题的解决方法,它提供了一个帮助程序类 ( CurrentDirectoryHelpers ) 以设置正确的当前目录。 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. SetCurrentDirectory静态方法使用 PInvoke,确定应用程序是否在 IIS 内运行,如果是,则根据完整的应用程序路径设置当前目录。 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();

        ...
    }
}

Here's CurrentDirectoryHelpers for completeness:这是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
            }
        }
    }
}

Try to upgrade .Net Core version.尝试升级 .Net Core 版本。 This issue seems to be fixed in 2.2.3 .这个问题似乎在 2.2.3 中得到修复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM