问题描述: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. 汇编题目:在DOS下,按F1键后改变当前屏幕的显示颜色

    我们都知道int9中断是键盘的按键中断程序,按下键盘触发int9中断,不懂int9中断的请自己去百度查查说明和用法 利用中断任务安装一个新的int 9中断例程,功能:在DOS下,按F1键后改变当前屏幕 ...

  2. POJ1456:Supermarket

    浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html 题目传送门:http://poj.org/problem?id=1456 把物品按照时间排序,显然\ ...

  3. System.getProperty()获取系统的相关属性

    我们在编程的过程中有时候需要获取系统的相关属性,今天就让我们一起来学习学习如何获取系统的相关属性 至于System.getProperty(param)中的各个参数的概念请看下表. java.vers ...

  4. Guice 学习

    Guice: 是一个轻量级的DI框架. 不需要繁琐的配置,只需要定义一个Module来表述接口和实现类,以及父类和子类之间的关联关系的绑定,如下是一个例子. http://blog.csdn.net/ ...

  5. 针对nginx的内核优化

    关于内核参数的优化: net.ipv4.tcp_max_tw_buckets = 6000timewait的数量,默认是180000.net.ipv4.ip_local_port_range = 10 ...

  6. 菜鸟学Nhibernate 之路---(1)

    首先说一下我为什么要学这个Nhibernate,现在在公司做项目后台的逻辑层都是用动软生成的简单三层,搞来搞去都是这些东西,代码冗余量很大,每个类方法基本上都一样,真是纯正的码农,虽然后来我也尝试使用 ...

  7. Java进阶之美文共享

    2.在Java中如何避免"!=null"式的判空语句?  3.Java问答:终极父类(3)  Java问答:终极父类(下) Java问答:终极父类(上) 内存不足:杀死进程还是牺牲 ...

  8. [HDU1754]I Hate It线段树裸题

    http://acm.hdu.edu.cn/showproblem.php?pid=1754 解题关键:刚开始死活超时,最后发现竟然是ch,和t1.t2每次循环都定义的锅,以后养成建全局变量的习惯. ...

  9. R: 数据结构、数据类型的描述。

    ################################################### 问题:数据结构..类型  18.4.27 有哪些数据结构.类型??  各自有什么特点? 解决方案 ...

  10. 32、Differential Gene Expression using RNA-Seq (Workflow)

    转载: https://github.com/twbattaglia/RNAseq-workflow Introduction RNAseq is becoming the one of the mo ...