我有一小组ServiceStack REST服务,它使用NLog 2.1(来自NuGet)进行日志记录。
我的测试服务器正在运行:
<nlog throwExceptions="true" internalLogToConsole="true" internalLogLevel="Debug" xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <targets> <target name="c" xsi:type="Console" /> <target name="f1" xsi:type="File" fileName="C:\logs\test.log" /> </targets> <rules> <logger name="*" writeTo="c,f1" /> </rules> </nlog>
我的NLog配置非常简单......只是想让它工作...... 在这种配置中,一切正常。 NLog正确创建日志文件。
在我的开发机器上,我正在使用:
这是我的Application_Start ...
protected void Application_Start() {
LogManager.LogFactory = new NLogFactory();
ILog log = LogManager.GetLogger(typeof(Global));
log.Info("Application_Start called");
try {
new AppHost().Init();
} catch (Exception e) {
log.Error("Exception caught initializing AppHost");
}
}
在此配置中,我的服务的AppHost()。Init()抛出异常,因为ServiceStack正在ServiceController.cs中注册我的服务。我相信这部分是无关紧要的,除了它是第一次在Application_Start之外记录某些东西(因为Application_Start中的两个调用都工作了......在异常之前的log.info 和log.error) 在例外之后)。
以下是显示的异常:
最相关的一点是在NLog.Internal.FileAppenders.BaseFileAppender.WindowsCreateFile(System.String fileName,Boolean allowConcurrentWrite)中抛出了 System.NotImplementedException 。
我找到了一个解决方法(在下面接受的答案中)。希望遇到此问题的其他任何人都能很快找到解决方案。
答案 0 :(得分:2)
Google上的一些搜索让我看到了这个NLog拉取请求:
<强> Avoid Win32-specific file functions in Mono where parts not implemented. 强>
似乎此更改尝试使用预处理器来完全不调用WindowsCreateFile。但是,出于某种原因,这仍然会执行。
然后我去检查NLog GitHub存储库中最新版本的BaseFileAppender.cs,以确保有人在稍后的某个时间点没有再次破坏它。
#if !NET_CF && !SILVERLIGHT && !MONO
try
{
if (!this.CreateFileParameters.ForceManaged && PlatformDetector.IsDesktopWin32)
{
return this.WindowsCreateFile(this.FileName, allowConcurrentWrite);
}
}
catch (SecurityException)
{
InternalLogger.Debug("Could not use native Windows create file, falling back to managed filestream");
}
#endif
嗯......它还在那里。是什么赋予了?为什么MONO似乎不是由预处理器定义的,因此允许执行该块?我不确定。在我开始调查之前,我注意到了另一个变化......
if (!this.CreateFileParameters.ForceManaged && ...
因此,在跟踪了ForceManaged布尔回到它原点的跟踪之后,似乎我可以在我的NLog配置中的FileTarget声明上设置 forceManaged =“true”。难道真的那么简单吗?!
<nlog throwExceptions="true" internalLogToConsole="true" internalLogLevel="Debug" xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <targets> <target name="c" xsi:type="Console" /> <target name="f1" xsi:type="File" forceManaged="true" fileName="C:\logs\test.log" /> </targets> <rules> <logger name="*" writeTo="c,f1" /> </rules> </nlog>
一旦做出改变,一切正常......跳过了抛出异常的WindowsCreateFile调用&amp;使用了托管文件流,效果很好。哈利路亚!
最后,我无法在任何地方找到NLog文档中的forceManaged标志。如果是的话,很可能会很快找到这个解决方案。