使log4net在数据库关闭后重新连接到数据库



我使用Log4Net Windows服务将日志保存在数据库中。我收到以下错误:

log4net:ERROR [CustomAdoNetAppender] ErrorCode: GenericFailure. Failed in DoAppend
System.Data.SqlClient.SqlException (0x80131904): Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (0x80004005): The wait operation timed out
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
   at System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync()
   at System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket()
   at System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer()
   at System.Data.SqlClient.TdsParserStateObject.TryReadByte(Byte& value)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)
   at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
   at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
   at System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction(IsolationLevel iso, String transactionName, Boolean shouldReconnect)
   at System.Data.SqlClient.SqlConnection.BeginTransaction(IsolationLevel iso, String transactionName)
   at System.Data.SqlClient.SqlConnection.BeginDbTransaction(IsolationLevel isolationLevel)
   at System.Data.Common.DbConnection.System.Data.IDbConnection.BeginTransaction()
   at log4net.Appender.AdoNetAppender.SendBuffer(LoggingEvent[] events)
   at log4net.Appender.BufferingAppenderSkeleton.Append(LoggingEvent loggingEvent)
   at log4net.Appender.AppenderSkeleton.DoAppend(LoggingEvent loggingEvent)
ClientConnectionId:a0b7de5e-2689-407b-b0da-5ebc733c0986
log4net: Attempting to reconnect to database. Current Connection State: Closed
log4net: Attempting to reconnect to database. Current Connection State: (null)
log4net: Attempting to reconnect to database. Current Connection State: (null)
log4net: Attempting to reconnect to database. Current Connection State: (null)
log4net: Attempting to reconnect to database. Current Connection State: (null)

我在服务窗口中的配置 Lo4Net 是:

<log4net>
    <appender name="AdoNetAppender" type="App.Uteis.CustomAdoNetAppender">
      <bufferSize value="1" />
      <reconnectonerror value="true" />
      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      <commandText value="INSERT INTO Log_Aplicacao ([Dt_Log],[Ds_Thread],[Ds_Nivel],[Ds_Servidor],[Ds_Aplicacao],[Ds_Login],[Ds_Log],[Ds_Mensagem],[Ds_Erro]) VALUES (@log_date, @thread, @log_level, @host_name,'AppMaster', @user_name, @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="@host_name" />
        <dbType value="String" />
        <size value="200" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%property{log4net:HostName}" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@user_name" />
        <dbType value="String" />
        <size value="150" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%username" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@logger" />
        <dbType value="String" />
        <size value="2000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%logger" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="8000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%message" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@exception" />
        <dbType value="String" />
        <size value="8000" />
        <layout type="log4net.Layout.ExceptionLayout" />
      </parameter>
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="AdoNetAppender" />
    </root>
  </log4net>

我的 CustomAdoNetAppender 类的配置是:

namespace AprovadorCartao.Uteis
{
    public class CustomAdoNetAppender : AdoNetAppender
    {
        public static RegistryKey _configRegistry = Registry.LocalMachine.OpenSubKey("Software\Conexao");
        public override void ActivateOptions()
        {
            PopulateConnectionString();
            base.ActivateOptions();
        }
        private void PopulateConnectionString()
        {
            ConnectionString = ConnectionString;
        }
        public new string ConnectionString
        {
            get { return base.ConnectionString; }
            set
            {
                base.ConnectionString = (string)_configRegistry.GetValue("Conexao") + ";Connect Timeout=1;";
            }
        }
    }
}

Log4Net 只有在重新启动服务后才能恢复正常(保存在数据库中)。

每当我的数据库出现错误时,Log4Net都会将数据保存在数据库中。是否有任何配置可以让 Log4Net 再次自动登录 Windows 服务?

由于您已经设置了reconnectOnError = true并且您正在使用适当低的连接超时,因此您走在正确的轨道上 - 我认为这里的问题是您没有通过设置正确覆盖连接字符串,您应该覆盖ResolveConnectionString()以替换超时值:

protected override string ResolveConnectionString(out string connectionStringContext)
{
    var connectionString = base.ResolveConnectionString(out connectionStringContext);
    if (string.IsNullOrEmpty(connectionString) || ReconnectOnError == false)
    {
        return connectionString;
    }
    var builder = new SqlConnectionStringBuilder(connectionString)
    {
        ConnectTimeout = 1; // Timeout value
    };
    return builder.ConnectionString;
}

相关内容

  • 没有找到相关文章

最新更新