问题描述
使用F#Interactive时,我需要捕获F#函数的输入和输出.当使用F5或Ctrl-F5在Visual Studio下运行程序时,我能够使NLog正常工作.同样,包含要输出到日志的语句的相同方法也可以正常工作,并且在通过F#Interactive调用时将被调用.日志文件中什么也没有.
I have a need to capture the input and output of F# functions when using F# Interactive. I am able to get NLog to work just fine when the program is run under Visual Studio using F5 or Ctrl-F5. Also the same methods that contain statements to output to the log work just fine and are called when invoked via F# Interactive; just nothing in the log file.
我还尝试使用F#Interactive进行以下操作,以设置对NLog的引用,而从F#Interactive运行时,日志中仍然没有任何内容.
I also tried the following with F# Interactive to setup references to NLog and still nothing in the log when run from F# Interactive.
#I @"..\packages\NLog.2.0.0.2000\lib\net40"
#r @"NLog.dll"
我什至发现了此,这促使我尝试了其中的每一个
And I even found this which led me to try each of these
NLog.Config.SimpleConfigurator.ConfigureForConsoleLogging()
NLog.Config.SimpleConfigurator.ConfigureForFileLogging(<full file name>)
并且在日志文件中仍然没有任何内容.
and still nothing in the log file.
任何人都知道Nlog是否可以与F#Interactive一起使用吗?
如果是这样,怎么做?
Anyone know if Nlog can be used with F# Interactive?
If so, how is it done?
编辑
当独立运行时,我能够使NLog与fsi.exe一起使用.因此,现在的问题似乎是让NLog查找配置文件,因为NLog无法从fsi.exe for Visual Studio的位置开始查找配置文件.在使用NLog.dll目录中的NLog.dll.nlog.
I was able to get NLog to work with fsi.exe when run as a stand alone. So now the problem appears to be getting NLog to find the config file because NLog cannot find the config file starting from the location of fsi.exe for Visual Studio. Looking at using NLog.dll.nlog in the NLog.dll directory.
推荐答案
问题
在F#Interactive中使用NLog的问题在于NLog认为Temp
目录是在其中找到NLog.config
的位置,并且永远不会成功.解决此问题的方法是以编程方式找到NLog的NLog.config
.
The Problem
The problem with using NLog from F# Interactive is that NLog thinks that the Temp
directory is where to find NLog.config
and never succeeds. The way around this is to programmatically locate NLog.config
for NLog.
-
在Visual Studio中运行F#Interactive时,它将当前工作目录设置为临时文件.
When you run F# Interactive from within Visual Studio, it sets the current working directory to a temp file.
> System.Environment.CurrentDirectory;;
val it : string = "C:\Users\Eric\AppData\Local\Temp"
NLog日志记录需要三个组件:
一种.对NLog.dll的引用.
b.配置文件.
C.从代码调用记录器方法.
NLog logging requires three components:
a. reference to NLog.dll.
b. configuration file.
c. calls to a logger method from code.
不是直接进入F#Interactive解决方案,而是使用以下过程,因为需要创建一个DLL来设置和保存用于F#Interactive的NLog的功能.
Instead of jumping right into the F# Interactive solution, the following progression will be used because a DLL will need to be created to setup and hold the functions for use with NLog from F# Interactive.
-
使用三个项目创建一个解决方案并安装NLog.
解决方案名称:NLogExample
项目1-库,名称:Log-包含调用NLog
的扩展功能项目2-库,名称:MyLibrary-用于生成使用Log函数的演示DLL.
项目3-控制台应用程序,名称:Main-用于生成使用Log函数的演示EXE.
Create a solution with three projects and install NLog.
Solution Name: NLogExample
Project 1 - Library, Name: Log - holds extension functions that call NLog
Project 2 - Library, Name: MyLibrary - used to generate a demo DLL that uses Log functions.
Project 3 - Console Application, Name: Main - used to generate a demo EXE that uses Log functions.
a.手动创建NLog.config
b.从正在运行的项目访问NLog.config.
C.将消息记录到文件
a. Manually create NLog.config
b. Access NLog.config from as a running project
c. Log a message to the file
a.以编程方式创建配置
b.为正在运行的项目创建配置,并将消息记录到文件
a. Programmatically create a configuration
b. Create a configuration for a running project and log a message to the file
创建配置并使用F#Interactive将消息记录到文件中
Create a configuration and log a message to the file using F# Interactive
1.创建包含三个项目的解决方案并安装NLog
使用Visual Studio创建三个项目.
1. Create a solution with three projects and install NLog
Using Visual Studio create the three projects.
为所有三个项目安装NLog.
Install NLog for all three projects.
注意:为了使这些示例在从F#Interactive运行__SOURCE_DIRECTORY__;;
时起作用,应报告属于项目的目录,而不是Temp
目录.
Note: For these examples to work when __SOURCE_DIRECTORY__;;
is run from F# Interactive it should report a directory that is part of the project and NOT the Temp
directory.
注意:此答案中的所有路径都相对于解决方案目录.
当您在实际的解决方案目录中看到<Solution directory>
替代项时.
Note: All the paths in this answer are relative to the solution directory.
When you see <Solution directory>
substitute in your actual 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"
Note: Remember to change <Solution directory>
to an actual path and set autoFlush="true"
注意:在解决方案中添加NLog.config
可以更轻松地查看/修改文件.
Note: Adding NLog.config
to the solution makes it easier to view/modify the file.
在Log.Library1.fs中
In 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
and for the Log project add a reference to System.XML
在Main.Program.fs
In Main.Program.fs
open Log
[<EntryPoint>]
let main argv =
MyLog.configureNLog ()
MyLog.printNLogConfig ()
0 // return an integer exit code
,并为Main项目添加对Log
项目的引用,并将Main项目设置为启动项目.
and for the Main project add a reference to the Log
project and set the Main project as the startup project.
运行时,应将其输出到控制台:
When run this should output to the console:
File Target[file]
logNamePattern: (:All) levels: [ Trace Debug Info Warn Error Fatal ] appendTo: [ file ]
2.c.将消息记录到文件中
在Log.Library1.fs中
2.c. Log a message to the file
In 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
In 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
项目的引用.
and for the Main project add a reference to the MyLibrary
project.
在MyLibrary.Library1.fs
In MyLibrary.Library1.fs
namespace Library1
open Log
module MyFunctions =
let test001 () =
MyLog.evalTracer.Trace("In Library @1.")
,并为MyLibrary项目添加对Log
项目的引用.
and for the MyLibrary project add a reference to the Log
project.
运行日志文件时,log.txt
应包含类似于以下内容的文件:
When run the log file log.txt
should contain something similar to:
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
文件,请将其删除以验证代码是否创建了新配置,但未创建文件.
3.a. Programmatically create a configuration
If a NLog.config
file exist delete it to verify that the code created a new configuration but did not create a file.
要使用F#以编程方式设置配置,您需要了解:
To set the configuration programmatically using F# you need to know:
- 此FileName字符串是一个布局,可能包含布局渲染器的实例.这使您可以使用单个目标写入多个文件.
- SimpleLayout-表示一个带有嵌入式占位符的字符串,该占位符可以呈现上下文信息.
向Log.Library1.fs添加
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
3.b. Create a configuration for a running project and log a message to the file
In 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
应包含类似于以下内容的文件:
When run the log file log.txt
should contain something similar to:
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
文件.
and note that a NLog.config
file was NOT created.
在MyLibrary.Script.fsx中
In 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执行脚本时
When the script is executed with 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
应包含类似于以下内容的文件:
The log file log.txt
should contain something similar to:
2016-03-28 11:42:41.5417|TRACE|file|In Library @1.
此外,当您仍然有活动的F#Interactive会话时,它将记录日志,因此您可以查看执行命令之间的日志.
Also, this will log while you still have an active F# Interactive session, so you can peek at the log between executing commands.
这篇关于在Visual Studio中将NLog与F#Interactive一起使用-需要文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!