问题描述:Log4Net,本地测试一切正常,发布后,无法自动创建文件夹和日志文件,无法写入文件。

一、在项目中配置Log4Net

请参考我的上一篇博客 《aspnetcore配置log4net并添加全局异常处理》,常规做法。

二、Log4Net不写日志常规解决步骤

一般讲来,Log4Net是非常成熟的框架,很难出现问题,出现不写日志这种情况,首先要做的是检查我们的代码、配置是否正确。

  1. 检查目录中是否包含 log4net.config ,如果文件不存在,手动复制一份即可。
  2. 检查  log4net.config 文件,主要是日志文件输出路径,一般日志保存目录是这样的  根目录/Logs/Errors/xxxx.log ,其他资料里一般写法为  <file value="Logs\\Errors\\" /> ,在这里个人推荐这样来写  <file value="Logs/Errors/" /> ,原因是曾经在  ubuntu > nginx  环境下部署时,第一种写法无法正常工作,改为第二种方法后正常。
  3. 检查文件夹权限,确保具有写权限。

三、绝望的排查过程

因为在本地测试完全正常,所以代码和配置文件应该没有问题,但保险起见,还是将网上常用的几种写法都尝试了一遍,然而,并没有什么卵用。

接下来,查看文件夹权限,讲真,对于Server的文件系统我是真的了解很少,大部分时间遇到权限问题,就简单的给Everyone一个读写权限了事。不出意外的,折腾许久,还是失败了。

重复以上步骤两个小时后...

头昏脑涨中,想起之前的项目中使用Log4Net是正常的,写法和部署方式一样,为什么这次不行呢?

于是对比之前的项目,把IIS中站点和应用程序池的配置项一条一条拿出来看,一个小时后...

完全一样啊,啥情况,要不换NLog???虽然为了项目进度换成其他框架也说的过去,但作为程序员,明知道有bug却解决不了,总归过不去心里这一关不是。不甘心啊~

四、灵光乍现

就在准备把问题先放放,修改项目使用Nlog的时候,鬼使神差的,去看了眼任务管理器,咦~~还真发现了问题,之前的项目都是开了三个进程(w3wp.exe \ conhost.exe \ dotnet.exe),而新项目只有两个(w3wp.exe \ conhost.exe),精神立马振奋了一下,看来问题可能就在这里了。打开项目的  web.config  文件,发现多了点东西:

有问题找度娘,搜索 InProcess ,大部分内容都一样,没看出啥问题,难道是我想错了,问题不在这里?说脏话会不会发布失败?咱也不知道咱也不敢问,还是憋回去吧!

抱着最后一丝希望,跑到官方文档 《ASP.NET Core 模块》,不得不说啊,微软自动翻译的文档真的很考验中文水平,但是再烂也得看不是,这块内容之前也没说关注过,不管能不能解决问题,看看也好,当补课了。

细细看下来,有这么一段

在 ASP.NET Core 2.2.1 或早期版本中,GetCurrentDirectory 会返回 IIS 启动的进程的工作目录而非应用目录(例如,对于 w3wp.exe,是 C:\Windows\System32\inetsrv)。

对于设置应用的当前目录的示例代码,请参阅 CurrentDirectoryHelpers 类。 调用 SetCurrentDirectory 方法。 后续 GetCurrentDirectory 调用提供应用的目录。

醍醐灌顶,虽然外面已经是傍晚时分,但我眼前仿佛一道曙光升起,恍惚间似乎看到天女降临,嘿,嘿嘿~~

五、填坑

接下来就简单了,github上把CurrentDirectoryHelpers类搞下来,在  startup.cs  的构造函数中添加  CurrentDirectoryHelpers.SetCurrentDirectory(); ,重新发布、部署、启动站点,文件出现了。

下面贴一下  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) != )
{
return;
} sitePhysicalPath = configurationData.pwzFullApplicationPath;
} Environment.CurrentDirectory = sitePhysicalPath;
}
catch
{
// ignore
}
}
}
}

aspnetcore进程内托管的坑-非常规方法解决Log4Net不写日志的问题的更多相关文章

  1. 一个不需要Log4Net的写日志的简单方法

    有些项目写日志时会选择大名鼎鼎的Log4Net.而在我们使用它时,总会出现一些诸如版本不匹配而造成的写日志失败的情况,还要改web.config,还要改AssemblyInfo.而且,它的失败,并不是 ...

  2. [06]ASP.NET Core中的进程内(InProcess)托管

    ASP.NET Core 进程内(InProcess)托管 本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP) 文章会随着版本进行更新,关注我获取最新版本 本文出自<从零开始学 ...

  3. ASP.NET Core 进程内(InProcess)托管

    ASP.NET Core 进程内(InProcess)托管 在 ASP.NET Core 中的进程内(InProcess)托管模型 什么是 Kestrel 服务器 当一个 ASP.NET Core 应 ...

  4. netcore进程内(InProcess)托管和进程外(out-of-Process)托管

    当一个 ASP.NET Core 应用程序执行的时候,.NET 运行时会去查找 Main()方法,因为它是这个应用程序的起点. 然后,Main()方法调用静态类WebHost中的静态方法CreateD ...

  5. ASP.NET Core 进程内与进程外的性能对比

    ASP.NET Core 进程内与进程外的性能对比 本文内容是<深入去浅出ASP.NET Core>提供的扩展内容,毕竟在书里说进程内外的性能说明对比,对于初学者而言,稍微复杂了点. 我在 ...

  6. 在VC6.0下如何调用Delphi5.0开发的进程内COM

    因为本人的语言水平很差,考大学时150的总分,我考了个60分.外语也是,初中及格过一次,会考及格过一次.其它的时间好像从没有及格过.所以我不写文章,因我一百字的文章给我写,至少要出八九个错别字.哈哈… ...

  7. 【转载】进程内COM与进程外COM

    原文:http://www.cnblogs.com/jyz/archive/2009/03/08/1406229.html 1.进程内和进程外Com COM/DCOM 组件可以在DLL 或EXE 文档 ...

  8. COM/DCOM开发练习之进程内组件实例

    作者 : 卿笃军 题目说明: 仿照例题,在其基础上实现下面功能: 1)使用C++语言实现进程内组件,组件提供复数的加.减.乘.除等计算服务:client部分包含录入(实部和虚部分开录入)和查询部分. ...

  9. 进程内COM与进程外COM

    1.进程内和进程外Com COM/DCOM 组件可以在DLL 或EXE 文档中实现. 其中在 DLL 中实现的COM/DCOM组件称为 In-Process Server,因为这些组件是加载到使用它们 ...

随机推荐

  1. How to manage concurrency in Django models

    How to manage concurrency in Django models The days of desktop systems serving single users are long ...

  2. 通过Jquery异步获取股票实时数据

    最近朋友让我帮他做个异步获取数据的程序,暂时服务器什么都没有,所以我就想先拿股票数据打个框架,方便后续开发和移植等事情 代码如下: <!-- 说明:股票看盘 作者:黑桃A 时间:2014-04- ...

  3. IPC的使用

    IPC,Inter-Processor Communication是SYS/BIOS处理核间通信的组件: IPC的几种应用方式: 1.最小使用(Minimal use) 这种情况是通过核间的通知机制( ...

  4. CRT Library Features

    CRT Library Features The new home for Visual Studio documentation is Visual Studio 2017 Documentatio ...

  5. altium designer 中的top/bottom solder和top/bottom paste mask

    转载请注明出处:http://blog.csdn.net/qq_26093511/article/details/51751936 1.top solder为助焊层,说白一点就是说,有这个层的地方就没 ...

  6. GIF助手激活教程(购买+激活)图文版

    GIF助手首页==>设置(右上角) ==>输入激活码会弹出购买或者激活的对话框.(如果不明白操作,可以点击如何购买激活码先查看购买帮助指南再进行购买) 点击复制设备码并购买. 此时会进入到 ...

  7. Java探索之旅(17)——多线程(1)

    1.多线程  1.1线程 线程是程序运行的基本执行单元.指的是一段相对独立的代码,执行指定的计算或操作.多操作系统执行一个程序时会在系统中建立一个进程,而在这个进程中,必须至少建立一个线程(这个线程被 ...

  8. Centos 7安装与配置chef

    背景:随着DevOps 逐渐流行起来,越来越多的工作需要自动化处理,而chef就是其中一款能实现自动化管理的工具,掌握类似chef这样的自动化工具,相信会使你在未来的竞争中更具优势. 俗话说“好记性不 ...

  9. Dialog 自定义使用1

    一: 布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andr ...

  10. (转)64位系统安装Delphi7提示Can’t load package:dclite70.bpl 以及 提示地址错误

    第一个问题: 今天在64的Win7上安装Delphi7,在启动时候出现如下提示: Can't load package:dclite70.bpl 告诉大家一个解决办法,就是给Delphi32.exe去 ...