• 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:11.定制化Log输出



    欢迎阅读我的开源项目《迷你微信》服务器《迷你微信》客户端

    前言

    《迷你微信》服务器中,我们用了Log4J来进行输出,这可以在我们程序出现异常的时候找到错误发生时的上下文。然而吗,在项目的组件迭代过程中,我们发现,log出来的内容越来越多,往往在储蓄出现异常去查Log的时候,会被一大堆不相干的Log给淹没,这时,我们想:如果能够只输出我要的那部分岂不是很爽,这样就能快速的找到我们要的Log了,所以博主自己别编写了一个定制化输出的方法。

    Log4J的Name

    Log4J在创建时是需要设置名称的,可以把它理解成一个索引,以此在其他地方拿到它。

    public class MyLogTest {
    	private Logger logger = Logger.getLogger(this.getClass().getSimpleName());
    p
    	public void method_1(){
    		logger.info("abcdefg");
    	}
    }
    
    public class Test_2 {
    	public Logger getMyLogger(String name){
    		return Logger.getLogger(name);
    	}
    
    }
    

    上述MyLogTest类中,我们用类名创建了一个Log4J的Logger对象,在第二个类Test_2中,我们有一个getMyLogger方法,如果我们调用时传入的是MyLogTest的类名,则会返回MyLogTest中的那个Logger对象。

    注:Logger.getLogger(name) 方法在以name命名对象不存在时,会创建一个新的返回,当已经被创建后调用则会返回之前创建过的那个Logger对象。

    定制化Log输出

    配置XML

    想要做到定制化Log输出,我们需要有一个配置文件来设置哪些Logger输出,哪些不输出。
    (详细源码请参考《迷你微信》服务器)

    <?xml version=""1.0" encoding="UTF-8"?>
    <LoggerRule>
    	<TypeContain>False</TypeContain>
    	<TypeList>
    		<ProtoHead logType="class">server.Server_User</ProtoHead>
    	</TypeList>
    </LoggerRule>
    

    先来解释一下上述代码所代表的意义:

    • LoggerRule : 代表Log规则的根,内不包含所有规则
    • TypeContain :参数为True时,代表包含,只输出列表中所述Logger的内容,Flase代表“除外”,即下面列表所述的Logger都不输出。
    • ProtoHead :每一个(不)要输出的条目(注:叫这个名字时历史遗留问题)

    整体来说,就是在项目运行时,叫server.Server_User这个名字的Logger将被忽略输出。

    编写读取类

    private void readLogRule() {
            DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
    		try {
                DocumentBuilder dombuilder=domfac.newDocumentBuilder();
                InputStream is=new FileInputStream(LoggerXML);    
                Document doc=dombuilder.parse(is);        
    
    			Element root = doc.getDocumentElement(); // 获取根元素
    			String typeContain = root.getElementsByTagName("TypeContain").item(0).getFirstChild().getNodeValue().toString();
    
    			loggerRule = new LoggerRule(typeContain.equals("True") ? LoggerType.Contain
    					: LoggerType.Ignore);
    			
    			NodeList nodeList = root.getElementsByTagName("ProtoHead");
    			Node node1, node2;
    			NamedNodeMap namedNodeMap;
    			String nodeValue;
    			for (int i=0; i<nodeList.getLength(); i++) {
    				node1 = nodeList.item(i);
    				namedNodeMap = node1.getAttributes();
    				for (int j=0; j<namedNodeMap.getLength(); j++) {
    					node2 = namedNodeMap.item(j);
    					if (node2.getNodeName().equals("logType")) {
    						nodeValue = node1.getFirstChild().getNodeValue().toString();
    						if (node2.getNodeValue().equals("Network")) {	// 显示服务器发了什么包的Log
    							loggerRule.loggerSet.add(ProtoHead.ENetworkMessage.valueOf(nodeValue));
    						} else if (node2.getNodeValue().equals("class")) {
    							loggerRule.logCalssList.add(nodeValue);
    						}
    					}	
    				}
    			}
    		} catch (Exception e) {
    			logger.error("MyLogger : load " + LoggerXML + " file error!
    " + MyException.getStackStr(e.getStackTrace()));
    		}
    	}
    	
    class LoggerRule {
    	public static enum LoggerType {
    		Contain, Ignore
    	};
    
    	public LoggerType loggerType;
    	HashSet<ProtoHead.ENetworkMessage> loggerSet;
    	public ArrayList<String> logCalssList;
    
    	public LoggerRule(LoggerType loggerType) {
    		this.loggerType = loggerType;
    		loggerSet = new HashSet<ProtoHead.ENetworkMessage>();
    		logCalssList = new ArrayList<String>();
    	}
    }
    

    通过上面这个方法,我们从配置文件中读出了我们制定的输出规则,存储在一个ArrayList中,接着,只要进行以此遍历,将指定的Logger关掉即可:

    public void closeLoggerNotWant(){
    	for (String className : loggerRule.logCalssList)
    		Logger.getLogger(className).setAdditivity(false);
    }
    

    优点

    通过这种方式,我们实现了配置编程,在不修改项目源码的前提下,我们可以通过修改配置文件的方式来设置哪些Logger不惊醒输出。甚至,在对上述程序做一些修改后,可以动态的进行变化(如:定时读取XML),即可以在不重启整个进程的前提下修改输出设置。

    欢迎阅读我的开源项目《迷你微信》服务器《迷你微信》客户端

  • 相关阅读:
    邮件发送的存储过程写法
    FormsAuthentication.GetRedirectUrl 方法
    视图性能优化——索引视图
    删除多字段的重复行保留最大最小行
    c#知识点
    sql存储过程exec执行字符串select 的区别
    UVALive5198 UVA512 Spreadsheet Tracking
    UVA129 HDU1627 Krypton Factor
    UVA129 HDU1627 Krypton Factor
    UVA10603 Fill
  • 原文地址:https://www.cnblogs.com/xiaozefeng/p/Wechat_MiniWechat_11.html
Copyright © 2020-2023  润新知