logback.xml自定义标签节点

logback.xml自定义标签节点

问题

xml 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="com.example.user.log.DataMaskingPatternLayout">
                <maskPattern>(\w+@\w+\.\w+)</maskPattern> <!-- Email -->
                <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </layout>
        </encoder>
    </appender>
    <root level="debug">
        <appender-ref ref="console"/>
    </root>
</configuration>

自定义layout

java 复制代码
public class DataMaskingPatternLayout extends PatternLayout {
    private List<String> maskPatterns = new ArrayList<>();

    /**
     * 标签属性的 set{TagName},add{TagName}, 都可以解析到标签
     * 这里就可以自动 注入 <maskPattern/>标签
     * @param maskPattern
     */
    public void setMaskPattern(String maskPattern) {
        maskPatterns.add(maskPattern);
    }
}

今天的目的不是讨论自定义layout,而是如何接收自定义标签值

像这里,我们定义了<maskPattern> 标签,然后要接收这个标签内的值 ,不难发现,只要我们在对应的java代码中增加这个标签属性名称的 set或者add 方法名就可以了,这就很奇怪了,是怎么实现的呢?

原理

  • 首先,logback会将自定义的结点封装成一个Action,而且是 ImplicitAction
  • 然后在运行时取出对应的Action, 如果是属性值方式,则 通过 NestedBasicPropertyIA 实现类
java 复制代码
//NestedBasicPropertyIA.java

public void body(InterpretationContext ec, String body) {

    String finalBody = ec.subst(body);
    // get the action data object pushed in isApplicable() method call
    IADataForBasicProperty actionData = (IADataForBasicProperty) actionDataStack.peek();
    switch (actionData.aggregationType) {
        case AS_BASIC_PROPERTY:
            actionData.parentBean.setProperty(actionData.propertyName, finalBody);
            break;
        case AS_BASIC_PROPERTY_COLLECTION:
            actionData.parentBean.addBasicProperty(actionData.propertyName, finalBody);
            break;
        default:
            addError("Unexpected aggregationType " + actionData.aggregationType);
    }
}

交给 PropertySetter

java 复制代码
public void setProperty(String name, String value) {
    if (value == null) {
        return;
    }
    Method setter = findSetterMethod(name);
    if (setter == null) {
        addWarn("No setter for property [" + name + "] in " + objClass.getName() + ".");
    } else {
        try {
            setProperty(setter, name, value);
        } catch (PropertySetterException ex) {
            addWarn("Failed to set property [" + name + "] to value \"" + value + "\". ", ex);
        }
    }
}

//找到属性名称的方法
private Method findSetterMethod(String name) {
    String propertyName = BeanUtil.toLowerCamelCase(name);
    return beanDescription.getSetter(propertyName);
}

public class BeanDescription {

    //propertyNameToGetter -- map of property names to the associated getter. 
    //propertyNameToSetter -- map of property names to the associated setter. 
    //propertyNameToAdder -- map of property names to the associated adder.
	private final Class<?> clazz;

	private final Map<String, Method> propertyNameToGetter;

	private final Map<String, Method> propertyNameToSetter;

	private final Map<String, Method> propertyNameToAdder;
}

这里就可以发现,通过添加标签属性的 set或者add方法,就可以将自定义的标签内的值注入

相关推荐
a8a3025 天前
Spring Boot 3.3.4 升级导致 Logback 之前回滚策略配置不兼容问题解决
java·spring boot·logback
aisifang007 天前
使用 Logback 的最佳实践:`logback.xml` 与 `logback-spring.xml` 的区别与用法
xml·spring·logback
Amour恋空9 天前
SpringBoot+Lombok+Logback实现日志
spring boot·后端·logback
lang2015092810 天前
从零开始掌握 Logback:Java 日志框架的“Hello World”实战指南
java·单元测试·logback
lang2015092810 天前
Logback 过滤器深度指南:从“三值逻辑”到高性能拦截
java·网络·logback
lang2015092811 天前
Logback TCP 远程日志实战:构建高可用的集中式日志中心
网络协议·tcp/ip·logback
lang2015092811 天前
深入理解 Logback 架构:从层级继承到性能优化的实战指南
架构·logback
lang2015092811 天前
Logback MDC 实战:在分布式混沌中构建清晰的日志链路
分布式·logback
bug攻城狮11 天前
Spring Boot项目启动时输出PID、CPU和内存信息的4种方法
java·spring boot·后端·logback
lang2015092811 天前
Logback Encoder 深度解析:从文本格式化到结构化 JSON 的进化之路
json·logback