log4net ADO.NET Appender在Dev Fabric上工作正常,但在Azure上默默失败

6
我正在使用log4net的ADO.NET appender来记录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操作系统。 SQL连接显然是有效的。

请问有人能想到原因吗?为什么log4net可以从开发环境记录错误,但在使用完全相同的服务配置文件时,无法从Azure操作系统中记录错误?


没什么。为了一个简单的自定义记录器,完全放弃了log4net。 - Rinat Abdullin
3个回答

13

我刚遇到这个问题,花了大部分时间来尝试解决它。事实证明,SQL Azure需要在你的表上使用聚集索引。log4net提供的示例SQL代码创建Log表时没有聚集索引,而这是SQL Azure的要求。除非表具有聚集索引(截至撰写本文时),否则添加任何数据都将失败。

如果连接到SQL Azure并尝试使用SQL Server Management Studio手动插入语句,则会立即告诉您是否存在此问题。如果是这样,请运行以下SQL以在表上添加聚集索引(假设您直接使用了来自log4net的SQL),然后再次尝试。

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

3
我可能已经找到了这个问题的线索。我按照这里描述的方式启用了log4net的内部日志记录。记录一段时间后会停止工作。在log4net日志中导致错误的是以下内容:
log4net:ERROR [log4netDbAppender] Failed in DoAppend System.Data.SqlClient.SqlException (0x80131904): A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An established connection was aborted by the software in your host machine.),具体原因还需进一步了解。这篇文章总结了一般情况下处理此类异常的方法,并且可以使用该方法扩展AdoNetAppender。
编辑 设置AdoNetAppender.ReconnectOnError=true有助于解决问题,默认值为false。

0

这可能与您的SQL Azure防火墙规则有关吗?


很遗憾,否定回答。在开发环境和 Azure 场景中,CQRS 命令处理程序在同一工作角色内使用相同的 SQL Azure 连接字符串没有任何问题。 - Rinat Abdullin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接