Introduction
備忘録。
NLog を使ったコンソールアプリを dotnet publish を使って、RedHat で動かしたら…なぜか一切ログが出ない。
なぜ?
What happened?
原因は dotnet publish を実行した際のオプションの問題。
自分は下記のコマンドを実行していた。
1 | $ dotnet publish -c Release -r linux-x64 --self-contained true -p:PublishTrimmed=true |
問題の究明のために下記のプログラムを用意。
1 | using System; |
NLog.confg は下記。
1 |
|
この条件で実行すると…ログファイルどころかコンソールにさえ何も表示されない。
プログラムがクラッシュしているわけではないのはわかっていたので、 NLog に問題があると判断し、NLog.config に下記の設定を加える。
1 | <?xml version="1.0" encoding="utf-8" ?> |
すると、実行時に NLog 側がロギング処理時の例外を上位アプリケーションに投げるようになる。
1 | $ ./Demo |
眺めていると、 CreateInstance(String itemName) の文字に気が付く。
リフレクションに失敗して、ロギングに必要なクラスが探せていないのでは?、と推測が働き -p:PublishTrimmed=true が原因だと思い至った次第である。
そもそも、 dotbet publish 実行時に
1 | $ dotnet publish -c Release -r linux-x64 --self-contained true -p:PublishTrimmed=true |
のように警告は出ていたのである…
凡ミスぅ。
言い訳だが、PublishTrimmed を使うと生成されるバイナリが格段に小さくなるので魅力的でもあり、それでウキウキしていたのもある。
上記の簡単なプログラムでさえ、これだけの違いがある。
| 項目 | PublishTrimmed あり | PublishTrimmed なし |
|---|---|---|
| ファイル数 | 60 | 191 |
| 合計ファイルサイズ | 26.2 MB | 76.7 MB |
PublishTrimmed を外せば動くのはわかるが、警告に出ているように対策はある。
問題となった NLog 自体はトリムで軽くなるとはいえ、1 MB にも満たないアセンブリなので、軽量化する意味は乏しい。
なので、NLog のみトリムを除外する方式を採用する。
*.csproj に下記の設定を追加することで解決できる。
1 | + <ItemGroup> |
追加後、-p:PublishTrimmed=true を加えて再度ビルドすると、ファイル数が 70、合計ファイルサイズが 27.5 MB と微増するが、問題なくログが出るようになる。
