NLog を利用したログ記録の手順 (WinFormsアプリケーション例)

本資料では、WinFormsアプリケーションで NLog を使用してログを記録する手順を、具体的なキャプチャーとサンプルコードをもとに解説します。以下の手順に従うことで、ファイルへのログ出力を簡単に実装できます。


アプリケーションの開発・運用において、ログはデバッグやトラブルシューティング、ユーザーサポートなど、あらゆる場面で大きな恩恵をもたらします。特に NLog は、簡単な導入方法と高い拡張性・柔軟性を兼ね備えているため、プロジェクト規模や要件を問わず、多くの場面で利用されています。
本資料では、WinFormsアプリケーションを例に、NLogを導入してログを記録する具体的な手順を紹介します。実装後は、例外が発生した際の原因追跡や、アプリケーションの動作状況の把握が容易になるなど、NLogの恩恵を大いに感じていただけるでしょう。

1. NuGetパッケージのインストール

  1. ソリューションエクスプローラー で、プロジェクト名(例:NLogSample)を右クリックし、
    「NuGet パッケージの管理…」 を選択します。
  2. 「参照」 タブまたは 「ブラウザー」 タブから NLog を検索し、インストールします。

以下のキャプチャーのように、コード上で LogManager にカーソルを合わせ、右クリック → 「パッケージ 'NLog’ のインストール」 を選択してもOKです。


2. NLog.config ファイルの作成

  1. ソリューションエクスプローラー で、プロジェクト名を右クリック → 「追加」「新しい項目」 を選択します。
  1. 「テキスト ファイル」を選択し、ファイル名を NLog.config として追加します。
  1. 作成した 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">

    <!-- ログの出力先を定義 -->
    <targets>
        <!-- ファイルにログを出力 -->
        <target xsi:type="File" name="fileTarget" fileName="logs/app.log"
                layout="${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}" />
    </targets>

    <!-- ロガーのルールを定義 -->
    <rules>
        <!-- 全てのロガーに対して、Traceレベル以上のログをfileTargetに出力 -->
        <logger name="*" minlevel="Trace" writeTo="fileTarget" />
    </rules>
</nlog>

以下は、提示された NLog.config の内容を項目ごとに詳細に解説したものです。


1. XML宣言と名前空間

<?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">
  • XML宣言:
    ファイルが UTF-8 エンコーディングで書かれていることを示します。
  • ルート要素 <nlog> と名前空間:
  • xmlns="http://www.nlog-project.org/schemas/NLog.xsd" により、NLog のスキーマに基づく設定であることを示しています。
  • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" は、XML Schema のインスタンス用の名前空間で、後述する xsi:type 属性などの定義に利用されます。

2. ログの出力先(ターゲット)の定義

<targets>
    <!-- ファイルにログを出力 -->
    <target xsi:type="File" name="fileTarget" fileName="logs/app.log"
            layout="${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}" />
</targets>
  • <targets> 要素:
    ログの出力先をまとめて定義するためのコンテナ要素です。
  • <target> 要素:
  • xsi:type="File"
    このターゲットが「ファイル出力」であることを示します。
  • name="fileTarget"
    このターゲットに一意な名前(ここでは fileTarget)を付与します。設定内で他の箇所から参照する際に使用します。
  • fileName="logs/app.log"
    ログを出力するファイルのパスとファイル名を指定しています。
    • この場合、アプリケーションの実行ファイルと同じディレクトリ内にある logs フォルダの中に app.log ファイルが作成されます。
  • layout 属性
    ログの各エントリの出力フォーマットを指定します。
    • ${longdate}: ログ出力日時を長い形式で表示
    • ${level:uppercase=true}: ログレベル(INFO、DEBUG、ERROR など)を大文字で表示
    • ${logger}: ログを出力したクラス名などの情報を表示
    • ${message:withexception=true}: ログメッセージを出力し、例外がある場合はその情報(例外のメッセージやスタックトレース)も含める

3. ロガーのルール設定

<rules>
    <!-- 全てのロガーに対して、Traceレベル以上のログをfileTargetに出力 -->
    <logger name="*" minlevel="Trace" writeTo="fileTarget" />
</rules>
  • <rules> 要素:
    どのログ(ロガー)がどのターゲットに出力されるかのルールを定義します。
  • <logger> 要素:
  • name="*"
    すべてのロガー(クラスや名前空間など)のログメッセージに適用されます。
  • minlevel="Trace"
    最小ログレベルとして Trace を指定しているため、Trace、Debug、Info、Warn、Error、Fatal といった全てのレベルのログが対象になります。
  • writeTo="fileTarget"
    先ほど定義した fileTarget へログを出力することを意味します。

4. まとめ

この NLog.config の設定では、

  • 出力先:
    ログは、実行ファイルのディレクトリにある logs フォルダ内の app.log というファイルに出力されます。
  • ログフォーマット:
    各ログエントリは、日時、ログレベル、ロガー名、ログメッセージ(および例外情報がある場合はその詳細)がパイプ区切りの形式で出力されます。
  • 適用ルール:
    すべてのロガーからの全てのログレベル(Trace 以上)のメッセージが、上記のファイルターゲットに出力される設定になっています。

この設定により、アプリケーション内で NLog を利用してログを出力する際、全ての詳細なログが指定したファイルに記録され、後から運用状況やトラブルシューティングに活用することができます。

ポイント:

  • fileName="logs/app.log" の部分で、logs フォルダに app.log ファイルを出力する設定です。
  • withexception=true を指定すると、例外発生時にスタックトレースも出力されます。
<?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">

  <targets>
    <!-- ファイルにログを出力 -->
    <target xsi:type="File" name="fileTarget" fileName="logs/app.log"
            layout="${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}" />

    <!-- 出力ウィンドウ(デバッガ)へログを出力 -->
    <target xsi:type="Debugger" name="debugger"
            layout="${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}" />
  </targets>

  <rules>
    <!-- 全てのロガーに対して、Traceレベル以上のログをファイルとデバッガに出力 -->
    <logger name="*" minlevel="Trace" writeTo="fileTarget,debugger" />
  </rules>
</nlog>

3. ソリューションの構成

NLog.config は、ビルド後に実行ファイルと同じフォルダにコピーされる必要があります。

  • NLog.configを選択し、プロパティ「ビルドアクション」 を「コンテンツ」に、「コピー先のディレクトリにコピー」 を「常にコピーする」または「新しい場合はコピー」に設定しておくきます

ソリューションエクスプローラーで確認すると、以下のように NLog.config が表示されます。


4. コード例(WinFormsでの使用)

以下は、WinFormsフォーム Form1 に NLog を組み込むサンプルコードです。
Form1.cs 内でログを初期化し、実行時にログを出力しています。

using NLog;
using System;
using System.Windows.Forms;

namespace NLogSample
{
    public partial class Form1 : Form
    {
        // 1. ログを記録するためのNLogのLoggerオブジェクトを取得します。
        //    GetCurrentClassLogger() は、現在のクラス(Form1)の名前空間をもとに
        //    ロガーを作成してくれます。
        private static readonly Logger logger = LogManager.GetCurrentClassLogger();

        public Form1()
        {
            // 2. フォームの初期化処理を行います。
            InitializeComponent();

            // 3. アプリケーションが開始したことをログに記録します。
            //    ここでは「Info」レベルのメッセージを出力しています。
            logger.Info("アプリケーションが開始されました。");

            try
            {
                // 4. デバッグに役立つ詳細な情報をログに記録します。
                //    「Debug」レベルのメッセージは、より細かい情報を記録したいときに使います。
                logger.Debug("デバッグメッセージ: 変数xの値を出力します。");

                // 5. 例外を意図的に発生させます(0 で割り算)。
                //    実際のプログラムではこのようなコードは書かないでください。
                int result = 10 / int.Parse("0");
            }
            catch (Exception ex)
            {
                // 6. 例外が起きた場合に、エラーの内容をログに記録します。
                //    「Error」レベルのメッセージは、障害や異常時に使います。
                //    ex(例外オブジェクト)を渡すことで、スタックトレースなどの詳細を記録できます。
                logger.Error(ex, "エラーが発生しました。");
            }
            finally
            {
                // 7. アプリケーションが終了したことをログに記録します。
                //    ここではフォームのコンストラクタが終わるタイミングでログを出していますが、
                //    実際の終了処理は、フォームを閉じるときなどで行うことが多いです。
                logger.Info("アプリケーションが終了しました。");
            }
        }
    }
}

コードのポイント

  1. Logger の取得:
    • NLog のロガーを取得し、クラス内で使い回します。
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
  1. ログレベルの使い分け:
    • Debug: 詳細なデバッグ情報
    • Info: 一般的な動作情報(起動・終了など)
    • Warn: 注意が必要な状況
    • Error: エラーが発生した場合
    • Fatal: 致命的なエラーの場合
  2. 例外処理:
    • catch (Exception ex) 内で logger.Error(ex, "メッセージ") を呼び出すことで、例外のスタックトレースやメッセージを含めてログに出力できます。
  3. NLog.config:
    • どこにログを出力するか(ファイル、コンソール、イベントログなど)や、どのログレベル以上を記録するかを設定ファイルで管理します。
    • 初心者の方は、まずファイル出力(例:app.log)を設定するとログの確認が容易です。

5. 実行結果

  1. アプリケーションを起動し、フォームが表示されると、上記のコードが実行されます。
  2. logs フォルダが作成され、その中に app.log ファイルが出力されます。
  3. app.log を開くと、下記のようなログが記録されていることを確認できます。
2025-02-28 07:26:01.5769|INFO|NLogSample.Form1|アプリケーションが開始されました。
2025-02-28 07:26:01.5978|DEBUG|NLogSample.Form1|デバッグメッセージ: 変数xの値を出力します。
2025-02-28 07:26:01.5978|ERROR|NLogSample.Form1|エラーが発生しました。|System.DivideByZeroException: 0 で除算しようとしました。
   場所 NLogSample.Form1..ctor() 場所 C:\Users\konishihideaki\source\repos\NLogSample\NLogSample\Form1.cs:行 27
2025-02-28 07:26:01.6098|INFO|NLogSample.Form1|アプリケーションが終了しました。

以下のログは、NLog で記録された アプリケーションの実行状況 を示しています。各行のフォーマットは概ね

[日時] | [ログレベル] | [ロガー名] | [メッセージ] | [例外情報(省略可)]

という構成になっています。ログを上から順に読み解くことで、アプリケーションの流れやエラー発生のタイミングがわかります。


ログ内容の解説

  1. 2025-02-28 07:26:01.5769|INFO|NLogSample.Form1|アプリケーションが開始されました。
    • 日時: 2025-02-28 07:26:01.5769
    • ログレベル: INFO(情報)
    • ロガー名: NLogSample.Form1
    • メッセージ: 「アプリケーションが開始されました。」
  • 解説:
    アプリケーション(Form1のコンストラクタ)が実行され始めたことを表します。
    「INFO」は一般的な動作状況を記録するレベルで、ここでは起動時のメッセージです。
  1. 2025-02-28 07:26:01.5978|DEBUG|NLogSample.Form1|デバッグメッセージ: 変数xの値を出力します。
    • 日時: 2025-02-28 07:26:01.5978
    • ログレベル: DEBUG(デバッグ)
    • ロガー名: NLogSample.Form1
    • メッセージ: 「デバッグメッセージ: 変数xの値を出力します。」
  • 解説:
    デバッグ用の詳細な情報を出力している行です。開発時の調査や検証に役立ちます。
    ここでは変数の値をチェックするなど、アプリケーション内部の詳細を把握するためのログです。
  1. 2025-02-28 07:26:01.5978|ERROR|NLogSample.Form1|エラーが発生しました。|System.DivideByZeroException: 0 で除算しようとしました。
    場所 NLogSample.Form1..ctor() 場所 C:\Users\konishihideaki\source\repos\NLogSample\NLogSample\Form1.cs:行 27
    • 日時: 2025-02-28 07:26:01.5978
    • ログレベル: ERROR(エラー)
    • ロガー名: NLogSample.Form1
    • メッセージ: 「エラーが発生しました。」
    • 例外情報:
      • 例外クラス: System.DivideByZeroException
      • エラー内容: 「0 で除算しようとしました。」
      • スタックトレース: Form1.cs の 27 行目でエラーが発生
  • 解説:
    0 で割り算しようとしたため、DivideByZeroException が発生したことを示します。
    ここでは ERROR レベルのログが出力され、例外の詳細(クラス名、メッセージ、発生箇所)が記録されています。
    この情報をもとに、どのコードでエラーが起きたか、原因は何かを特定できます。
  1. 2025-02-28 07:26:01.6098|INFO|NLogSample.Form1|アプリケーションが終了しました。
    • 日時: 2025-02-28 07:26:01.6098
    • ログレベル: INFO(情報)
    • ロガー名: NLogSample.Form1
    • メッセージ: 「アプリケーションが終了しました。」
  • 解説:
    例外が発生した後も finally ブロックで処理が実行され、アプリケーションの終了処理に到達したことがわかります。
    正常/異常終了にかかわらず、アプリケーションが終わったタイミングを記録するために、このようなログがあると便利です。

全体の流れ

  1. 開始(INFO): アプリケーションが起動し、処理を開始。
  2. デバッグ(DEBUG): 開発者向けの細かい情報をログに出力。
  3. エラー(ERROR): 0 で割り算するコードが実行され、例外が発生。
  4. 終了(INFO): 例外処理後に、アプリケーションが終了する際の情報を記録。

このログを分析すると、起動 → デバッグメッセージ → 例外発生 → 終了、というアプリケーションの流れが一目でわかります。エラーの種類や発生箇所も特定できるため、トラブルシューティングや修正の際に非常に役立ちます。

ログが表示されない場合:

  • NLog.config の配置やビルドアクションの設定を再度ご確認ください。
  • 相対パス logs/app.log は、実行ファイル (.exe) からの相対パスです。実行環境によりファイルパスが異なる場合があります。

6. まとめ

  1. NLog NuGetパッケージをインストール する。
  2. プロジェクトに NLog.config を追加し、ログ出力先やフォーマットを設定。
  3. LogManager.GetCurrentClassLogger() でロガーを取得し、コード内でログメッセージを出力。
  4. 実行すると、指定した場所(今回の例では logs/app.log)にログが生成される。

これらの手順を踏むことで、WinFormsアプリケーションでも簡単にログ出力を行うことができます。開発時・運用時のトラブルシューティングや情報把握に大いに役立ちますので、ぜひご活用ください。

デバッグ

Posted by hidepon