NLog自定义布局渲染器嵌套${exception}参数解析异常求助
解决NLog自定义布局渲染器中嵌套布局的括号截断问题
这个问题的根源是NLog在解析字符串类型的参数时,会把第一个}误认为是自定义渲染器参数的结束标记,导致嵌套的${exception}被截断成${exception。下面是两种可靠的解决方案,优先推荐第一种:
方案一:将参数类型改为Layout(最优解)
修改自定义布局渲染器的Exception和Code属性类型为Layout,让NLog自动解析嵌套的布局表达式,而不是把它们当作纯字符串处理:
[LayoutRenderer("ignore-exception")] public class ExceptionLoggingRenderer : LayoutRenderer { /// <summary> /// 捕获的异常(与Code配合校验) /// </summary> [RequiredParameter] public Layout Exception { get; set; } /// <summary> /// 错误代码(与Exception配合校验) /// </summary> [RequiredParameter] public Layout Code { get; set; } protected override void Append(StringBuilder builder, LogEventInfo logEvent) { // 渲染Layout得到实际的字符串值 var exceptionText = Exception.Render(logEvent); var codeText = Code.Render(logEvent); builder.Append(IgnoreLoggingToDb(exceptionText, codeText)); } private bool IgnoreLoggingToDb(string exception, string code) { if (exception == "whatever" && code == "123") return true; else return false; } }
修改后,你的过滤器配置可以保持原样,NLog会正确解析${exception}:
<filters> <whenEqual ignoreCase="true" layout="${ignore-exception:Code=82:Exception=${exception}}" action="Ignore" compareTo="true"/> <!-- 注意:condition里需要明确判断布尔值的字符串形式 --> <when condition="'${ignore-exception:Code=82:Exception=${exception}}' == 'True'" action="Ignore"/> </filters>
为什么这个方法有效?因为Layout类型是NLog专门用来处理动态日志内容的类型,它会完整解析嵌套的布局渲染器(比如${exception}),而不会被内部的}截断参数值。
方案二:在配置中转义括号(临时 workaround)
如果暂时不想修改代码,可以在XML配置里用转义符处理嵌套的}。注意XML里需要将反斜杠保留为\:
<filters> <whenEqual ignoreCase="true" layout="${ignore-exception:Code=82:Exception=${exception\}}}" action="Ignore" compareTo="true"/> <when condition="'${ignore-exception:Code=82:Exception=${exception\}}}' == 'True'" action="Ignore"/> </filters>
不过这种方法不够直观,而且在复杂嵌套场景下容易出错,所以优先推荐方案一。
内容的提问来源于stack exchange,提问作者Kal
相关产品推荐
相关产品推荐

