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

时间:2016-06-07 15:51:23

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

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

1 个答案:

答案 0 :(得分:2)

正如您已设置reconnectOnError = true并且您正在使用适当低的连接超时,您处于正确的轨道 - 我认为这里的问题是您没有通过设置正确覆盖连接字符串,您应该改为覆盖set tmargin 0 set bmargin 0 set lmargin 1 set rmargin 1 set multiplot layout 4,1 margins 0.05,0.95,.1,.99 spacing 0,0 set xrange [0:10] unset xtics plot sin(x), sin(2*x) plot cos(x), cos(2*x) plot sin(x) set xtics plot cos(x) unset multiplot 以替换超时值:

ResolveConnectionString()