log4netの設定ファイルで文字コードをBOM付きとかBEとか細かく設定したい

2021-02-07

現状UTF8のBOMの指定がC#のEncodingクラスの初期値に準じているのでもし変わった文字コードで出力したい場合に困るなーと思ったので。
(まあそんなことよっぽどないと思いますけど)

とりあえずできないならできないなりにそれっぽい検証しましたよー感が欲しい。

type指定してかつコンストラクタに値を入れたい

これさえできれば文字コードにBOMを付けたり外したり自由だ!!というわけなのですが、残念なことに今のところお手軽に設定ファイルから指定する方法を見つけられていません。

<Encoding type="System.Text.UTF8Encoding" encoderShouldEmitUTF8Identifier="false" />

一応、上記のようなコードでlog4netはエラーを吐かないことまでは検証済みですが、falseにした場合もtrueにした場合も出力されるログの文字コードは変わりませんでした。ログを出力時、コンストラクタの値は使用していないようです。もしくはエラーを吐いてないだけで実際に値の格納ができていないのかもしれません。

これ以上調べるとなるとlog4netさんのソース読み解かないといけないから嫌だなーーー。System.Text.Encodingクラスを継承するクラス作ったら思い通りの挙動するんですかね?

とりあえずEncodingクラスを継承するクラス作ってみた

public class UTF16BOMEncoding : System.Text.UnicodeEncoding{}

ばばーん

とりあえずUnicodeEncoding継承しただけの空っぽのクラスを作ってみました。これを設定ファイルで指定して…実行!!

見事なエラー。考えてみたら継承したクラス作ってもlog4netから参照できてないのだから見れるわけがない。

じゃあ参照設定追加したら?

ついにnugetパッケージをそのまま使うことを放棄。公式からソースをダウンロードしてダウンロードしたパッケージに参照設定を追加して実行してします。

この場合、参照を相互でできないので新しくクラスモジュールを作成する必要があります…なんてめんどくさい。

using System.Text;

namespace Encode
{
    public class UTF16BOMEncoding : UnicodeEncoding
    {
        public UTF16BOMEncoding() : base(false, true) { }
    }

    public partial class UTF16NoBOMEncoding : UnicodeEncoding
    {
        public UTF16NoBOMEncoding() : base(false, false) { }
    }
}

こんなクラスを作ってlog4netから参照設定をしてみました。そして実行!

結果は失敗に終わった

結果失敗です。残念。なんか書き方おかしいのかなー?と思いながらデバック実行してみた…ら、見つけてしまいました。

上の画像はxml(設定ファイル)に書いてあるクラス名から該当するクラスを検索している部分です。ここで気が付く。検索対象がもともと絞られていることに。新しくクラス追加しても検索対象外なら意味ないやん。
この辺触らないとどうがんばっても思った結果にはならなさそうです。

最後に

他になんとかする方法が思い浮かんだらまた検証する所存です。以上。