当前位置: 首页 > news >正文

聊聊logback的UNDEFINED_PROPERTY

本文主要研究一下logback的UNDEFINED_PROPERTY

substVars

ch/qos/logback/core/util/OptionHelper.java

    public static String substVars(String input, PropertyContainer pc0, PropertyContainer pc1) {try {return NodeToStringTransformer.substituteVariable(input, pc0, pc1);} catch (ScanException e) {throw new IllegalArgumentException("Failed to parse input [" + input + "]", e);}}

OptionHelper提供了substVars方法,它执行NodeToStringTransformer的substituteVariable方法

substituteVariable

ch/qos/logback/core/subst/NodeToStringTransformer.java

    public static String substituteVariable(String input, PropertyContainer pc0, PropertyContainer pc1) throws ScanException {Node node = tokenizeAndParseString(input);NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, pc0, pc1);return nodeToStringTransformer.transform();}

substituteVariable方法则先根据input解析node,再创建NodeToStringTransformer,执行其transform方法

transform

ch/qos/logback/core/subst/NodeToStringTransformer.java

    public String transform() throws ScanException {StringBuilder stringBuilder = new StringBuilder();compileNode(node, stringBuilder, new Stack<Node>());return stringBuilder.toString();}

transform方法主要是执行compileNode,通过stringBuilder来收集变量值

compileNode

ch/qos/logback/core/subst/NodeToStringTransformer.java

    private void compileNode(Node inputNode, StringBuilder stringBuilder, Stack<Node> cycleCheckStack) throws ScanException {Node n = inputNode;while (n != null) {switch (n.type) {case LITERAL:handleLiteral(n, stringBuilder);break;case VARIABLE:handleVariable(n, stringBuilder, cycleCheckStack);break;}n = n.next;}}

compileNode方法针对VARIABLE类型的执行handleVariable方法

handleVariable

ch/qos/logback/core/subst/NodeToStringTransformer.java

    private void handleVariable(Node n, StringBuilder stringBuilder, Stack<Node> cycleCheckStack) throws ScanException {// Check for recursionif (haveVisitedNodeAlready(n, cycleCheckStack)) {cycleCheckStack.push(n);String error = constructRecursionErrorMessage(cycleCheckStack);throw new IllegalArgumentException(error);}cycleCheckStack.push(n);StringBuilder keyBuffer = new StringBuilder();Node payload = (Node) n.payload;compileNode(payload, keyBuffer, cycleCheckStack);String key = keyBuffer.toString();String value = lookupKey(key);// empty values are considered validif (value != null) {Node innerNode = tokenizeAndParseString(value);compileNode(innerNode, stringBuilder, cycleCheckStack);cycleCheckStack.pop();return;}// empty default literal is a valid valueif (n.defaultPart == null) {stringBuilder.append(key + CoreConstants.UNDEFINED_PROPERTY_SUFFIX);cycleCheckStack.pop();return;}Node defaultPart = (Node) n.defaultPart;StringBuilder defaultPartBuffer = new StringBuilder();compileNode(defaultPart, defaultPartBuffer, cycleCheckStack);cycleCheckStack.pop();String defaultVal = defaultPartBuffer.toString();stringBuilder.append(defaultVal);}   

handleVariable方法对于value为null,且defaultValue也为null的设置了默认值为key + CoreConstants.UNDEFINED_PROPERTY_SUFFIX)

UNDEFINED_PROPERTY_SUFFIX

public class CoreConstants {//......public static final String UNDEFINED_PROPERTY_SUFFIX = "_IS_UNDEFINED";}

UNDEFINED_PROPERTY_SUFFIX的值为_IS_UNDEFINED

小结

logback通过NodeToStringTransformer的handleVariable来获取变量值,若该value为null,且defaultValue也为null的设置了默认值为key + CoreConstants.UNDEFINED_PROPERTY_SUFFIX),即key_IS_UNDEFINED,注意这里如果defaultValue不为null则不走IS_UNDEFINED的逻辑,即空字符串也是可以的。对于自定义appender需要注意一下appender属性的value处理逻辑。

http://www.lryc.cn/news/218861.html

相关文章:

  • 记一次pdjs时安装glob出现,npm ERR! code ETARGET和npm ERR! code ELIFECYCLE
  • Zabbix如何监控腾讯云NAT网关
  • SpringBoot案例(数据层、业务层、表现层)
  • 交叉编译程序:以 freetype 为例
  • spring-cloud-starter-dubbo不设置心跳间隔导致生产者重启no Provider问题记录
  • 【数据结构】败者树的建树与比较过程
  • GlobalMapper---dem生成均匀分布的网格,或者均匀分布的点高程点
  • k8s系列文章一:安装指南
  • Pod 进阶
  • Proteus仿真--12864LCD显示计算器键盘按键实验(仿真文件+程序)
  • pam_radius库的使用
  • qt6:无法使用setFontColor
  • 竞赛 深度学习疫情社交安全距离检测算法 - python opencv cnn
  • 无声的世界,精神科用药并结合临床的一些分析及笔记(十)
  • 构建强大的Web应用之Django详解
  • Linux 之搭建 arm 的 qemu 模拟器
  • uinapp微信小程序隐私政策授权
  • 使用Java工作流简单介绍
  • 数字媒体技术基础之:ICC 配置文件
  • 解析SD-WAN组网方式及应用场景,全面了解典型案例
  • 中小学智慧校园电子班牌管理系统源码
  • 日常踩坑-[sass]Error: Expected newline
  • UI设计感蓝色商务数据后台网站模板源码
  • 二、计算机组成原理与体系结构
  • MySQL-sql的优化
  • 一致性哈希在分库分表的应用
  • PostCSS通过px2rem插件和lib-flexible将px单位转换为rem(root em)单位实现大屏适配
  • 什么是缓冲区溢出?
  • 论文浅尝 | ChatKBQA:基于微调大语言模型的知识图谱问答框架
  • 软件测试的目的---防范项目风险