脱config file

log4net で logger を使おうとしてググるとほぼ100% xml でその定義をした例しかない．
多分それで事足りるんだろうし，十分なんだろうけど， logger class を共通なものを保持しておいて，他のプロジェクトで参照して，参照先プロジェクトで別なlog file を作りたいとか，動的に吐き出し先を変えたいとかはなんか難しい．

ならlogger 作成から動的にすればいいじゃないって感じの記事です．
まぁ英語ベースならいくらでも？あるんですが，せっかくなので日本語で書いてみる．

### 環境
.Net 6
log4net version: 2.0.15

### ベースになるだろう logger class
今回はベースには， Console 出力として， Error のみファイルに書き出す．
ファイルは，日付ごとにファイルは分けることにしてみた．
(xml で書くには RollingFileAppender で書けば良い．)

```c#
using System;
using log4net;
using log4net.Appender;
using log4net.Core;
using log4net.Layout;
using log4net.Repository.Hierarchy;

namespace TestConsole
{
    public static class CustomLogger
    {
        public static void Setup()
        {
            Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();

            // set root logger
            ConsoleAppender consoleAppender = new ConsoleAppender()
            {
                Name = "Console",
                Layout = CreatePatternLayout(),
            };
            consoleAppender.ActivateOptions();
            // ---

            // set error
            var Filter = new log4net.Filter.LevelRangeFilter()
            {
                LevelMin = log4net.Core.Level.Error,
                LevelMax = log4net.Core.Level.Error,
            };
            Filter.ActivateOptions();

            FileAppender fileAppender = new FileAppender()
            {
                Name = "Error",
                File = $"../ErrorLog_{DateTime.Now.ToString("yyyyMMdd")}.txt",
                Layout = CreatePatternLayout(),
                AppendToFile = true,
            };
            fileAppender.AddFilter(Filter);
            fileAppender.ActivateOptions();
            //

            hierarchy.Root.AddAppender(consoleAppender);
            hierarchy.Root.AddAppender(fileAppender);

            hierarchy.Root.Level = Level.Info;
            hierarchy.Configured = true;
        }

        public static ILog GetLogger()
            => log4net.LogManager.GetLogger("TestConsole");


        private static PatternLayout CreatePatternLayout()
        {
            PatternLayout patternLayout = new PatternLayout();
            patternLayout.ConversionPattern = "%date [%thread] %-5level %logger - %message%newline";
            patternLayout.ActivateOptions();
            return patternLayout;
        }

        // 後から足すよう
        public static void AddAppender(IAppender appender)
        {
            Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
            var rootLogger = hierarchy.Root;
            rootLogger.AddAppender(appender);
        }

    }
}
```

### 使い方
```C#
using System;
class Program
{
    static void Main(string[] args)
    {
        // まず始めに loggr を set する
        TestConsole.CustomLogger.Setup();

        // logger instance を取得し
        var logger = TestConsole.CustomLogger.GetLogger();

        // log を吐き出してみる
        logger.Info("info");
        logger.Error("error");
        logger.Info("info");
        logger.Error("error");

        // 入力待機
        Console.ReadLine();
    }
}
```

### 最後に？
これを呼び出す感じにすることで， xml からおさらばできる．

ちなみに，ある程度処理して，あぁここからこの deebug log も分たいって時は， Appender 追加すれば良い．
でも，そんなことあるかな？

project Aでは， 普通の log で，
project Bでは， error log はちょっとわけで出したいって時に使うのかな．
```c#
TestConsole.CustomLogger.AddAppender()
```

### 参考記事
https://stackoverflow.com/questions/16336917/can-you-configure-log4net-in-code-instead-of-using-a-config-file

https://garafu.blogspot.com/2014/05/log4net-add-appender.html