用于布局以外类型的nlog渲染器(用于目标属性)

时间:2014-12-04 09:47:21

标签: layout config nlog renderer

我正在尝试使用自定义渲染器从app.config中使用params配置邮件目标。我的NLog邮件目标:

<target name="AlertMail" xsi:type="Mail"
  to="${mailTo}"
  from="${mailFrom}"
  html="true"
  encoding="${enc}"
  subject="[APPNAME][${mailEnv}][${instanceName}][${logger:uppercase=true}]"
  smtpServer="${smtpHost}"
  smtpAuthentication="${smtpAuth}"
  smtpUserName="${smtpUserName}"
  smtpPassword="${smtpPassword}"
  header="${mailHtmlHeader}${mailBodyHeader}"
  layout="${mailMessage}"
  footer="${mailBodyFooter}${mailHtmlFooter}"/>

NLog变量:

<variable name="${enc}" value="${app-settings:default.encoding}" />
<variable name="${smtpAuth}" value="${app-settings:alerting.smtp.authentication}" />

NLog Layout Renderer:

[LayoutRenderer("app-settings")]
public class AppSettingsRenderer : LayoutRenderer
{
    [RequiredParameter]
    [DefaultParameter]
    public string Key { get; set; }
    protected override void Append(StringBuilder builder, NLog.LogEventInfo logEvent)
    {
        var param = ConfigurationManager.AppSettings[this.Key];
        builder.Append(param);
    }
}

我收到错误

Error when setting property 'Encoding' on Mail Target[AlertMail]
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 Common.Logging.NLog.NLogLoggerFactoryAdapter..ctor(NameValueCollection properties) in D:\Project\GSJSJZB\GSJ_SJZB\Common.Logging.NLog\Logging\NLog\NLogLoggerFactoryAdapter.cs:line 109

这显然是因为LayoutRenderer只处理属性类型的Layout。属性smtpAuthentication具有相同的问题。如何解决此限制,从appconfig使用params以外的类型?

1 个答案:

答案 0 :(得分:0)

我使用从MailTarget派生的自定义目标来解决此问题:

[Target("MyMail")]
class MyMailTarget : MailTarget
{
    /// <summary>
    /// Wrapper for enum to use placeholders
    /// </summary>
    [DefaultValue("None")]
    public Layout SmtpAuth { get; set; }

    protected override void Write(NLog.Common.AsyncLogEventInfo logEvent)
    {
        Write(new[] {logEvent});
    }

    protected override void Write(NLog.Common.AsyncLogEventInfo[] logEvents)
    {
        var renderedAuthType = SmtpAuth.Render(logEvents.Last().LogEvent);
        SmtpAuthenticationMode mode;
        if (Enum.TryParse(renderedAuthType, true, out mode))
            SmtpAuthentication = mode;
        else
        {
            InternalLogger.Warn("Could not convert '{0}' to SmtpAuthenticationMode, valid values are None, Basic and Ntlm.");
            throw new NLogRuntimeException(String.Format("Cannot render SmtpAuthentication. SmtpAuth = {0}", renderedAuthType));
        }
        base.Write(logEvents);
    }
}

使用:

<extensions>
  <add assembly="AssemplyNameWithMyMailTarget" />
</extensions>

<variable name="smtpAuth" value="${app-settings:alerting.SMTP.Authentication}"/>

<!-- smtpAuth - my custom attribute -->

<target name="AlertMail" xsi:type="MyMail"
  to="${mailTo}"
  from="${mailFrom}"
  subject="[APPNAME][ALERT][${mailEnv}][${instanceName}]"
  smtpServer="${smtpHost}"
  smtpAuth="${smtpAuth}" 
  smtpUserName="${smtpUserName}"
  smtpPassword="${smtpPassword}"
  layout="${longdate}${newline}${message}${newline}"
  />