简体   繁体   English

NLog-MySQL数据库目标发生StackOverflow异常/NLog.NLogRuntimeException

[英]NLog - StackOverflow exception/NLog.NLogRuntimeException occurred with MySQL database target

I've configured NLog to log errors/logs to two MySQL/Database targets: 我已将NLog配置为将错误/日志记录到两个MySQL / Database目标中:

<nlog autoReload="false" internalLogFile="omg.txt" throwExceptions="true" xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <!--<nlog autoReload="false" xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">-->
  <variable name="DefaultLayout" value="${longdate} | ${uppercase:${level}} | ${logger} | ${message}&#xD;&#xA;     ${exception:innerFormat=ToString:maxInnerExceptionLevel=6:innerExceptionSeparator=InnerException:format=ToString}" />
  <targets>
    <target xsi:type="ColoredConsole" name="console" layout="${DefaultLayout}" />
    <target xsi:type="Null" name="nulltarget" formatMessage="false" layout="${DefaultLayout}" />
    <target xsi:type="Database"
          name="MySqlErrorTarget"
          dbProvider="MySql.Data.MySqlClient" connectionString="x"
          keepConnection="true">
      <commandText>
        CALL Error_Insert(@Message)
      </commandText>
      <parameter name="@Message" layout="${message}" />
      (...)
    </target>
    <target xsi:type="Database"
          name="MySqlLogTarget"
          dbProvider="MySql.Data.MySqlClient" connectionString="x"
          keepConnection="true">
      <commandText>
        CALL Log_Insert(@Message)
      </commandText>
      <parameter name="@Message" layout="${message}" />
      (...)
    </target>
  </targets>
  <rules>
    <logger name="*" levels="TRACE, DEBUG, INFO" writeTo="MySqlLogTarget"/>
    <logger name="*" levels="WARN, ERROR, FATAL" writeTo="MySqlErrorTarget"/>
    <logger name="*" minlevel="INFO" writeTo="console" />
  </rules>
</nlog>

When MySQL database is available everything works great, however when MySQL goes down, NLog throws StackOverflow exception. 当MySQL数据库可用时,一切正常,但是当MySQL关闭时,NLog会引发StackOverflow异常。 Internal log file looks like follows: 内部日志文件如下所示:

2016-03-21 15:36:33.0487 Error Error when writing to database MySql.Data.MySqlClient.MySqlException (0x80004005): Unable to connect to any of the specified MySQL hosts. ---> System.Net.Sockets.SocketException (0x80004005): No such host is known
   at System.Net.Dns.GetAddrInfo(String name)
   at System.Net.Dns.InternalGetHostByName(String hostName, Boolean includeIPv6)
   at System.Net.Dns.GetHostEntry(String hostNameOrAddress)
   at MySql.Data.Common.MyNetworkStream.CreateStream(MySqlConnectionStringBuilder settings, Boolean unix)
   at MySql.Data.Common.StreamCreator.GetStream(MySqlConnectionStringBuilder settings)
   at MySql.Data.MySqlClient.NativeDriver.Open()
   at MySql.Data.MySqlClient.NativeDriver.Open()
   at MySql.Data.MySqlClient.Driver.Open()
   at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings)
   at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()
   at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()
   at MySql.Data.MySqlClient.MySqlPool.GetConnection()
   at MySql.Data.MySqlClient.MySqlConnection.Open()
   at NLog.Targets.DatabaseTarget.OpenConnection(String connectionString)
   at NLog.Targets.DatabaseTarget.EnsureConnectionOpen(String connectionString)
   at NLog.Targets.DatabaseTarget.WriteEventToDatabase(LogEventInfo logEvent)
   at NLog.Targets.DatabaseTarget.Write(LogEventInfo logEvent)
2016-03-21 15:37:00.1794 Error Error when writing to database MySql.Data.MySqlClient.MySqlException (0x80004005): Unable to connect to any of the specified MySQL hosts. ---> System.Net.Sockets.SocketException (0x80004005): No such host is known
   at System.Net.Dns.GetAddrInfo(String name)
   at System.Net.Dns.InternalGetHostByName(String hostName, Boolean includeIPv6)
   at System.Net.Dns.GetHostEntry(String hostNameOrAddress)
   at MySql.Data.Common.MyNetworkStream.CreateStream(MySqlConnectionStringBuilder settings, Boolean unix)
   at MySql.Data.Common.StreamCreator.GetStream(MySqlConnectionStringBuilder settings)
   at MySql.Data.MySqlClient.NativeDriver.Open()
   at MySql.Data.MySqlClient.NativeDriver.Open()
   at MySql.Data.MySqlClient.Driver.Open()
   at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings)
   at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()
   at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()
   at MySql.Data.MySqlClient.MySqlPool.GetConnection()
   at MySql.Data.MySqlClient.MySqlConnection.Open()
   at NLog.Targets.DatabaseTarget.OpenConnection(String connectionString)
   at NLog.Targets.DatabaseTarget.EnsureConnectionOpen(String connectionString)
   at NLog.Targets.DatabaseTarget.WriteEventToDatabase(LogEventInfo logEvent)
   at NLog.Targets.DatabaseTarget.Write(LogEventInfo logEvent)

This goes infinitely, thus in the end StackOverflow occurs. 这是无限进行的,因此最终会发生StackOverflow。 Exception reported in Visual Studio looks like follows: Visual Studio中报告的异常如下所示:

NLog.NLogRuntimeException occurred
  HResult=-2146233088
  Message=Exception occurred in NLog
  Source=NLog
  StackTrace:
       at NLog.LoggerImpl.<>c__DisplayClass1.<Write>b__0(Exception ex)
       at NLog.Internal.SingleCallContinuation.Function(Exception exception)
       at NLog.Targets.Target.Write(AsyncLogEventInfo logEvent)
       at NLog.Targets.Target.WriteAsyncLogEvent(AsyncLogEventInfo logEvent)
       at NLog.LoggerImpl.WriteToTargetWithFilterChain(TargetWithFilterChain targetListHead, LogEventInfo logEvent, AsyncContinuation onException)
       at NLog.LoggerImpl.Write(Type loggerType, TargetWithFilterChain targets, LogEventInfo logEvent, LogFactory factory)
       at NLog.Logger.Debug(String message)
       at Runner.Main(String[] args) in C:\Repos\x\src\Runner.cs:line 36
  InnerException: 
       ErrorCode=-2147467259
       HResult=-2147467259
       Message=Unable to connect to any of the specified MySQL hosts.
       Number=1042
       Source=MySql.Data
       StackTrace:
            at MySql.Data.MySqlClient.NativeDriver.Open()
            at MySql.Data.MySqlClient.Driver.Open()
            at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings)
            at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()
            at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()
            at MySql.Data.MySqlClient.MySqlPool.GetConnection()
            at MySql.Data.MySqlClient.MySqlConnection.Open()
            at NLog.Targets.DatabaseTarget.OpenConnection(String connectionString)
            at NLog.Targets.DatabaseTarget.EnsureConnectionOpen(String connectionString)
            at NLog.Targets.DatabaseTarget.WriteEventToDatabase(LogEventInfo logEvent)
            at NLog.Targets.DatabaseTarget.Write(LogEventInfo logEvent)
            at NLog.Targets.Target.Write(AsyncLogEventInfo logEvent)
       InnerException: 
            ErrorCode=11001
            HResult=-2147467259
            Message=No such host is known
            NativeErrorCode=11001
            Source=System
            StackTrace:
                 at System.Net.Dns.GetAddrInfo(String name)
                 at System.Net.Dns.InternalGetHostByName(String hostName, Boolean includeIPv6)
                 at System.Net.Dns.GetHostEntry(String hostNameOrAddress)
                 at MySql.Data.Common.MyNetworkStream.CreateStream(MySqlConnectionStringBuilder settings, Boolean unix)
                 at MySql.Data.Common.StreamCreator.GetStream(MySqlConnectionStringBuilder settings)
                 at MySql.Data.MySqlClient.NativeDriver.Open()
            InnerException: 

I've tried changing the rules to: 我尝试将规则更改为:

  <rules>
    <logger name="NLog.*" minlevel="TRACE" writeTo="nulltarget" final="true"/>
    <logger name="MySql.*" minlevel="TRACE" writeTo="nulltarget" final="true"/>
    <logger name="System.*" minlevel="TRACE" writeTo="nulltarget" final="true"/>
    <logger name="*" levels="TRACE, DEBUG, INFO" writeTo="MySqlLogTarget"/>
    <logger name="*" levels="WARN, ERROR, FATAL" writeTo="MySqlErrorTarget"/>
    <logger name="*" minlevel="INFO" writeTo="console" />
  </rules>

However, it doesn't help. 但是,它没有帮助。 Any ideas how can I avoid the StackOverflowException? 有什么想法可以避免StackOverflowException吗?

Set throwExceptions on <nlog to false . throwExceptions关于<nlog ,以false The connection exception will be ignored by NLog and NLog won't try to log it to the database. 连接异常将被NLog忽略,并且NLog不会尝试将其记录到数据库中。

Turns out that somewhere in my code base was this line invoked: 原来,在我的代码库中某个地方调用了此行:

Trace.Listeners.Add(new NLogTraceListener());

Which caused that error log from MySql was redirected to Trace, and thanks to the NLogTraceListener, it was logged by NLog using MySql target, which failed and was redirected to Trace, and thanks to the NLogTraceListener, it was logged by NLog using MySql target, which... you know how this goes. 导致将来自MySql的错误日志重定向到Trace,这要归功于NLogTraceListener,它是由NLog使用MySql目标记录的,失败了,并被重定向到了Trace,感谢NLogTraceListener,它是由NLog使用MySql目标记录的,哪...你知道这是怎么回事。

I didn't come up with a nice solution since there is no enough info to filter the logs in the TraceListener (just a message as a string). 因为没有足够的信息来过滤TraceListener中的日志(只是一条消息作为字符串),所以我没有提出一个好的解决方案。 Therefore I've turned off the NLogTraceListener temporarily, as it's not crucial to have it on. 因此,我暂时关闭了NLogTraceListener,因为打开它并不关键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM