Can anyone help me with a situation where NLog is logging into a database using AsyncTargetWrapper
and there is a connection problem? How can I obtain/intercept those exceptions (since async targets don't throw exceptions)? It seems to be a pretty common scenario so I find it hard to believe that InternalLogger
is the only option. Here's an example project (requires NLog nuget package installed):
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();
}
}
So the app can't connect to the server (invalid server name in connection string). After some default (hidden in NLog's guts?) connection timeout is hit, an exception is printed to the console by 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)
Now, I know I can set InternalLogger.LogFile()
but I have to use this in a Web service hosted on Azure Web Apps and it doesn't create any file when I try that (I have to use relative path, which works locally in a console app but not after deployment to Azure).
How one deals with connection exceptions when using async NLog logger?
You can try: a fallback-wrapper with a file and DB target.
Something like this:
<targets>
<target xsi:type="FallbackGroup" name="target1" returnToFirstOnSuccess="true">
<target xsi:type="Database" ... />
<target xsi:type="File" ... />
</target>
That should also work with <targets async="true">
, but I would advise to test it first without async.
Edit:
It's a known issue that exceptions are not thrown even if ThrowExceptions =true
. We're working on this, see GitHub.
For now, if you have trouble logging to file, you can choose another target, like the Memory or MethodCall target?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With