How do you get an integer value to come from a custom layout renderer?
I am getting an exception when trying to use a custom layout renderer to set a property of a target that expects an integer. By stepping through the code, it looks like custom layout renderers are replaced with their values at the point of the log entry being written to the target. The exception thrown is happening when the logger object is created - and presumably when the NLog.config is processed and when it sees the reference to my custom layout renderer instead of an integer, the exception is thrown.
This is the custom layout renderer:
[LayoutRenderer("buffer-size")]
public class BufferSizeLayoutRenderer : LayoutRenderer
{
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
int BufferSize=150; // would actually read from externally managed settings
builder.Append(BufferSize);
}
}
I have the extension assembly registered in the NLog.config.
The reference to the custom layout renderer is in the BufferingWrapper target like this:
<target xsi:type="BufferingWrapper"
name="InfoBufferingTarget"
bufferSize="${buffer-size}"
flushTimeout="60000"
slidingTimeout="true">
And when the line of code executes that creates the logger object, this exception is thrown:
NLog.NLogConfigurationException was unhandled by user code
HResult=-2146233088
Message=Error when setting property 'BufferSize' on BufferingWrapper Target[InfoBufferingTarget]()
Source=NLog
StackTrace:
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)
at NLog.Config.XmlLoggingConfiguration..ctor(String fileName)
at NLog.LogFactory.LoadLoggingConfiguration(String configFile)
at NLog.LogFactory.get_Configuration()
at NLog.LogFactory.GetLogger(LoggerCacheKey cacheKey)
at NLog.LogFactory.GetLogger(String name)
at NLog.LogManager.GetCurrentClassLogger()
at MyCompany.NLogRepository..ctor() in c:\Source\NLogRepository.cs:line 19
at MyCompany.Controllers.LogController.Post(Data data) in c:\Source\LogController.cs:line 21
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClassc.<GetExecutor>b__6(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
InnerException:
HResult=-2146233088
Message=${buffer-size} is not a valid value for Int32.
Source=System
StackTrace:
at System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
at System.ComponentModel.TypeConverter.ConvertFromInvariantString(String text)
at NLog.Internal.PropertyHelper.TryTypeConverterConversion(Type type, String value, Object& newValue)
at NLog.Internal.PropertyHelper.SetPropertyFromString(Object o, String name, String value, ConfigurationItemFactory configurationItemFactory)
InnerException: System.FormatException
HResult=-2146233033
Message=Input string was not in a correct format.
Source=mscorlib
StackTrace:
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at System.ComponentModel.Int32Converter.FromString(String value, NumberFormatInfo formatInfo)
at System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
InnerException:
This exception is thrown before the code in the custom layout renderer is ever executed.
My ultimate goal - I need to be able to modify NLog settings at runtime without overwriting the NLog.config, which in my case would require a full application deployment. I want to be able to tweak the BufferingWrapper settings and see the effect on performance. If there's another way to accomplish this without using custom layout renderers and without completely creating the NLog configuration in code, let me know.
Any help would be greatly appreciated.