aspnetcore进程内托管的坑-非常规方法解决Log4Net不写日志的问题
问题描述:Log4Net,本地测试一切正常,发布后,无法自动创建文件夹和日志文件,无法写入文件。
一、在项目中配置Log4Net
请参考我的上一篇博客 《aspnetcore配置log4net并添加全局异常处理》,常规做法。
二、Log4Net不写日志常规解决步骤
一般讲来,Log4Net是非常成熟的框架,很难出现问题,出现不写日志这种情况,首先要做的是检查我们的代码、配置是否正确。
- 检查目录中是否包含 log4net.config ,如果文件不存在,手动复制一份即可。
- 检查 log4net.config 文件,主要是日志文件输出路径,一般日志保存目录是这样的 根目录/Logs/Errors/xxxx.log ,其他资料里一般写法为 <file value="Logs\\Errors\\" /> ,在这里个人推荐这样来写 <file value="Logs/Errors/" /> ,原因是曾经在 ubuntu > nginx 环境下部署时,第一种写法无法正常工作,改为第二种方法后正常。
- 检查文件夹权限,确保具有写权限。
三、绝望的排查过程
因为在本地测试完全正常,所以代码和配置文件应该没有问题,但保险起见,还是将网上常用的几种写法都尝试了一遍,然而,并没有什么卵用。
接下来,查看文件夹权限,讲真,对于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不写日志的问题的更多相关文章
- 一个不需要Log4Net的写日志的简单方法
有些项目写日志时会选择大名鼎鼎的Log4Net.而在我们使用它时,总会出现一些诸如版本不匹配而造成的写日志失败的情况,还要改web.config,还要改AssemblyInfo.而且,它的失败,并不是 ...
- [06]ASP.NET Core中的进程内(InProcess)托管
ASP.NET Core 进程内(InProcess)托管 本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP) 文章会随着版本进行更新,关注我获取最新版本 本文出自<从零开始学 ...
- ASP.NET Core 进程内(InProcess)托管
ASP.NET Core 进程内(InProcess)托管 在 ASP.NET Core 中的进程内(InProcess)托管模型 什么是 Kestrel 服务器 当一个 ASP.NET Core 应 ...
- netcore进程内(InProcess)托管和进程外(out-of-Process)托管
当一个 ASP.NET Core 应用程序执行的时候,.NET 运行时会去查找 Main()方法,因为它是这个应用程序的起点. 然后,Main()方法调用静态类WebHost中的静态方法CreateD ...
- ASP.NET Core 进程内与进程外的性能对比
ASP.NET Core 进程内与进程外的性能对比 本文内容是<深入去浅出ASP.NET Core>提供的扩展内容,毕竟在书里说进程内外的性能说明对比,对于初学者而言,稍微复杂了点. 我在 ...
- 在VC6.0下如何调用Delphi5.0开发的进程内COM
因为本人的语言水平很差,考大学时150的总分,我考了个60分.外语也是,初中及格过一次,会考及格过一次.其它的时间好像从没有及格过.所以我不写文章,因我一百字的文章给我写,至少要出八九个错别字.哈哈… ...
- 【转载】进程内COM与进程外COM
原文:http://www.cnblogs.com/jyz/archive/2009/03/08/1406229.html 1.进程内和进程外Com COM/DCOM 组件可以在DLL 或EXE 文档 ...
- COM/DCOM开发练习之进程内组件实例
作者 : 卿笃军 题目说明: 仿照例题,在其基础上实现下面功能: 1)使用C++语言实现进程内组件,组件提供复数的加.减.乘.除等计算服务:client部分包含录入(实部和虚部分开录入)和查询部分. ...
- 进程内COM与进程外COM
1.进程内和进程外Com COM/DCOM 组件可以在DLL 或EXE 文档中实现. 其中在 DLL 中实现的COM/DCOM组件称为 In-Process Server,因为这些组件是加载到使用它们 ...
随机推荐
- How to manage concurrency in Django models
How to manage concurrency in Django models The days of desktop systems serving single users are long ...
- 通过Jquery异步获取股票实时数据
最近朋友让我帮他做个异步获取数据的程序,暂时服务器什么都没有,所以我就想先拿股票数据打个框架,方便后续开发和移植等事情 代码如下: <!-- 说明:股票看盘 作者:黑桃A 时间:2014-04- ...
- IPC的使用
IPC,Inter-Processor Communication是SYS/BIOS处理核间通信的组件: IPC的几种应用方式: 1.最小使用(Minimal use) 这种情况是通过核间的通知机制( ...
- CRT Library Features
CRT Library Features The new home for Visual Studio documentation is Visual Studio 2017 Documentatio ...
- altium designer 中的top/bottom solder和top/bottom paste mask
转载请注明出处:http://blog.csdn.net/qq_26093511/article/details/51751936 1.top solder为助焊层,说白一点就是说,有这个层的地方就没 ...
- GIF助手激活教程(购买+激活)图文版
GIF助手首页==>设置(右上角) ==>输入激活码会弹出购买或者激活的对话框.(如果不明白操作,可以点击如何购买激活码先查看购买帮助指南再进行购买) 点击复制设备码并购买. 此时会进入到 ...
- Java探索之旅(17)——多线程(1)
1.多线程 1.1线程 线程是程序运行的基本执行单元.指的是一段相对独立的代码,执行指定的计算或操作.多操作系统执行一个程序时会在系统中建立一个进程,而在这个进程中,必须至少建立一个线程(这个线程被 ...
- Centos 7安装与配置chef
背景:随着DevOps 逐渐流行起来,越来越多的工作需要自动化处理,而chef就是其中一款能实现自动化管理的工具,掌握类似chef这样的自动化工具,相信会使你在未来的竞争中更具优势. 俗话说“好记性不 ...
- Dialog 自定义使用1
一: 布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andr ...
- (转)64位系统安装Delphi7提示Can’t load package:dclite70.bpl 以及 提示地址错误
第一个问题: 今天在64的Win7上安装Delphi7,在启动时候出现如下提示: Can't load package:dclite70.bpl 告诉大家一个解决办法,就是给Delphi32.exe去 ...