前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊logback的UNDEFINED_PROPERTY

聊聊logback的UNDEFINED_PROPERTY

作者头像
code4it
发布2023-11-07 16:33:09
1270
发布2023-11-07 16:33:09
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究一下logback的UNDEFINED_PROPERTY

substVars

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

代码语言:javascript
复制
    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

代码语言:javascript
复制
    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

代码语言:javascript
复制
    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

代码语言:javascript
复制
    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

代码语言:javascript
复制
    private void handleVariable(Node n, StringBuilder stringBuilder, Stack<Node> cycleCheckStack) throws ScanException {

        // Check for recursion
        if (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 valid
        if (value != null) {
            Node innerNode = tokenizeAndParseString(value);
            compileNode(innerNode, stringBuilder, cycleCheckStack);
            cycleCheckStack.pop();
            return;
        }

        // empty default literal is a valid value
        if (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

代码语言:javascript
复制
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处理逻辑。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-11-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码匠的流水账 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • substVars
  • substituteVariable
  • transform
  • compileNode
    • handleVariable
    • UNDEFINED_PROPERTY_SUFFIX
    • 小结
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档