6

log4net アペンダー ADO.NET を使用して、Azure ワーカー ロールのメッセージを SQL Azure インスタンスに記録しています (既定の診断は適合しません)。何らかの理由で、dev ファブリックでワーカーを実行しているときに、ログが機能します。ただし、インスタンスが (まったく同じ構成で) クラウドにデプロイされると、エラーはログに記録されません。

構成は、このファイルを使用してコードで行われます。

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <renderer renderingClass="{ExceptionRenderer}" renderedClass="System.Exception" />
  <appender name="TraceAppender" type="log4net.Appender.TraceAppender">
    <layout type="log4net.Layout.PatternLayout">
      <!--<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />-->
      <conversionPattern value="%message%newline" />
    </layout>
  </appender>
  <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
    <bufferSize value="3" />
    <connectionType value="{ConnectionType}" />
    <connectionString value="{ConnectionString}" />
    <commandText value="INSERT INTO Salescast_Log ([Date],[Thread],[Version],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, '{Version}',@log_level, @logger, @message, @exception)" />
    <parameter>
      <parameterName value="@log_date" />
      <dbType value="DateTime" />
      <layout type="log4net.Layout.RawTimeStampLayout" />
    </parameter>
    <parameter>
      <parameterName value="@thread" />
      <dbType value="String" />
      <size value="255" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%thread" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@log_level" />
      <dbType value="String" />
      <size value="50" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%level" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@logger" />
      <dbType value="String" />
      <size value="255" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%logger" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@message" />
      <dbType value="String" />
      <size value="4000" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%message" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@exception" />
      <dbType value="String" />
      <size value="4000" />
      <layout type="{ExceptionLayoutType}" />
    </parameter>
    <filter type="log4net.Filter.LevelRangeFilter">
      <levelMin value="ERROR" />
      <levelMax value="FATAL" />
    </filter>
  </appender>
  <root>
    <level value="DEBUG" />
    <appender-ref ref="TraceAppender" />
    <appender-ref ref="AdoNetAppender" />
  </root>
</log4net>

Autofac IoC 環境が (ロールの起動ごとに) 初期化されると、log4net は適切な値で初期化されます。コードは次のようになります。

static ILogProvider BuildProvider(IComponentContext context)
{
  var connection = context
    .Resolve<IProvideBusSettings>()
    .GetString("SqlConnection")
    .ExposeException("Failed to get SQL string for logging");

  var xml = Properties.Resources.Logging
    .Replace("{ConnectionType}", typeof(SqlConnection).AssemblyQualifiedName)
    .Replace("{ConnectionString}", connection)
    .Replace("{ExceptionLayoutType}", typeof(LoggingTrimmedExceptionLayout).AssemblyQualifiedName)
    .Replace("{ExceptionRenderer}", typeof(LoggingExceptionRenderer).AssemblyQualifiedName)
    .Replace("{Version}", SystemDescriptor.Default.Version.ToString());

  var doc = new XmlDocument();
  doc.LoadXml(xml);
  XmlConfigurator.Configure(doc.DocumentElement);
  return new LoggingProvider();
}

デフォルトの Azure OS が使用されます。SQL 接続は明らかに有効です。

まったく同じサービス構成ファイルを使用して、log4net が開発ファブリックからエラーをログに記録するのに、azure OS からはエラーをログに記録できない理由を誰か考えてください。

4

3 に答える 3

13

私はちょうどこれに出くわし、それを理解しようとして一日の大部分を費やしました。SQL Azure では、テーブルにクラスター化されたインデックスが必要であるという事実にたどり着きました。ログ テーブルを作成するために log4net が提供する SQL コードの例には、SQL Azure の要件であるクラスター化インデックスがありません。クラスター化されたインデックスがない限り、テーブルにデータを追加すると失敗します (これが書かれている時点で)。

SQL Azure に接続しているときに、SQL Server Management Studio を使用して手動で挿入ステートメントを実行してみてください。これが問題であるかどうかがすぐにわかります。その場合は、次の SQL を実行してテーブルにクラスター化インデックスを追加し (log4net から直接 SQL を使用したと仮定)、再試行してください。

CREATE UNIQUE CLUSTERED INDEX PK_Log ON [Log]
  ([Id])
GO
于 2011-11-27T03:29:17.193 に答える
3

この問題につながる可能性があります。ここで説明されているように、log4net の内部ログを有効にしました。ロギングはしばらく機能し、その後停止します。log4net ログの原因となったエラーは次のとおりです。

log4net:ERROR [log4netDbAppender] Failed in DoAppend System.Data.SqlClient.SqlException (0x80131904): サーバーに要求を送信するときにトランスポート レベルのエラーが発生しました。(プロバイダー: TCP プロバイダー、エラー: 0 - 確立された接続は、ホスト コンピューターのソフトウェアによって中止されました。) System.Data.SqlClient.SqlConnection.OnError (SqlException 例外、ブール値の breakConnection) で System.Data.SqlClient.TdsParser で。 System.Data.SqlClient.TdsParserStateObject.WriteSni() での ThrowExceptionAndWarning() System.Data.SqlClient.TdsParserStateObject.ExecuteFlush() での System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray、Int32 タイムアウト、Boolean inSchema、SqlNotificationRequest notificationRequest、TdsParserStateObject stateObj、Boolean isCommandProc) を System.Data.SqlClient.SqlCommand に設定します。
log4net.Appender.BufferingAppenderSkeleton.Append (LoggingEvent loggingEvent) で log4net.Appender.AppenderSkeleton.DoAppend (LoggingEvent loggingEvent) で

このエラーが発生した後、log4net は試行を停止したようです。この記事では、この種の例外を一般的に処理する方法について説明し、これを使用して AdoNetAppender を拡張できます。

編集 AdoNetAppender.ReconnectOnError=true を設定すると役立つ場合があります。デフォルトでは false です。

于 2011-08-03T20:29:34.023 に答える
0

SQL Azure ファイアウォール ルールの問題でしょうか?

于 2010-05-18T18:12:58.907 に答える