在Visual Studio中使用NLog和F#Interactive - 需要文档

时间:2013-02-02 02:20:18

标签: f# nlog f#-interactive

使用F#Interactive时,我需要捕获F#函数的输入和输出。当程序在Visual Studio下使用F5或Ctrl-F5运行时,我能够让NLog正常工作。包含输出到日志的语句的相同方法也可以正常工作,并在通过F#Interactive调用时调用;日志文件中没有任何内容。

我还尝试使用F#Interactive来设置对NLog的引用,当从F#Interactive运行时,日志中仍然没有任何内容。

#I @"..\packages\NLog.2.0.0.2000\lib\net40" 
#r @"NLog.dll"

我甚至发现this让我尝试了这些

NLog.Config.SimpleConfigurator.ConfigureForConsoleLogging()
NLog.Config.SimpleConfigurator.ConfigureForFileLogging(<full file name>)

并且日志文件中仍然没有任何内容。

任何人都知道Nlog是否可以与F#Interactive一起使用?
如果是这样,它是如何完成的?

修改

当单独运行时,我能够让NLog与fsi.exe一起使用。所以现在问题似乎是让NLog找到配置文件,因为NLog无法从Visual Studio的fsi.exe位置找到配置文件。看看在NLog.dll目录中使用NLog.dll.nlog。

1 个答案:

答案 0 :(得分:11)

问题

使用F#Interactive的NLog的问题是NLog认为Temp目录在哪里找NLog.config并且从不成功。解决这个问题的方法是以编程方式为NLog找到NLog.config

要解决这个问题的事情:

  1. 从Visual Studio中运行F#Interactive时,它会将当前工作目录设置为临时文件。

    > System.Environment.CurrentDirectory;; 
    val it : string = "C:\Users\Eric\AppData\Local\Temp"
    
  2. NLog日志记录需要三个组件:
    一个。参考NLog.dll 湾配置文件 C。从代码调用记录器方法。

  3. 可以通过多种方式配置NLog,无论是以编程方式还是使用配置文件。
  4. AppData是一个隐藏文件夹。猜猜使用Windows资源管理器意味着什么。
  5. 要在Visual Studio中使用F#Interactive获取应用程序的位置,您需要__SOURCE_DIRECTORY__。请参阅F# Spec 3.11标识符替换
  6. NLog.conf可以使用完整的文件路径。显而易见但是必要。
  7. NLog file targets有一个autoFlush选项。
  8. NLog可以使用Visual Studio project安装到NuGet
  9. 此处的大部分信息来自NLog Wiki
  10. 不是直接进入F#Interactive解决方案,而是使用以下进程,因为需要创建DLL来设置和保存用于F#Interactive的NLog的函数。

    1. 创建一个包含三个项目的解决方案并安装NLog 解决方案名称:NLogExample
      项目1 - 库,名称:日志 - 保存调用NLog的扩展功能 项目2 - 库,名称:MyLibrary - 用于生成使用日志功能的演示DLL 项目3 - 控制台应用程序,名称:主要 - 用于生成使用日志功能的演示EXE。

    2. 一个。手动创建NLog.config
      湾从正在运行的项目中访问NLog.config C。将消息记录到文件

    3. 一个。以编程方式创建配置
      湾为正在运行的项目创建配置并将消息记录到文件

    4. 使用F#Interactive

    5. 创建配置并将消息记录到文件中

      1。创建包含三个项目的解决方案并安装NLog

      使用Visual Studio创建三个项目。

      enter image description here

      为所有三个项目安装NLog。

      enter image description here

      2.A。手动创建NLog.config

      注意:要使这些示例在从F#Interactive运行__SOURCE_DIRECTORY__;;时起作用,它应报告属于项目的目录和 NOT Temp目录。

      注意:此答案中的所有路径都与解决方案目录相关   当您在实际解决方案目录中看到<Solution directory>替换时。

      路径:<Solution director>\NLog.config

      <?xml version="1.0" encoding="utf-8" ?>
      <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            throwExceptions="true">
      
        <targets>
          <target xsi:type="File"
                  name="file"
                  fileName="<Solution directory>\log.txt"
                  autoFlush="true"
            />
          </targets>
      
        <rules>
          <logger name="*"
                  minlevel="Trace"
                  writeTo="file"
          />
        </rules>
      </nlog>
      

      注意:请务必将<Solution directory>更改为实际路径并设置autoFlush="true"

      注意:向解决方案添加NLog.config可以更轻松地查看/修改文件。

      enter image description here

      2.b中。从正在运行的项目中访问NLog.config

      在Log.Library1.fs

      namespace Log
      
      module MyLog =
      
          let configureNLog () =
            let projectPath = __SOURCE_DIRECTORY__
            let soulutionPath = projectPath + "\.."
            let configPath = soulutionPath + @"\NLog.config"
            let xmlConfig = new NLog.Config.XmlLoggingConfiguration(configPath)
            NLog.LogManager.Configuration <- xmlConfig
      
          let NLogConfigToString () = 
            let targets = NLog.LogManager.Configuration.AllTargets
            let out = ""
            let out = Seq.fold (fun out target -> out + (sprintf "%A\n" target)) out targets
            let rules = NLog.LogManager.Configuration.LoggingRules
            let out = Seq.fold (fun out rule -> out + (sprintf "%A\n" rule)) out rules
            out
      
          let printNLogConfig () = 
             Printf.printfn "%s" (NLogConfigToString ())
      

      并为Log项目添加对System.XML

      的引用

      在Main.Program.fs

      open Log
      
      [<EntryPoint>]
      let main argv = 
      
          MyLog.configureNLog ()
          MyLog.printNLogConfig ()
      
          0 // return an integer exit code
      

      并为Main项目添加对Log项目的引用,并将Main项目设置为启动项目。

      运行时,应输出到控制台:

      File Target[file]
      logNamePattern: (:All) levels: [ Trace Debug Info Warn Error Fatal ] appendTo: [ file ]
      

      2.C。将消息记录到文件

      在Log.Library1.fs

      namespace Log
      
      open NLog
      
      module MyLog =
      
          let configureNLog () =
            let projectPath = __SOURCE_DIRECTORY__
            let soulutionPath = projectPath + "\.."
            let configPath = soulutionPath + @"\NLog.config"
            let xmlConfig = new NLog.Config.XmlLoggingConfiguration(configPath)
            NLog.LogManager.Configuration <- xmlConfig
      
          let NLogConfigToString () = 
            let targets = NLog.LogManager.Configuration.AllTargets
            let out = ""
            let out = Seq.fold (fun out target -> out + (sprintf "%A\n" target)) out targets
            let rules = NLog.LogManager.Configuration.LoggingRules
            let out = Seq.fold (fun out rule -> out + (sprintf "%A\n" rule)) out rules
            out
      
          let printNLogConfig () = 
             Printf.printfn "%s" (NLogConfigToString ())
      
          let evalTracer = LogManager.GetLogger("file")
      

      在Main.Program.fs

      open Log
      open Library1
      
      [<EntryPoint>]
      
          let main argv = 
      
              MyLog.configureNLog ()
              MyLog.printNLogConfig ()
      
              // Add as many of these as needed
              MyLog.evalTracer.Trace("In Main @1.")
      
              MyFunctions.test001 ()
      
              0 // return an integer exit code
      

      并为Main项目添加对MyLibrary项目的引用。

      在MyLibrary.Library1.fs

      namespace Library1
      
      open Log
      
      module MyFunctions =
      
          let test001 () =
              MyLog.evalTracer.Trace("In Library @1.")
      

      并为MyLibrary项目添加对Log项目的引用。

      运行时,日志文件log.txt应包含类似于:

      的内容
      2016-03-28 11:03:52.4963|TRACE|file|In Main @1.
      2016-03-28 11:03:52.5263|TRACE|file|In Library @1
      

      3.A。以编程方式创建配置

      如果存在NLog.config文件,请将其删除以验证代码是否已创建新配置但未创建文件。

      要使用F#以编程方式设置配置,您需要知道:

      1. 此FileName字符串是一种布局,可能包含布局渲染器的实例。这允许您使用单个目标写入多个文件。
      2. SimpleLayout - 表示具有嵌入式占位符的字符串,可以呈现上下文信息。
      3. To Log.Library1.fs add

        let configureNLogPrgramatically () =
          let config = new NLog.Config.LoggingConfiguration()
          let fileTarget = new NLog.Targets.FileTarget()
          let projectPath = __SOURCE_DIRECTORY__
          let soulutionPath = projectPath + "\.."
          let filePath = soulutionPath + @"\log.txt"
          let layout = new NLog.Layouts.SimpleLayout(filePath)
          fileTarget.Name <- "file"
          fileTarget.FileName <- layout
          fileTarget.AutoFlush <- true
          config.AddTarget("file", fileTarget)
          let rule1 = new NLog.Config.LoggingRule("*",NLog.LogLevel.Trace,fileTarget)
          config.LoggingRules.Add(rule1)
          NLog.LogManager.Configuration <- config
        

        3.B。为正在运行的项目创建配置并将消息记录到文件

        在Main.Program.fs

        open Log
        open Library1
        
        [<EntryPoint>]
        
            let main argv = 
        
                MyLog.configureNLogPrgramatically ()
                MyLog.printNLogConfig ()
        
                // Add as many of these as needed
                MyLog.evalTracer.Trace("In Main @1.")
        
                MyFunctions.test001 ()
        
                0 // return an integer exit code
        

        运行时,日志文件log.txt应包含类似于:

        的内容
        2016-03-28 11:16:07.2901|TRACE|file|In Main @1.
        2016-03-28 11:16:07.3181|TRACE|file|In Library @1.
        

        并注意NLog.config文件 NOT 已创建。

        4。使用F#Interactive

        创建配置并将消息记录到文件中

        在MyLibrary.Script.fsx

        // print out __SOURCE_DIRECTORY__ to make sure we are not using the Temp directory
        printfn __SOURCE_DIRECTORY__
        
        #I __SOURCE_DIRECTORY__
        
        // Inform F# Interactive where to find functions in Log module
        #I "../Log/bin/Debug/"
        #r "Log.dll"
        
        open Log
        
        // Functions in Log module can now be run.
        MyLog.configureNLogPrgramatically ()
        MyLog.printNLogConfig ()
        
        // Inform F# Interactive where to find functions in MyLibrary module
        #I "../MyLibrary/bin/Debug/"
        #r "MyLibrary.dll"
        
        open Library1
        
        // Functions in MyLibrary module can now be run.
        MyFunctions.test001 ()
        

        使用F#Interactive

        执行脚本时
        Microsoft (R) F# Interactive version 14.0.23413.0
        Copyright (c) Microsoft Corporation. All Rights Reserved.
        
        For help type #help;;
        
        > 
        <Solution directory>\MyLibrary
        val it : unit = ()
        
        --> Added <Solution directory>\MyLibrary' to library include path
        
        
        --> Added <Solution directory>\MyLibrary\../Log/bin/Debug/' to library include path
        
        
        --> Referenced <Solution directory>\MyLibrary\../Log/bin/Debug/Log.dll'
        
        File Target[file]
        logNamePattern: (:All) levels: [ Trace Debug Info Warn Error Fatal ] appendTo: [ file ]
        
        
        --> Added <Solution directory>\MyLibrary\../MyLibrary/bin/Debug/' to library include path
        
        
        --> Referenced <Solution directory>\MyLibrary\../MyLibrary/bin/Debug/MyLibrary.dll'
        
        
        val it : unit = ()
        
        > 
        

        日志文件log.txt应包含类似于:

        的内容
        2016-03-28 11:42:41.5417|TRACE|file|In Library @1.
        

        此外,这将在您仍有活动的F#Interactive会话时进行记录,因此您可以查看执行命令之间的日志。