log4j增加过滤器
日志log4j一般配置
<appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender"> <!-- 设置日志输出的样式 --> <layout class="org.apache.log4j.PatternLayout"> <!-- 设置日志输出的格式 --> <param name="ConversionPattern" value="**** [%p] [%d{yyyy/MM/dd HH:mm:ss:SSS}] ******************************%n[Thread] %t%n[Class] %C%n[Method] %M%n[Message] %m%n%n" /> </layout> </appender>
可以增加过滤器
<appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender"> <!-- 设置日志输出的样式 --> <layout class="org.apache.log4j.PatternLayout"> <!-- 设置日志输出的格式 --> <param name="ConversionPattern" value="**** [%p] [%d{yyyy/MM/dd HH:mm:ss:SSS}] ******************************%n[Thread] %t%n[Class] %C%n[Method] %M%n[Message] %m%n%n" /> </layout> <filter class="org.apache.log4j.varia.StringMatchFilter"> <param name="StringToMatch" value="adminPass" /> <param name="AcceptOnMatch" value="false" /> </filter> </appender>
log4j的StringMatchFilter只能判断是否包含某个字符串,源码中用的是indexOf
public int decide(LoggingEvent event) { String msg = event.getRenderedMessage(); if(msg == null || stringToMatch == null) return Filter.NEUTRAL; if( msg.indexOf(stringToMatch) == -1 ) { return Filter.NEUTRAL; } else { // we've got a match if(acceptOnMatch) { return Filter.ACCEPT; } else { return Filter.DENY; } } }
filter可以自定义,可以实现更复杂的过滤,比如写个正则判断是否包含身份证
package com.daimeng.interceptor; import org.apache.log4j.spi.Filter; import org.apache.log4j.spi.LoggingEvent; import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.log4j.helpers.OptionConverter; /** * * @功能描述: log4j的过滤器 * @用法:在log4j的appender里面添加filter * 参考 org.apache.log4j.varia.StringMatchFilter * <filter class="org.apache.log4j.varia.StringMatchFilter"> <param name="StringToMatch" value="adminPass" /> <param name="AcceptOnMatch" value="false" /> </filter> * @名称: MyIdNoStringMatchFilter.java * @路径 com.dms.interceptor * @作者 daimeng.fun * @E-Mail * @创建时间 2020年8月25日 下午3:11:45 * @version V1.0 */ public class MyIdNoStringMatchFilter { /** * @deprecated Options are now handled using the JavaBeans paradigm. This * constant is not longer needed and will be removed in the * <em>near</em> term. */ public static final String STRING_TO_MATCH_OPTION = "StringToMatch"; /** * @deprecated Options are now handled using the JavaBeans paradigm. This * constant is not longer needed and will be removed in the * <em>near</em> term. */ public static final String ACCEPT_ON_MATCH_OPTION = "AcceptOnMatch"; boolean acceptOnMatch = true; String stringToMatch; /** * @deprecated We now use JavaBeans introspection to configure components. * Options strings are no longer needed. */ public String[] getOptionStrings() { return new String[] { STRING_TO_MATCH_OPTION, ACCEPT_ON_MATCH_OPTION }; } /** * @deprecated Use the setter method for the option directly instead of the * generic <code>setOption</code> method. */ public void setOption(String key, String value) { if (key.equalsIgnoreCase(STRING_TO_MATCH_OPTION)) { stringToMatch = value; } else if (key.equalsIgnoreCase(ACCEPT_ON_MATCH_OPTION)) { acceptOnMatch = OptionConverter.toBoolean(value, acceptOnMatch); } } public void setStringToMatch(String s) { stringToMatch = s; } public String getStringToMatch() { return stringToMatch; } public void setAcceptOnMatch(boolean acceptOnMatch) { this.acceptOnMatch = acceptOnMatch; } public boolean getAcceptOnMatch() { return acceptOnMatch; } /** * Returns {@link Filter#NEUTRAL} is there is no string match. */ public int decide(LoggingEvent event) { String msg = event.getRenderedMessage(); if (msg == null || stringToMatch == null) return Filter.NEUTRAL; if (!checkId(msg)) { return Filter.NEUTRAL; } else { // we've got a match if (acceptOnMatch) { return Filter.ACCEPT; } else { return Filter.DENY; } } } public static boolean checkId(String idmsg) { //假设18位身份证号码:41000119910101123X 410001 19910101 123X //^开头 //[1-9] 第一位1-9中的一个 4 //\\d{5} 五位数字 10001(前六位省市县地区) //(18|19|20) 19(现阶段可能取值范围18xx-20xx年) //\\d{2} 91(年份) //((0[1-9])|(10|11|12)) 01(月份) //(([0-2][1-9])|10|20|30|31)01(日期) //\\d{3} 三位数字 123(第十七位奇数代表男,偶数代表女) //[0-9Xx] 0123456789Xx其中的一个 X(第十八位为校验值) //$结尾 //假设15位身份证号码:410001910101123 410001 910101 123 //^开头 //[1-9] 第一位1-9中的一个 4 //\\d{5} 五位数字 10001(前六位省市县地区) //\\d{2} 91(年份) //((0[1-9])|(10|11|12)) 01(月份) //(([0-2][1-9])|10|20|30|31)01(日期) //\\d{3} 三位数字 123(第十五位奇数代表男,偶数代表女),15位身份证不含X //$结尾 String regularExpression = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; boolean matches = idmsg.matches(regularExpression); //判断第18位校验值 if (matches) { if (idmsg.length() == 18) { try { char[] charArray = idmsg.toCharArray(); //前十七位加权因子 int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; //这是除以11后,可能产生的11位余数对应的验证码 String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; int sum = 0; for (int i = 0; i < idCardWi.length; i++) { int current = Integer.parseInt(String.valueOf(charArray[i])); int count = current * idCardWi[i]; sum += count; } char idCardLast = charArray[17]; int idCardMod = sum % 11; if (idCardY[idCardMod].toUpperCase().equals(String.valueOf(idCardLast).toUpperCase())) { return true; } else { return false; } } catch (Exception e) { e.printStackTrace(); return false; } } } return matches; } public static ArrayList<String> getParamFromXml(String context){ Pattern p = Pattern.compile("\\>(.*?)\\<\\/"); Matcher m = p.matcher(context); ArrayList<String> result=new ArrayList<String>(); while(m.find()){ String r = m.group(1); if(r != null && r.indexOf(">") > -1) { r = r.split(">")[r.split(">").length-1]; } System.out.println(r); result.add(r); } return result; } }
log4j就可以这么配置
<appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender"> <!-- 设置日志输出的样式 --> <layout class="org.apache.log4j.PatternLayout"> <!-- 设置日志输出的格式 --> <param name="ConversionPattern" value="**** [%p] [%d{yyyy/MM/dd HH:mm:ss:SSS}] ******************************%n[Thread] %t%n[Class] %C%n[Method] %M%n[Message] %m%n%n" /> </layout> <filter class="org.apache.log4j.varia.StringMatchFilter"> <param name="StringToMatch" value="adminPass" /> <param name="AcceptOnMatch" value="false" /> </filter> <filter class="com.daimeng.interceptor.MyIdNoStringMatchFilter"> <param name="StringToMatch" value="adminPass" /> <param name="AcceptOnMatch" value="false" /> </filter> </appender>