3

F# Interactive を使用する場合、F# 関数の入力と出力をキャプチャする必要があります。F5 または Ctrl-F5 を使用して Visual Studio でプログラムを実行すると、NLog を正常に動作させることができます。また、ログに出力するステートメントを含む同じメソッドは正常に機能し、F# Interactive 経由で呼び出されたときに呼び出されます。ログファイルには何もありません。

また、F# Interactive で次のことを試して、NLog への参照を設定しましたが、F# Interactive から実行してもログには何も記録されませんでした。

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

そして、私はこれを見つけて、これらのそれぞれを試すようになりました

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

ログファイルにはまだ何もありません。

F# Interactive で Nlog を使用できるかどうか知っている人はいますか?
もしそうなら、それはどのように行われますか?

編集

スタンドアロンとして実行すると、NLog を fsi.exe で動作させることができました。そのため、NLog は Visual Studio の fsi.exe の場所から始まる構成ファイルを見つけることができないため、NLog が構成ファイルを見つけることが問題になっているようです。NLog.dll ディレクトリで NLog.dll.nlog の使用を検討しています。

4

1 に答える 1

11

問題

F# Interactive から NLog を使用する際の問題は、NLog がTempディレクトリを検索する場所であると認識しNLog.config、決して成功しないことです。これを回避する方法は、プログラムNLog.configで NLog を見つけることです。

この問題を解決するために知っておくべきこと:

  1. Visual Studio 内から F# Interactive を実行すると、現在の作業ディレクトリが一時ファイルに設定されます。

    > System.Environment.CurrentDirectory;; 
    val it : string = "C:\Users\Eric\AppData\Local\Temp"
    
  2. NLog ロギングには、次の 3 つのコンポーネントが必要
    です。NLog.dll への参照。
    b. 構成ファイル。
    c. コードからロガー メソッドを呼び出します。

  3. NLog は、プログラムと構成ファイルの両方を使用して、さまざまな方法で構成できます。
  4. AppData は隠しフォルダーです。Windows エクスプローラーを使用する場合、これが何を意味するかを推測してください。
  5. Visual Studio 内で F# Interactive を使用してアプリケーションの場所を取得するには、__SOURCE_DIRECTORY__. F# 仕様3.11 識別子の置換を参照してください。
  6. NLog.conf は完全なファイル パスを使用できます。当たり前だけど必要。
  7. NLogファイル ターゲットには autoFlush オプションがあります。
  8. NLog は、 NuGetを使用してVisual Studio プロジェクトにインストールできます。
  9. ここにある情報のほとんどは、NLog Wikiからのものです。

F# インタラクティブ ソリューションに飛び込む代わりに、F# インタラクティブの NLog で使用する関数をセットアップして保持するために DLL を作成する必要があるため、次の手順を使用します。

  1. 3 つのプロジェクトでソリューションを作成し、NLog をインストールします。
    ソリューション名: NLogExample
    プロジェクト 1 - ライブラリ、名前: ログ - NLog を呼び出す拡張関数を保持
    プロジェクト 2 - ライブラリ、名前: MyLibrary - ログ関数を使用するデモ DLL の生成に使用。
    プロジェクト 3 - コンソール アプリケーション、名前: メイン - ログ関数を使用するデモ EXE を生成するために使用されます。

  2. を。
    a. NLog.config を手動で作成します。実行中のプロジェクトとしてから NLog.config にアクセスします
    c. メッセージをファイルに記録する

  3. を。プログラムで構成を作成する
    b. 実行中のプロジェクトの構成を作成し、メッセージをファイルに記録します

  4. 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# を使用してプログラムで構成を設定するには、次のことを知っておく必要があります。

  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

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# インタラクティブ セッションがある間にログが記録されるため、コマンドを実行する間にログを確認できます。

于 2013-02-04T01:23:27.530 に答える