Javaと情熱のあいだ

カステラとドーナツと珈琲

log4netのDB接続をコード上で設定する方法

log4netのAdoNetAppenderを使用する際にDB接続をC#のコード上で変更したいと思ったのでメモ。

今回は.net Framework 4.0で確認。

方法論としては 下記のように設定。

  • SQL文、カスタム項目をlog4net.confgに設定。
  • C#側でAdoNetAppenderを設定、カスタム項目の値を設定。
log4net.confg

確認のためlog4netデバッグモードで動作させる。*1

<?xml version="1.0" encoding="utf-8" ?>
<!-- [log4net.config] -->
<configuration>
    <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
    </configSections>

    <log4net debug ="true">
        <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
            <bufferSize value="100" />
            <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
            <commandText value="INSERT INTO EVENT_LOG ([UPDATED_AT],[TEST],[THREAD],[LEVEL],[LOGGER],[MESSAGE],[EXCEPTION_DATA]) VALUES (@updated_at, @test, @thread, @level, @logger, @message, @exception_data)" />
            <useTransactions value="false" />
            <bufferSize value="1" />
            <parameter>
                <parameterName value="@updated_at" />
                <dbType value="DateTime" />
                <layout type="log4net.Layout.RawTimeStampLayout" />
            </parameter>

            <parameter>
                <parameterName value="@test" />
                <dbType value="String" />
                <size value="20" />
                <layout type="log4net.Layout.PatternLayout">
                    <conversionPattern value="%X{test}" />
                </layout>
            </parameter>

            <parameter>
                <parameterName value="@thread" />
                <dbType value="String" />
                <size value="256" />

                <layout type="log4net.Layout.PatternLayout">
                    <conversionPattern value="%thread" />
                </layout>
            </parameter>

            <parameter>
                <parameterName value="@level" />
                <dbType value="String" />
                <size value="64" />

                <layout type="log4net.Layout.PatternLayout">
                    <conversionPattern value="%level" />
                </layout>
            </parameter>

            <parameter>
                <parameterName value="@logger" />
                <dbType value="String" />
                <size value="256" />
                <layout type="log4net.Layout.PatternLayout">
                    <conversionPattern value="%logger" />
                </layout>
            </parameter>

            <parameter>
                <parameterName value="@message" />
                <dbType value="String" />
                <size value="4096" />
                <layout type="log4net.Layout.PatternLayout">
                    <conversionPattern value="%message" />
                </layout>
            </parameter>

            <parameter>
                <parameterName value="@exception_data" />
                <dbType value="String" />
                <size value="2048" />
                <layout type="log4net.Layout.ExceptionLayout" />
            </parameter>
        </appender>

        <root>
            <level value="DEBUG"/>
            <appender-ref ref="AdoNetAppender"/>
        </root>
    </log4net>
</configuration>
test.cs
/// <summary>
/// AdoNetAppenderの設定
/// </summary>
private void updateLog4NetAdoNetAppender(string serverName, string userName, string password, string database)
{
    Hierarchy hierarchy = LogManager.GetRepository() as Hierarchy;
    if (hierarchy != null && hierarchy.Configured)
    {
        foreach (IAppender appender in hierarchy.GetAppenders())
        {
            if (appender is AdoNetAppender)
            {
                var adoNetAppender = (AdoNetAppender)appender;
                adoNetAppender.ConnectionString = string.Format("data source={0};integrated security=false;persist security info=True;User ID={1};Password={2};initial catalog={3}"
                    , serverName
                    , userName
                    , password
                    , databaseName);
                adoNetAppender.ActivateOptions();
            }
        }
    }
}

/// <summary>
/// カスタム項目の設定
/// </summary>
private void setLog4netProperties(string test)
{
        log4net.ThreadContext.Properties["test"] = test;
}

一様この方法で動作しているようですが、感知してない問題が有るかもしれません。

*1:を設定することでlog4netデバッグログを出力するようになる。