LoginSignup
2
3

More than 5 years have passed since last update.

Release Build 時に log4net のログ出力が行われない場合がある

Posted at

環境

.NET Framerowk 4.6.1
log4net 2.0.8

実行環境: Windows 10 Pro / Windows Server 2012

状況

コマンドラインアプリケーションにおいて、log4net を利用しているのですが、Debug Build 時にはログが出力されるにも関わらず、Release Build 時にはログが出力されませんでした。

設定の状態

App.config に設定を記述する特になんの変哲もない設定です。

AssermblyInfo.cs
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
App.config
<configuration>
    <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    </configSections>
    <log4net>
        <appender name="ConsoleAppendar" type="log4net.Appender.ConsoleAppender">
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%date %5level %message%newline" />
            </layout>
        </appender>

        <appender name="FileAppendar" type="log4net.Appender.RollingFileAppender">
            <file value="logs\ConsoleApp\ConsoleApp" />
            <appendToFile value="true" />
            <maximumFileSize value="10000KB" />
            <maxSizeRollBackups value="2" />
            <param name="DatePattern" value='"."yyyy-MM-dd".log"' />
            <param name="RollingStyle" value="date " />
            <param name="StaticLogFileName" value="false" />

            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%date [%thread] %-5level %message%newline" />
            </layout>
        </appender>

        <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
            <applicationName value="ConsoleApp"/>
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%date %-5level %message%newline"/>
            </layout>
            <filter type="log4net.Filter.LevelRangeFilter">
                <param name="LevelMin" value="WARN"/>
                <param name="LevelMax" value="FATAL"/>
            </filter>
        </appender>

        <root>
            <level value="INFO" />
            <appender-ref ref="ConsoleAppendar" />
            <appender-ref ref="FileAppendar" />
            <appender-ref ref="EventLogAppender" />
        </root>
    </log4net>
</configuration>

なぜ Release Build 時にだけログが出ないのかさっぱりわかりませんでした :cry:

原因と対処

公式の設定ファイルの書き方のところに普通に書いてありました :sweat_smile:

Using attributes can be a clearer method for defining where the application's configuration will be loaded from. However it is worth noting that attributes are purely passive. They are information only. Therefore if you use configuration attributes you must invoke log4net to allow it to read the attributes. A simple call to LogManager.GetLogger will cause the attributes on the calling assembly to be read and processed. Therefore it is imperative to make a logging call as early as possible during the application start-up, and certainly before any external assemblies have been loaded and invoked.

どうやら、assembly の attribute として記述する場合は、アプリのスタートからできるだけ早く log4net の呼び出しを行わなければいけないようです。

実際、私の書いていたコンソールアプリは、起動からそこそこの初期化処理( DB への I/O もある)の後に Logger を初めて呼び出すようになっていました。

エントリーポイントになるクラスで LogManager.GetLogger 相当を呼び出すことで Release Build でもログが問題なく出力されるようになりました。

どうして Debug Build では問題なかったのか

自分の知識だときちんと説明ができないのですが、Debug Build 時には依存アセンブリが事前にある程度ロードされるのではないかと思います。

Appendix

調査していて参考になったリンク

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3