log4net ADO.NET Appender适用于Dev Fabric,但在Azure上无声地失败

时间:2010-05-18 15:49:47

标签: .net log4net azure azure-sql-database

我正在使用log4net appender ADO.NET将Azure Worker Role的消息记录到SQL Azure实例(默认诊断不适合)。出于某种原因,在开发结构中运行worker时,日志记录工作。然而,当实例部署到云(具有完全相同的配置)时,错误不会被记录。

使用此文件在代码中进行配置:

<?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操作系统执行此操作?

3 个答案:

答案 0 :(得分:13)

我刚刚碰到这个并花了一天的大部分时间试图解决这个问题。归结为SQL Azure需要在表上使用聚簇索引。 log4net提供的用于创建Log表的示例SQL代码没有聚集索引,这是SQL Azure的要求。除非它具有聚集索引(截至编写本文时),否则将所有数据添加到表中都将失败。

尝试在连接到SQL Azure时使用SQL Server Management Studio执行手动插入语句,如果出现此问题,它会立即告诉您。如果是这样,运行以下SQL在表上添加聚簇索引(假设您使用了log4net中的SQL直接),然后再试一次。

CREATE UNIQUE CLUSTERED INDEX PK_Log ON [Log]
  ([Id])
GO

答案 1 :(得分:3)

我可能会引导这个问题。我按照here所述为log4net启用了内部日志记录。日志记录会工作一段时间,然后就会停止。 log4net日志中导致的错误是:

  

log4net:错误[log4netDbAppender]在DoAppend中失败   System.Data.SqlClient.SqlException(0x80131904):传输级别   将请求发送到服务器时发生错误。 (服务提供商:   TCP提供程序,错误:0 - 建立的连接被中止   主机上的软件。)at   System.Data.SqlClient.SqlConnection.OnError(SqlException异常,   Boolean breakConnection)at   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()at   System.Data.SqlClient.TdsParserStateObject.WriteSni()at   System.Data.SqlClient.TdsParserStateObject.ExecuteFlush()at   System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC [] rpcArray,   Int32 timeout,Boolean inSchema,SqlNotificationRequest   notificationRequest,TdsParserStateObject stateObj,Boolean   isCommandProc)at   System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(的CommandBehavior   cmdBehavior,RunBehavior runBehavior,Boolean returnStream,Boolean   async)at   System.Data.SqlClient.SqlCommand.RunExecuteReader(的CommandBehavior   cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String   方法,DbAsyncResult结果)at   System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult   result,String methodName,Boolean sendToPipe)at   System.Data.SqlClient.SqlCommand.ExecuteNonQuery()at   log4net.Appender.AdoNetAppender.SendBuffer(IDbTransaction dbTran,   LoggingEvent []事件)at   log4net.Appender.AdoNetAppender.SendBuffer(LoggingEvent [] events)
  在log4net.Appender.BufferingAppenderSkeleton.Append(LoggingEvent   loggingEvent)at   log4net.Appender.AppenderSkeleton.DoAppend(LoggingEvent loggingEvent)

似乎log4net在遇到此错误后停止尝试。 This文章描述了一种处理此类异常的方法,这可用于扩展AdoNetAppender。

修改 设置AdoNetAppender.ReconnectOnError = true可能有所帮助,默认情况下为false。

答案 2 :(得分:0)

这可能是您的SQL Azure防火墙规则的问题吗?