问题
使用 F# Interactive 的 NLog 的问题在于,NLog 认为该Temp
目录是可以找到的位置NLog.config
并且永远不会成功。解决这个问题的方法是以编程方式定位NLog.config
NLog。
解决这个问题需要知道的事情:
从 Visual Studio 中运行 F# Interactive 时,它会将当前工作目录设置为临时文件。
> System.Environment.CurrentDirectory;;
val it : string = "C:\Users\Eric\AppData\Local\Temp"
NLog 日志记录需要三个组件
:参考 NLog.dll。
湾。配置文件。
C。从代码调用记录器方法。
- NLog 可以通过多种方式进行配置,包括编程方式和使用配置文件。
- AppData 是一个隐藏文件夹。猜猜在使用 Windows 资源管理器时这意味着什么。
- 要在 Visual Studio 中使用 F# Interactive 获取应用程序的位置,您需要
__SOURCE_DIRECTORY__
. 请参阅F# Spec 3.11 标识符替换
- NLog.conf 可以使用完整的文件路径。明显但必要。
- NLog文件目标有一个 autoFlush 选项。
- NLog 可以使用NuGet安装到Visual Studio 项目中。
- 这里的大部分信息来自NLog Wiki。
无需直接跳入 F# Interactive 解决方案,而是使用以下进程,因为需要创建一个 DLL 来设置和保存用于 F# Interactive 的 NLog 的函数。
创建一个包含三个项目的解决方案并安装 NLog。
解决方案名称:NLogExample
项目 1 - 库,名称:Log - 包含调用 NLog
项目 2 - 库的扩展函数,名称:MyLibrary - 用于生成使用 Log 函数的演示 DLL。
项目 3 - 控制台应用程序,名称:Main - 用于生成使用日志功能的演示 EXE。
一种。手动创建 NLog.config
b. 从正在运行的项目中访问 NLog.config
c。将消息记录到文件
一种。以编程方式创建配置
b. 为正在运行的项目创建配置并将消息记录到文件中
使用 F# Interactive 创建配置并将消息记录到文件中
1.创建一个包含三个项目的解决方案并安装NLog
使用 Visual Studio 创建三个项目。
为所有三个项目安装 NLog。
2.a. 手动创建 NLog.config
注意:为了让这些示例在从 F# Interactive 运行时能够正常工作,它应该报告作为项目一部分的目录__SOURCE_DIRECTORY__;;
而不是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
到解决方案可以更轻松地查看/修改文件。
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# 以编程方式设置配置,您需要知道:
- 此 FileName 字符串是一个布局,其中可能包含布局渲染器的实例。这使您可以使用单个目标写入多个文件。
- 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
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
创建文件 。
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 会话时,这将记录下来,因此您可以在执行命令之间查看日志。