首先收藏一下log4j2的官网:http://logging.apache.org/log4j/2.x/manual/plugins.html#TypeConverters
有时候需要在日志中实现类似aop的效果,统一加进去某些参数。对于这种需要,log4j2则可以使用插件机制。
具体做法:
package com.hotusm.ticket.interceptor; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.pattern.ConverterKeys; import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; import org.apache.logging.log4j.core.pattern.PatternConverter; /** * Created by hotusm 2017/2/16. */ @Plugin(name = "LogIdPatternConverter", category = PatternConverter.CATEGORY) @ConverterKeys({ "y", "logId" }) public class LogIdPatternConverter extends LogEventPatternConverter { private static final LogIdPatternConverter INSTANCE = new LogIdPatternConverter(); public static LogIdPatternConverter newInstance( final String[] options) { return INSTANCE; } private LogIdPatternConverter(){ super("LogId", "logId"); } @Override public void format(LogEvent event, StringBuilder toAppendTo) { toAppendTo.append(Math.random()); } }
定义一个类继承LogEventPatternConverter
1.定义的这个类必须提供一个newInstance方法,参数是final String[] options,返回值为定义的类(对于是否是单例没有明确的要求)
2.提供一个私有的构造函数,调用父类的构造函数,函数需要提供两个参数 第一个参数是转换器的名称,第二个是css样式,
3.还有主要的工作format,这里有两个参数,LogEvent是系统已经存在的一些可选数据,StringBuilder 表示的是最终的输出字符流。一般都是将自定义的
append进去
4.注解:Plugin 表示的是这是一个插件,name是名称,category为PatternConverter.CATEGORY(目前插件只有这个选择)
ConverterKeys表示的就是自定义的参数,可以多个
定义好了之后,然后在log4j2的配置文件中设置
<configuration status="WARN" packages="com.hotusm.ticket.interceptor">
打印格式:
<Property name="patternStyle">lodId:%-10y %d{HH:mm:ss.SSS}
最后就ok了。下面是输出:
以上是log4j2的配置,使用log4j可以继承patternLayout和patternParser,自定义一个patternConverter实现。如下:
public class ExtPatternLayout extends PatternLayout {
public ExtPatternLayout(String pattern) {
super(pattern);
System.out.println("pattern is null ???:" + pattern);
}
public ExtPatternLayout() {
super(DEFAULT_CONVERSION_PATTERN);
}
@Override
protected PatternParser createPatternParser(String pattern) {
System.out.println("pattern is null ???:" + pattern);
return new ExtPatternParser(pattern == null ? DEFAULT_CONVERSION_PATTERN: pattern);
}
}
pattern解析器:
public class ExtPatternParser extends PatternParser {
public static final ThreadLocal<Map<String, Object>> TH_LOCAL = new ThreadLocal<Map<String, Object>>(){
@Override
protected HashMap<String, Object> initialValue() {
return new HashMap<String, Object>();
}
};
public static void setCurrentValue(String key, Object value) {
Map<String, Object> map = TH_LOCAL.get();
map.put(key, value);
}
public ExtPatternParser(String pattern) {
super(pattern);
}
@Override
protected void finalizeConverter(char c) {
if (c == '#') {
String option = super.extractOption();
addConverter(new ExtPatternConverter(this.formattingInfo,option));
currentLiteral.setLength(0);
} else {
super.finalizeConverter(c);
}
}
}
pattern转换器:
public class ExtPatternConverter extends PatternConverter {
private String cfg;
@Autowired
public ExtPatternConverter(FormattingInfo fi, String cfg) {
super(fi);
this.cfg = cfg;
}
@Override
protected String convert(LoggingEvent event) {
System.out.println("start char convert");
Map<String, Object> valueMap = ExtPatternParser.TH_LOCAL.get();
if (valueMap != null) {
Object value = valueMap.get(cfg);
if (value != null) {
return String.valueOf(value);
}
}
return "notExist";
}
}