2016-01-20 23 views
4

任何人都可以帮我一个情况,其中NLog使用AsyncTargetWrapper登录到数据库,并且存在连接问题?我如何获得/拦截这些异常(因为异步目标不会抛出异常)?这似乎是一个很常见的情况,所以我很难相信InternalLogger是唯一的选择。下面是一个例子项目(需要安装NLOG NuGet包):NLog异步目标数据库连接异常 - 如何获取它们?

using System; 
using System.Threading; 
using NLog; 
using NLog.Common; 
using NLog.Config; 
using NLog.Targets; 
using NLog.Targets.Wrappers; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     LogManager.ThrowExceptions = true; 
     InternalLogger.LogToConsole = true; 
     InternalLogger.LogLevel = LogLevel.Error; 

     var conf = new LoggingConfiguration(); 
     var target = new DatabaseTarget 
     { 
      ConnectionString = 
       "Server=BAD_SERVER;Database=foo;", 
      CommandText = "INSERT INTO logs(message) VALUES ('bar')" 
     }; 

     var asyncTarget = new AsyncTargetWrapper(target); 
     var rule = new LoggingRule("*", LogLevel.Trace, asyncTarget); 
     conf.LoggingRules.Add(rule); 

     LogManager.Configuration = conf; 

     Logger logger = LogManager.GetLogger("Example"); 
     logger.Info("Message"); // doesn't throw an exception 

     Thread.Sleep(16000); 

     Console.WriteLine("\nDone"); 
     Console.ReadLine(); 
    } 
} 

因此,应用程序无法连接到服务器(无效的服务器名称在连接字符串)。一些默认后(隐藏在NLOG的胆量?)连接超时被击中,一个异常被InternalLogger打印到控制台:

2016-01-20 16:39:36.8466 Error Error when writing to database System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) 

现在,我知道我可以设置InternalLogger.LogFile(),但我有一个Web服务使用这个托管在Azure Web Apps上,并且在尝试时不会创建任何文件(我必须使用相对路径,该路径在控制台应用程序中本地运行,但在部署到Azure之后运行)。

如何使用异步NLog记录器处理连接异常?

回答

1

您可以尝试:带文件和数据库目标的备用包装器。

事情是这样的:

<targets> 
    <target xsi:type="FallbackGroup" name="target1" returnToFirstOnSuccess="true"> 
    <target xsi:type="Database" ... /> 
    <target xsi:type="File" ... /> 
    </target> 

这也应与<targets async="true">工作,但我会建议首先测试它没有异步。

编辑: 这是一个已知的问题,即使ThrowExceptions =true也不会抛出异常。我们正在研究这个,请参阅GitHub

现在,如果您在登录文件时遇到问题,可以选择another target,如Memory或MethodCall目标?

+0

谢谢。您的解决方案可以在本地使用,也可以使用异步。非常有用,但不幸的是它在部署到Azure后无法工作:(。我想应该有一些应用程序权限问题,我必须深入挖掘。最终,我宁愿抛出异常,因为我可以通知客户端如果我只是在Azure上创建该文件,那么您提出的解决方案就足够了。 – Caleb9