6

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

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

<?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 操作系统。SQL 连接显然是有效的。

请任何人想一想为什么 log4net 从开发结构记录错误,但无法从 azure OS 使用完全相同的服务配置文件执行此操作的原因?

4

3 回答 3

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
于 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.TdsParser 的 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔中断连接)。 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) 在 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 回答