servicestack,nlog,Mono,servicestack,Nlog" /> servicestack,nlog,Mono,servicestack,Nlog" />

NLog无法在使用Mono的Windows上打开文件

NLog无法在使用Mono的Windows上打开文件,mono,servicestack,nlog,Mono,servicestack,Nlog,我有一小组ServiceStack REST服务,它使用NLog 2.1(来自NuGet)进行日志记录 我的测试服务器正在运行: 视窗7 IIS 7.5 .NET 4.5 NLog配置: 在此配置中,我的服务的AppHost().Init()在ServiceStack在ServiceController.cs中注册我的服务时引发异常。我认为这一部分是不相关的,除了它是第一次在Application_Start之外记录某些内容(因为Application_Start中的两个调用都有效…异常前的

我有一小组ServiceStack REST服务,它使用NLog 2.1(来自NuGet)进行日志记录

我的测试服务器正在运行:

  • 视窗7
  • IIS 7.5
  • .NET 4.5
  • NLog配置:
在此配置中,我的服务的AppHost().Init()在ServiceStack在ServiceController.cs中注册我的服务时引发异常。我认为这一部分是不相关的,除了它是第一次在Application_Start之外记录某些内容(因为Application_Start中的两个调用都有效…异常前的log.info和异常后的log.error)

以下是显示的例外情况:

最相关的一点是在NLog.Internal.FileAppenders.BaseFileAppender.WindowsCreateFile(System.String文件名,布尔allowConcurrentWrite)处抛出了一个System.NotImplementedException


我已经找到了一个解决办法(在下面接受的答案中)。希望遇到这种情况的任何其他人都能很快找到这种解决方案。

在谷歌上进行的一些挖掘让我找到了这个NLog pull请求:

此更改似乎试图使用预处理器根本不调用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的调用&使用了托管文件流,效果非常好。哈利路亚


最后,我在NLog文档中的任何地方都找不到forceManaged标志。如果是的话,很可能会很快找到这个解决方案。

太好了,但是如果你使用Mono,你应该避免完全使用Windows,因为它在Windows上的功能越来越少,越来越差(Mono的目的是在Windows之外运行.NET)当然,当然。但测试和生产服务器是Windows还是Linux尚未做出最终决定。我无法控制开发机器上的操作系统,除非我想在虚拟机上运行其他东西。除此之外,我遇到的另一个问题是。最近在这方面有了一些改进,我建议您使用mono master进行测试
if (!this.CreateFileParameters.ForceManaged && ...
<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>