自定义NLog Layout Renderer无法解析内部布局,环境变量未正常替换
问题描述
我希望将预定义的Elastic Search索引与ASP环境变量值进行映射,为此编写了如下自定义NLog Layout Renderer:
[LayoutRenderer("elk-environment-index")] public class EnvironmentNameLayoutRender : LayoutRenderer { [DefaultParameter] [RequiredParameter] public string? AspNetEnvironmentName { get; set; } protected override void Append(StringBuilder builder, LogEventInfo logEvent) { var name = AspNetEnvironmentName switch { "development" => "debug", "staging" => "test", "production" => "prod", _ => AspNetEnvironmentName }; builder.Append(name); } }
随后在NLog.config中按如下方式使用:
<variable name="asp_environment" value="${environment:variable=ASPNETCORE_ENVIRONMENT}" /> *** layout="my render: ${elk-environment-index:${asp_environment}}">
预期当环境为Development时输出my render: debug,但实际输出为my render: ${environment:variable=ASPNETCORE_ENVIRONMENT},请问哪里操作错误?
问题原因与解决方法
错误原因
你的自定义Layout Renderer参数定义为string? AspNetEnvironmentName,NLog会直接把配置中传入的原始布局表达式字符串赋值给这个属性,不会自动解析其中的NLog变量或布局渲染逻辑。
修复方案
修改自定义Layout Renderer,将参数类型从string改为Layout,这样NLog会先解析参数中的布局表达式,再把实际的环境变量值传递给你的映射逻辑:
[LayoutRenderer("elk-environment-index")] public class EnvironmentNameLayoutRender : LayoutRenderer { [DefaultParameter] [RequiredParameter] public Layout? AspNetEnvironmentName { get; set; } protected override void Append(StringBuilder builder, LogEventInfo logEvent) { // 先解析布局得到实际的环境变量值 var envValue = AspNetEnvironmentName?.Render(logEvent); var name = envValue switch { "development" => "debug", "staging" => "test", "production" => "prod", _ => envValue ?? string.Empty }; builder.Append(name); } }
配置说明
原NLog.config中的配置无需修改,现在NLog会正确解析${asp_environment}对应的环境变量值,再传入自定义Renderer完成索引名映射。
内容的提问来源于stack exchange,提问作者Artem Grunin
相关产品推荐
相关产品推荐

