log4netを使用してC#.Net(WindowsForm)にログ出力機能を仕込む

# log4netとは
Apacheが開発しているログ出力用のコンポーネントライブラリです。
数年ぶりに".net"を触ったのでいろいろ調べたのですがまだこのlog4netが主流のようですね。

復習がてら基本的な使い方を記述していきます。
新規のWindowsFormプロジェクトにlog4netを使用したログを仕込む所までやっていこうと思います。

# 前提

自分の環境は以下の通り。

*  windows 10
*  C#を使用
*  IDEはVisualStudio2017を使用
*  .net framework のverは4.6

VB.Netでも適宜読み替えて頂ければ参考にはなるかと思います。

# 使い方

## 1. dllをDLする
nugetから直接インストールもできますが、ここではApache公式からDLすることとします。

https://logging.apache.org/log4net/download_log4net.cgi
Binariesのlog4net-2.0.8-bin-newkey.zipをDLします。  


## 2. 任意の場所に置き解凍する
自分はプロジェクト直下のbinフォルダ配下に解凍しました。

## 3. dllの参照設定を追加する
VisualStudioの参照マネージャーからdllを追加します。
dllは解凍したディレクトリ内のbinの配下にあります。
> .\log4net-2.0.8\bin


各種環境用のdllが用意されていますので自分の環境に合わせてdllを参照してください。
自分の場合は下記を追加しました。
> .\log4net-2.0.8\bin\net\4.5\release\log4net.dll

※ .net frameworkのverは4.6を使用していますが、log4netの方が4.5までしかなかったので4.5を選択しました。


## 4. AssemblyInfo.csに設定を追記する。

`AssemblyInfo.cs`に下記設定を追記します。
> `[assembly: log4net.Config.XmlConfigurator(Watch=true)]`


`Watch`を定義することで、設定を変更した際再ロードされるかどうかを設定することができます。

他には設定ファイルとして、どのファイルを参照するか指定することもできるようです。
デフォルトでは`app.config(web.config)`を参照するようになっています。
今回は`app.config`に直接log4net関連の設定を記述していくこととします。

## 5. app.configにlog4netの設定を記述する。

自分は大体下記のような感じで記述しました。

```xml:app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <log4net>
        <appender name="tryLogAppender" type="log4net.Appender.RollingFileAppender" >
            <File value=".\log\" />
            <DatePattern value='yyyyMMdd".log"' />
            <StaticLogFileName value="false" />
            <RollingStyle value="date" />
            <AppendToFile value="true" />
            <MaximumFileSize value="100MB" />
            <MaxSizeRollBackups value="30" />
            <layout type="log4net.Layout.PatternLayout">
                <ConversionPattern value="%date [%thread] [%-5level] (%method) - %message%n" />
            </layout>
        </appender>
        <filter type="log4net.Filter.LevelRangeFilter">
            <LevelMax value="FATAL" />
            <LevelMin value="DEBUG" />
        </filter>
        <root>
            <level value="Debug" />
            <appender-ref ref="tryLogAppender" />
        </root>        
    </log4net>
</configuration>
```

`＜root＞`
どの＜appender＞を使用するかを指定します。  
`＜appender＞`
ログの出力内容を定義している要素です。

出力先は今回は相対パスで書いています。
この相対パスは実行ファイルからみての相対パスになります。

xmlの各要素については、下記サイトが参考になりました。
https://tomosoft.jp/design/?p=3123

## 6. ログを仕込む

ここまででlog4netの準備は完了です。
あとは実際のソースコード上でlogを出力させていくだけです。

ログを仕込みたいクラスでlog4netのインスタンスを取得します。

```csharp:Form1.cs
    public partial class Form1 : Form
    {

        private static log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        
```

ログを呼び出したい場所に下記のような形でログを仕込みます。
button1はForm上に単純にbuttonを置いただけです。

```csharp:Form1.cs
        public Form1()
        {
            InitializeComponent();
            logger.Fatal("log1");
            logger.Error("log2");
            logger.Warn("log3");
            logger.Info("log4");
            logger.Debug("log5");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            logger.Debug("ボタンが押されたよ");
        }
```

ここらへん、ラッパークラスなどを作って独自で管理・拡張しているプロジェクトなどよく見るイメージです。
今回は一番シンプルな形で仕込んでいます。

## 7. 実行してみる

デバッグを開始してbutton1をバンバン連打してみました。

`\bin\Debug\logs`にlogファイルが出力されました。
logファイルには下記のように出力されています。

```log:20181030.log
2018-10-30 17:53:45,280 [1] [FATAL] (.ctor) - log1
2018-10-30 17:53:45,306 [1] [ERROR] (.ctor) - log2
2018-10-30 17:53:45,307 [1] [WARN ] (.ctor) - log3
2018-10-30 17:53:45,308 [1] [INFO ] (.ctor) - log4
2018-10-30 17:53:45,309 [1] [DEBUG] (.ctor) - log5
2018-10-30 17:53:46,549 [1] [DEBUG] (button1_Click) - ボタンが押されたよ
2018-10-30 17:53:46,692 [1] [DEBUG] (button1_Click) - ボタンが押されたよ
2018-10-30 17:53:46,812 [1] [DEBUG] (button1_Click) - ボタンが押されたよ
2018-10-30 17:53:46,965 [1] [DEBUG] (button1_Click) - ボタンが押されたよ
2018-10-30 17:53:47,076 [1] [DEBUG] (button1_Click) - ボタンが押されたよ
2018-10-30 17:53:47,212 [1] [DEBUG] (button1_Click) - ボタンが押されたよ
2018-10-30 17:53:47,484 [1] [DEBUG] (button1_Click) - ボタンが押されたよ
```

めでたし。めでたし。

## おわり

ログ出力を実装できるようになったのは良いんですが、ログって設計が難しいんですよね。
設計レベルのお話に関しては下記記事が大変参考になりました。おすすめです。
https://qiita.com/nanasess/items/350e59b29cceb2f122b3