I have NLog 4.2.3 configured to write to a database and a text file using the following config:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogLevel="Error" internalLogFile="C:/tmp/NLog.txt">
<targets>
<target name="database" xsi:type="Database" dbProvider="Npgsql.NpgsqlFactory,Npgsql,Version=2.0.12.00,Culture=neutral,PublicKeyToken=5d8b90d52f46fda7" connectionString="Server=xxx.xxx.xxx.xxx;Port=5432;User Id=userid;Password=password;Database=testdb;">
<commandText>INSERT INTO invoice_log (message, level, logger) VALUES (#msg, #level, #logger)</commandText>
<parameter name="#msg" layout="${message}" />
<parameter name="#level" layout="${level}" />
<parameter name="#logger" layout="${logger}" />
</target>
<target name="log" xsi:type="File" layout="${longdate} | ${logger} | ${level:uppercase=true}: ${message}" fileName="${basedir}/Logs.txt" keepFileOpen="false" encoding="iso-8859-2" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="database" />
<logger name="*" minlevel="Trace" writeTo="log" />
</rules>
</nlog>
I'm trying to log a simple Info message. It logs correctly to the text file, but it fails for the database and I get the following error in the NLog internal log file:
Error Error when writing to database System.MissingMethodException: No parameterless constructor defined for this object.
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
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)
I have looked at configs from other similar questions (NLog is not writing to database table, NLog to PostgreSQL connection), but I can't see what is missing from mine?
According to the nlog docs, dbProvider is an invariant name for a factory registered in a config file OR the fully qualified name of a type that implements IDbConnection. Npgsql.NpgsqlConnection implements the required interface and has a parameterless contructor. NpgsqlFactory does not and it does not have a parameterless constructor (the cause of the error).
Related
I want to log the errors from my C# app in Windows Event Viewer using log4net with the EventLogAppender (the errors must be logged under the Application log)
I have a log4net.config class with this code
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a" />
</configSections>
<log4net>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
<applicationName value="MySource" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="{%level} {%date} – %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="EventLogAppender" />
</root>
</log4net>
</configuration>
In AssemblyInfo I added the following line
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch=true)]
Then in my Program class
class Program
{
static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
static void Main(string[] args)
{
string name=null;
try
{
Console.WriteLine("Name : " + name.ToString());
}
catch (NullReferenceException nullException)
{
log.Error("Name is NULL", nullException);
}
}
}
I have to mention that I used power shell to create a new EventLog called "MySource"
The problem is that I receive the following error:
log4net:ERROR Could not create Appender [EventLogAppender] of type [log4net.Appender.EventLogAppender]. Reported error follows.
System.TypeLoadException: Could not load type 'log4net.Appender.EventLogAppender' from assembly 'log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a'.
at System.Reflection.RuntimeAssembly.GetType(QCallAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type, ObjectHandleOnStack keepAlive, ObjectHandleOnStack assemblyLoadContext)
at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
at log4net.Util.SystemInfo.GetTypeFromString(Assembly relativeAssembly, String typeName, Boolean throwOnError, Boolean ignoreCase)
at log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseAppender(XmlElement appenderElement)
log4net:ERROR Appender named [EventLogAppender] not found.
Latest version of log4net (2.0.8 as of today) is implementing .net standard 1.3: https://logging.apache.org/log4net/release/release-notes.html.
In .net standard 1.3 EventLogAppender is not supported: https://logging.apache.org/log4net/release/framework-support.html#netstandard-1.3
If you want to use EventLogAppender, you will have to switch to .net framework.
I've configured NLog to log errors/logs to two MySQL/Database targets:
<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}
${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. 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. Exception reported in Visual Studio looks like follows:
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?
Set throwExceptions on <nlog to false. The connection exception will be ignored by NLog and NLog won't try to log it to the database.
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.
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). Therefore I've turned off the NLogTraceListener temporarily, as it's not crucial to have it on.
When I throw an exception in a handler for a message type, then the exception is logged with UTCDate, however this should be the computer date.
The weird thing is that it logs it correctly and then logs in wrong, so multiple log messages are added to the file. This is not needed!
The correct time in the log below is 2014-02-18 14:... and the wrong time is 18-02-2014 13:....
I do not need the log with the wrong time
Log:
2014-02-18 14:08:43,616 WARN Rebus 1 worker 1 Rebus.Bus.RebusBus - User exception in Rebus 1 worker 1: System.IO.IOException: Error writing to file ---> System.UnauthorizedAccessException: Access to the path 'X' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode)
at X.Y(X X, X X, X X) in X:line 538
--- End of inner exception stack trace ---
at X.Y(X X, X X, X X) in X:line 546
at Rebus.Bus.Dispatcher.DispatchToHandler[TMessage](TMessage message, IHandleMessages`1 handler)
18-02-2014 13:08:43:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.IOException: Error writing to file ---> System.UnauthorizedAccessException: Access to the path 'X' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode)
at X.Y(X X, X X, X X) in X:line 538
--- End of inner exception stack trace ---
at X.Y(X X, X X, X X) in X:line 546
at Rebus.Bus.Dispatcher.DispatchToHandler[TMessage](TMessage message, IHandleMessages`1 handler)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Rebus.Bus.Dispatcher.Dispatch[TMessage](TMessage message)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Rebus.Bus.Worker.DoTry()
at Rebus.Bus.Worker.TryProcessIncomingMessage()
at Rebus.Bus.Worker.MainLoop()
Log4NetConfiguration:
<log4net>
<logger name="NHibernate">
<level value="ERROR" />
</logger>
<logger name="NHibernate.SQL">
<level value="ERROR" />
</logger>
<!-- The DebugFileAppender writes all messages to a log file-->
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="X" />
<appendToFile value="true" />
<maximumFileSize value="10000KB" />
<maxSizeRollBackups value="10" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level %thread %logger - %message%newline" />
</layout>
</appender>
<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="ERROR" />
<forecolor value="Red" />
</mapping>
<mapping>
<level value="DEBUG" />
<forecolor value="Yellow" />
</mapping>
<mapping>
<level value="INFO" />
<forecolor value="White" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionpattern value="%date [%thread] %logger %-5level - %message%newline" />
</layout>
</appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
<!--<param name="LogName" value="X" />-->
<param name="ApplicationName" value="X" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %newline %type %newline %method %newline %message %newline %exception" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="WARN" />
<levelMax value="FATAL" />
</filter>
</appender>
<root>
<!-- add other appenders here and the log messages will be sent to every listed appender -->
<appender-ref ref="EventLogAppender" />
<appender-ref ref="RollingFile" />
<appender-ref ref="ColoredConsoleAppender" />
</root>
</log4net>
Rebus logging setup:
var rebusConfigurer = Configure.With(new WindsorContainerAdapter(container))
.Logging(l => l.Log4Net()).Transport(t => t.UseMsmqAndGetInputQueueNameFromAppConfig())
.MessageOwnership(o => o.FromRebusConfigurationSection())
.X(s => s.StoreInSqlServer(() => (SqlConnection)container.Resolve<ISession>().Connection, "X", "X"))
.SpecifyOrderOfHandlers(s => s.Use(new MyMessageHandlerInspector()));
Exception being caught by Rebus
throw new IOException("Error writing to file", exception);
How do I prevent or configure how rebus logs this? As you can see in the log, some of the rebus logging is ok, and other is not.
The thing is that Rebus keeps track of caught exceptions including their timestamps between retries, which is dnoe by keeping a list of Timed<Exception> instances around - and it used to initialize each with DateTime.UtcNow.
I've changed it in Rebus 0.57.0 though to use DateTime.Now, because I agree with you that it doesn't make sense - or at least it looks pretty weird alongside Log4Net's timestamps :)
I'm getting a weird exception when trying to initialize NLog instance as a static class member (update: this is happening in a desktop app which is targeting .NET 4.0).
The problem is, I'm getting it only on one specific client machine, and can't reproduce on any of my development configurations. Can someone point me in a direction, what should I look for?
PS: User tried to run the app with administrator rights as well, getting same exception.
System.Configuration.ConfigurationErrorsException: An error occurred creating the configuration section handler for nlog: Request for permission of type "System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" failed. (C:\Users\XXX\Desktop\Test.exe.Config line 9) ---> System.Security.SecurityException: Request for permission of type "System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" failed.
in System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
in System.Security.CodeAccessPermission.Demand()
in System.AppDomainSetup.VerifyDir(String dir, Boolean normalize)
in NLog.Internal.Fakeables.AppDomainWrapper..ctor(AppDomain appDomain)
in NLog.Internal.Fakeables.AppDomainWrapper.get_CurrentDomain()
in NLog.Config.ConfigSectionHandler.System.Configuration.IConfigurationSectionHandler.Create(Object parent, Object configContext, XmlNode section)
in System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionImpl(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
in System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionWithRestrictedPermissions(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
in System.Configuration.RuntimeConfigurationRecord.CreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
in System.Configuration.BaseConfigurationRecord.CallCreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader, String filename, Int32 line)
--- End of inner exception stack trace ---
in System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)
in System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)
in System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
in System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
in System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
in System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
in System.Configuration.ConfigurationManager.GetSection(String sectionName)
in NLog.Config.XmlLoggingConfiguration.get_AppConfig()
in NLog.LogFactory.get_Configuration()
in NLog.LogFactory.GetLogger(LoggerCacheKey cacheKey)
in NLog.LogFactory.GetLogger(String name)
in NLog.LogManager.GetCurrentClassLogger()
Update (config file)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="Test.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="logfile" xsi:type="File" fileName="log-${machinename}.txt" layout="${longdate} ${level:uppercase=True} ${logger} ${message} ${exception:format=ToString,StackTrace}" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>
</nlog>
<applicationSettings>
<Test.Properties.Settings>
<setting name="servers" serializeAs="Xml">
<value>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>111</string>
<string>222</string>
</ArrayOfString>
</value>
</setting>
</Test.Properties.Settings>
</applicationSettings>
</configuration>
NLog is instantiated this way (static field on a class):
private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
SOLUTION is to remove "untrusted origin" flag from application .config file using "unblock" button in file properties, or Sysinternals Streams tool
Thanks to #giammin who pointed me in right direction (trust level)!
Stupid me. It turns out that the cause of the problem was pretty obvious: it was result of Attachment Manager work. "Untrusted origin" flag (Zone.Identifier alternate data stream) was set on downloaded archive which contained app files.
What was unexpected for me in this, is that:
I thought that only IE implements this "protective measure". Turns out, I was wrong - user downloaded the file via Chrome, which also sets this flag. Firefox doesn't set it (I checked on the latest versions to date).
Flag was copied to files from archive (zip) after extraction. This happened, I believe, because user extracted files using built-in Windows archive tool.
The direct cause of this problem was not a flag on assembly or executable files, but rather a flag on .config file itself. Once it was removed, problem disappeared. Flags on .exe/.dll files do not contribute to the problem in any way.
I'm still not sure why this only happens on .net 4.0, and disappears when .net 4.5 is installed (application files are exactly the same).
to debug nlog you can use its internal logging:
<nlog autoReload="true" throwExceptions="true" internalLogFile="c:\log.txt" internalLogLevel="Trace">
---UPDATE---
Another check could be to move the config to an external file:
<configSections>
...
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<nlog configSource="NLog.config" />
NLog.config:
<?xml version="1.0"?>
<nlog autoReload="true" throwExceptions="true" internalLogFile="c:\log.txt" internalLogLevel="Trace">
...
</nlog>
Anyway It seems that the application is not running in FullTrust.
----UPDATE2----
Try to add this requirePermission="false" in
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" requirePermission="false"/>
I'm trying to setup NLog to send mail and use my system settings (with a pickup directory) as documented here
Here's my NLog configuration
<nlog internalLogLevel="Trace" internalLogFile="C:\NLogInternal.log" throwExceptions="true" autoReload="true" xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="logfile" xsi:type="File" fileName="c:\backupservice.log.txt" layout="${longdate} ${callsite} ${level} ${message}"/>
<target name="console" xsi:type="Console" />
<target xsi:type="EventLog"
name="event"
layout="${longdate} ${callsite} ${level} ${message}"
source="BackupService"
eventId="898"
log="BackupService"
/>
<target xsi:type="Mail"
name="email"
useSystemNetMailSettings="True"
layout="${longdate} ${callsite} ${level} ${message}" />
</targets>
<rules>
<logger name="*" minlevel="Fatal" writeTo="email" />
<logger name="*" minLevel="Info" writeTo="event" />
<logger name="*" minLevel="Debug" writeTo="console" />
</rules>
Here is my mail setting:
<system.net>
<mailSettings>
<smtp from="backup#[COMPANY].com" deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="C:\testmail\Pickup" />
<network host="mail.[COMPANY].com" password="[PASSWORD]" userName="[EMAIL_ADDRESS]" />
</smtp>
</mailSettings>
Here is the output from NLog's internal logging:
** SNIP **
2013-06-20 17:41:03.8368 Debug Setting 'MailTarget.name' to 'email'
2013-06-20 17:41:03.8368 Debug Setting 'MailTarget.useSystemNetMailSettings' to 'True'
2013-06-20 17:41:03.8688 Error Error System.NotSupportedException: Parameter useSystemNetMailSettings not supported on MailTarget
at NLog.Internal.PropertyHelper.SetPropertyFromString(Object o, String name, String value, ConfigurationItemFactory configurationItemFactory)
at NLog.Config.XmlLoggingConfiguration.ConfigureObjectFromAttributes(Object targetObject, NLogXmlElement element, Boolean ignoreType)
at NLog.Config.XmlLoggingConfiguration.ParseTargetElement(Target target, NLogXmlElement targetElement)
at NLog.Config.XmlLoggingConfiguration.ParseTargetsElement(NLogXmlElement targetsElement)
at NLog.Config.XmlLoggingConfiguration.ParseNLogElement(NLogXmlElement nlogElement, String baseDirectory)
at NLog.Config.XmlLoggingConfiguration.ParseTopLevel(NLogXmlElement content, String baseDirectory)
at NLog.Config.XmlLoggingConfiguration.Initialize(XmlReader reader, String fileName, Boolean ignoreErrors)...
2013-06-20 17:41:03.8688 Error ConfigSectionHandler error: NLog.NLogConfigurationException: Exception occurred when loading configuration from C:\Projects\Fee\WindowsServices\BackupService\BackupService\bin\Debug\BackupService.vshost.exe.Config ---> System.NotSupportedException: Parameter useSystemNetMailSettings not supported on MailTarget
at NLog.Internal.PropertyHelper.SetPropertyFromString(Object o, String name, String value, ConfigurationItemFactory configurationItemFactory)
at NLog.Config.XmlLoggingConfiguration.ConfigureObjectFromAttributes(Object targetObject, NLogXmlElement element, Boolean ignoreType)
at NLog.Config.XmlLoggingConfiguration.ParseTargetElement(Target target, NLogXmlElement targetElement)
at NLog.Config.XmlLoggingConfiguration.ParseTargetsElement(NLogXmlElement targetsElement)
at NLog.Config.XmlLoggingConfiguration.ParseNLogElement(NLogXmlElement nlogElement, String baseDirectory)
at NLog.Config.XmlLoggingConfiguration.ParseTopLevel(NLogXmlElement content, String baseDirectory)
at NLog.Config.XmlLoggingConfiguration.Initialize(XmlReader reader, String fileName, Boolean ignoreErrors)
--- End of inner exception stack trace ---
at NLog.Config.XmlLoggingConfiguration.Initialize(XmlReader reader, String fileName, Boolean ignoreErrors)
at NLog.Config.XmlLoggingConfiguration..ctor(XmlElement element, String fileName)
at NLog.Config.ConfigSectionHandler.System.Configuration.IConfigurationSectionHandler.Create(Object parent, Object configContext, XmlNode section)
I'm not sure what I'm doing wrong or if it's a bug in Nlog.
NB: I've tried both useSystemNetMailSettings and UseSystemNetMailSettings.
So I didn't get NLog to work specifically through NLog but I used a work around. NLog has a "MethodCall" target that I used like so:
<target name="sendmail" xsi:type="MethodCall" className="BackupLib.Email, BackupLib" methodName="Send">
<parameter layout="backupservice#[COMPANY].com" />
<parameter layout="backups#[COMPANY].com" />
<parameter layout="FATAL ERROR: Backup Service on ${machinename}" />
<parameter layout="${longdate} - ${callsite} - ${message}" />
</target>
</targets>
<rules>
<logger name="*" minLevel="Fatal" writeTo="sendmail" />
<logger name="*" minLevel="Info" writeTo="event" />
<logger name="*" minLevel="Debug" writeTo="console" />
</rules>
This allowed me to call a static method (BackupLib.Email.Send()) that sent out an email for me. Simple yet effective and since I used the SMTPClient baked into .NET it used my system email settings!
Glad I finally got this.
If you have the extension NLog.MailKit installed and you try to use the useSystemNetMailSettings parameter within your target, this will causes the error Parameter useSystemNetMailSettings not supported on MailTarget.
Uninstalling the NLog.MailKit package fixed this for me!
The Nlog.MailKit package is only required if you are using NetStandard1.X.