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

Guy*_*der 3 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"
Run Code Online (Sandbox Code Playgroud)

我甚至发现导致我尝试了这些

NLog.Config.SimpleConfigurator.ConfigureForConsoleLogging()
NLog.Config.SimpleConfigurator.ConfigureForFileLogging(<full file name>)
Run Code Online (Sandbox Code Playgroud)

并且仍然没有在日志文件中.

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

编辑

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

Guy*_*der 11

问题

使用F#Interactive的NLog的问题是NLog认为该Temp目录是查找的位置NLog.config,从不成功.解决这个问题的方法是以编程方式定位NLog.configNLog.

要解决这个问题的事情:

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

    > System.Environment.CurrentDirectory;; 
    val it : string = "C:\Users\Eric\AppData\Local\Temp"
    
    Run Code Online (Sandbox Code Playgroud)
  2. NLog日志记录需要三个组件:
    a.引用NLog.dll.
    湾 配置文件.
    C.从代码调用记录器方法.

  3. NLog可以通过多种方式进行配置,包括以编程方式和使用配置文件.
  4. AppData是一个隐藏文件夹.猜猜使用Windows资源管理器时意味着什么.
  5. 要在Visual Studio中使用F#Interactive获取应用程序的位置,您需要__SOURCE_DIRECTORY__.请参阅F#规范 3.11标识符替换
  6. NLog.conf可以使用完整的文件路径.显而易见但必要.
  7. NLog 文件目标有一个autoFlush选项.
  8. 可以使用NuGet将NLog安装到Visual Studio项目中.
  9. 这里的大部分信息来自NLog Wiki.

而不是直接进入F#Interactive解决方案,将使用以下进程,因为需要创建DLL来设置和保存用于F#Interactive的NLog的函数.

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

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

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

  4. 使用F#Interactive创建配置并将消息记录到文件中

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

使用Visual Studio创建三个项目.

在此输入图像描述

为所有三个项目安装NLog.

在此输入图像描述

2.A. 手动创建NLog.config

注意:要使这些示例在__SOURCE_DIRECTORY__;;从F#Interactive运行时起作用,它应报告属于项目的目录而不是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>
Run Code Online (Sandbox Code Playgroud)

注意:请记住更改<Solution directory>为实际路径并进行设置 autoFlush="true"

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

在此输入图像描述

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 ())
Run Code Online (Sandbox Code Playgroud)

并为Log项目添加引用 System.XML

在Main.Program.fs中

open Log

[<EntryPoint>]
let main argv = 

    MyLog.configureNLog ()
    MyLog.printNLogConfig ()

    0 // return an integer exit code
Run Code Online (Sandbox Code Playgroud)

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

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

File Target[file]
logNamePattern: (:All) levels: [ Trace Debug Info Warn Error Fatal ] appendTo: [ file ]
Run Code Online (Sandbox Code Playgroud)

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")
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

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

在MyLibrary.Library1.fs中

namespace Library1

open Log

module MyFunctions =

    let test001 () =
        MyLog.evalTracer.Trace("In Library @1.")
Run Code Online (Sandbox Code Playgroud)

并为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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

要Log.Library1.fs添加

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

运行时,日志文件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.
Run Code Online (Sandbox Code Playgroud)

并注意,NLog.config文件 创建.

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 ()
Run Code Online (Sandbox Code Playgroud)

使用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 = ()

> 
Run Code Online (Sandbox Code Playgroud)

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

2016-03-28 11:42:41.5417|TRACE|file|In Library @1.
Run Code Online (Sandbox Code Playgroud)

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