【问题标题】:Serilog does not write log to file while using InProcess hosting model in ASP.NET Core 2.2在 ASP.NET Core 2.2 中使用 InProcess 托管模型时,Serilog 不会将日志写入文件
【发布时间】:2019-05-19 15:45:06
【问题描述】:

如果我在ASP.NET Core 2.2中使用新引入的InProcess托管模型如下:

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

Serilog 不将日志写入文件。但如果我从.csproj 中删除&lt;AspNetCoreHostingModel&gt;InProcess&lt;/AspNetCoreHostingModel&gt;,一切都会按预期进行。

我在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 
}

请高手给点意见!

【问题讨论】:

  • 请记住,托管进程的默认目录与自托管进程不同。所以您可能需要在启动期间设置它或使用绝对路径(通过 appsettings.json、环境变量等)

标签: c# asp.net-core serilog asp.net-core-2.2


【解决方案1】:

正如您问题本身的 cmets 中所建议的,当使用 InProcess 托管模型运行时,应用程序的当前目录与 OutOfProcess 托管模型不同。对于InProcess,此目录是 IIS 本身的位置 - 例如C:\Program Files\IIS Express,表示你的日志文件正在写入C:\Program Files\IIS Express\Logs\log-.txt(假设设置了相关权限)。

this GitHub issue 中详细介绍了解决此问题的方法,它提供了一个帮助程序类 (CurrentDirectoryHelpers) 用于设置正确的当前目录。 SetCurrentDirectory 静态方法使用 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
            }
        }
    }
}

【讨论】:

    【解决方案2】:

    尝试升级 .Net Core 版本。这个问题似乎在 2.2.3 中得到修复。

    【讨论】:

      猜你喜欢
      • 2018-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多