問題
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 ロギングには、次の 3 つのコンポーネントが必要
です。NLog.dll への参照。
b. 構成ファイル。
c. コードからロガー メソッドを呼び出します。
- NLog は、プログラムと構成ファイルの両方を使用して、さまざまな方法で構成できます。
- AppData は隠しフォルダーです。Windows エクスプローラーを使用する場合、これが何を意味するかを推測してください。
- Visual Studio 内で F# Interactive を使用してアプリケーションの場所を取得するには、
__SOURCE_DIRECTORY__
. F# 仕様3.11 識別子の置換を参照してください。
- NLog.conf は完全なファイル パスを使用できます。当たり前だけど必要。
- NLogファイル ターゲットには autoFlush オプションがあります。
- NLog は、 NuGetを使用してVisual Studio プロジェクトにインストールできます。
- ここにある情報のほとんどは、NLog Wikiからのものです。
F# インタラクティブ ソリューションに飛び込む代わりに、F# インタラクティブの NLog で使用する関数をセットアップして保持するために DLL を作成する必要があるため、次の手順を使用します。
3 つのプロジェクトでソリューションを作成し、NLog をインストールします。
ソリューション名: NLogExample
プロジェクト 1 - ライブラリ、名前: ログ - NLog を呼び出す拡張関数を保持
プロジェクト 2 - ライブラリ、名前: MyLibrary - ログ関数を使用するデモ DLL の生成に使用。
プロジェクト 3 - コンソール アプリケーション、名前: メイン - ログ関数を使用するデモ EXE を生成するために使用されます。
を。
a. NLog.config を手動で作成します。実行中のプロジェクトとしてから NLog.config にアクセスします
c. メッセージをファイルに記録する
を。プログラムで構成を作成する
b. 実行中のプロジェクトの構成を作成し、メッセージをファイルに記録します
F# Interactive を使用して構成を作成し、メッセージをファイルに記録する
1. 3 つのプロジェクトでソリューションを作成し、NLog をインストールします。
Visual Studio を使用して 3 つのプロジェクトを作成します。
3 つのプロジェクトすべてに 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
メイン プロジェクトの場合は、プロジェクトへの参照を追加し、Log
メイン プロジェクトをスタートアップ プロジェクトとして設定します。
実行すると、コンソールに次のように出力されます。
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
メイン プロジェクトの場合は、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# インタラクティブ セッションがある間にログが記録されるため、コマンドを実行する間にログを確認できます。