【问题标题】:Make log4net reconnect to database after database down数据库关闭后使 log4net 重新连接到数据库
【发布时间】:2016-06-07 15:51:22
【问题描述】:

我使用 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服务?

【问题讨论】:

  • 如果数据库宕机,将日志记录在文件中
  • 我已经完成了,但我的问题是关于重新登录数据库

标签: c# windows-services log4net log4net-appender


【解决方案1】:

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

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 2013-10-16
    • 1970-01-01
    • 2017-09-05
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多