0

実行時に定義する ConnectionString を使用したいと考えています。多くの例を見つけましたが、機能させることはできません。

カスタム AdoNetAppender を作成しました。

 public class AdoNetMultiTenantAppender : AdoNetAppender
{
    public new string ConnectionString
    {
        get
        {
            return base.ConnectionString;
        }

        set
        {
            base.ConnectionString = Tenant.Current.DataSource.ConnectionString; // Return the connection string
        }
    }
}

私は次の構成を持っています:

<appender name="AdoNetMultiTenantAppender" type="MyNameSpace.AdoNetMultiTenantAppender">
    <bufferSize value="1" />
    <connectionstring value="" />
    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <commandText value="[...]" />
    <parameter>
        [...]
    </parameter>
</appender>

私のロガーは、構成ファイルで次のように定義されています。

  <logger name="ProcessLogger" additivity="false">
    <level value="INFO"/>
    <appender-ref ref="AdoNetMultiTenantAppender"/>
  </logger>

そして最後に、私のコードでロガーを取得するには、次のことを行っています。

[...]    
private static readonly ILog Logger = LogManager.GetLogger("ProcessLogger");
[...]
ProcessLogger.Logger.Info(message);
[...]

接続文字列を構成に「ハードコード」しようとすると、機能します。しかし、いくつかの変数に応じて別の ConnectionString が必要なため、これを行うことはできません。カスタムアペンダーに入れたプロパティ ConnectionString は決して呼び出されません。私が何かを見逃している場所はありますか?

4

2 に答える 2

2

どのバージョンの log4net を使用していますか?

いずれにせよ、new派生クラスの ConnectionString プロパティは、既存のインフラストラクチャから自動的に呼び出されることはありません。

適切な仮想メンバーをオーバーライドすることで、より成功する可能性があります。たとえば、log4net 1.2.11 を使用している場合は、CreateConnectionorResolveConnectionStringメソッドをオーバーライドできます。

コメントに応じて更新:

ただし、CreateConnection は 1 回しか使用されないため、複数の ConnectionString に対して同じアペンダーを使用することはできません。

はい、log4netAdoNetAppenderは、接続オブジェクトを開いたままにし、ログ要求ごとに再利用するという点で、通常とは異なる設計になっています。これは、データベース接続をできるだけ遅く作成/開き、使用後すぐに閉じるという通常の推奨されるアプローチとは対照的です。推奨されるアプローチにより、アプリケーションは ADO.NET の組み込みの接続プールを利用できます。

あなたが試すことができることの1つは、オーバーライドすることSendBuffer(LoggingEvent[] events)であり、オーバーライドで基本クラスを呼び出してから接続を閉じます。SendBufferこれにより、が呼び出される たびに接続が強制的に再度開かれます。

ただし、これで必要なものがすべて得られるかどうかはわかりません-複数の接続文字列を使用するマルチテナントアプリケーションについて話します。この場合、LoggingEvent渡された の配列にSendBufferは、異なる接続に送信する必要があるイベントが含まれる場合があります。おそらく、何らかの属性を使用LoggingEventして入力配列をターゲット接続ごとに分割し、各ターゲット接続に対して接続を開き、呼び出してから接続base.SendBufferを閉じる必要があります。

于 2015-01-28T22:21:28.693 に答える