最近项目要用到日志服务器,需要把所有服务器的日志统一存入一个日志文件服务器中,于是就想到了Log4j的SocketAppender。 网上一通搜索,终于找到了相关的只言片语,内容几乎雷同,和examples\lf5\UsingSocketAppenders中提供的例子没有什么区别! 只好自己研究了! 1.基本使用 1.1服务器 这个日志服务器的服务器端需要运行: log4j jar包中的org.apache.log4j.net.SocketServer 加参数 【本地监听端口】【配置文件】【客户端配置文件目录】 第三个参数【配置文件目录】其实指的是针对每个客户端的配置文件,等会详细讲!现在用“.”就可以了. 服务器端的配置文件可以用这个(引自利用Log4j 创建日志服务器 By ?の?): #文件名socketserver.properties #如果需要显示日志界面,可以将本行启用 #log4j.rootCategory=, A1 log4j.rootLogger=DEBUG,A3 log4j.category.org.apache.log4j.net=INFO log4j.appender.A1=org.apache.log4j.lf5.LF5Appender log4j.appender.A1.MaxNumberOfRecords=700 log4j.appender.A4=org.apache.log4j.DailyRollingFileAppender log4j.appender.A4.file=server.log log4j.appender.A4.DatePattern='.'yyyyMMdd log4j.appender.A4.layout=org.apache.log4j.PatternLayout log4j.appender.A4.layout.ConversionPattern=\n\n[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n log4j.appender.A3=org.apache.log4j.RollingFileAppender log4j.appender.A3.file=server2.log log4j.appender.A3.MaxFileSize=1024KB log4j.appender.A3.MaxBackupIndex=999 log4j.appender.A3.layout=org.apache.log4j.PatternLayout log4j.appender.A3.layout.ConversionPattern=\n\n[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n 其中A1是启动Lf5的log监视终端,A3限制大小的文件,A4是日期滚动文件。 单A3,A4是讲所有客户端的日志都存放到了同一个日志文件中,我觉的这种方法并不好。 1.2客户端 客户端的配置文件是这样的: log4j.rootCategory=,SOCKET log4j.addivity.org.apache=true #应用于socket log4j.appender.SOCKET=org.apache.log4j.net.SocketAppender log4j.appender.SOCKET.RemoteHost=localhost #服务器的IP地址 log4j.appender.SOCKET.Port=1978 #服务器的监听端口 log4j.appender.SOCKET.LocationInfo=true #这个是什么我不知道 log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout log4j.appender.SOCKET.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%t%m%n #A2 log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender log4j.appender.A2.file=server.log log4j.appender.A2.DatePattern='.'yyyy-MM-dd log4j.appender.A2.layout=org.apache.log4j.PatternLayout log4j.appender.A2.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n 启动服务器端,再运行客户端就可以了!但所有的服务器端/客户端的日志都放到了一个日志文件中! 2.稍微高级点的使用 下面讲如何把各个客户端和服务器端的日志分别放到不同的日志文件中. 这个我在网上找了好久也没有找到! 2.1服务器 服务器的配置文件不用怎么改动,如果你不需要在同一个文件中存放所有日志,可以把配置文件第一行的A3去掉。 但服务器端有个更大的麻烦:代码有问题!问题够大了吧,不知道算不算是个bug(我用的是1.2.11版log4j)。 改吧! 打开log4j目录下的src\java\org\apache\log4j\net\SocketServer.java 在这段中改动(看下面代码第12行) LoggerRepository configureHierarchy(InetAddress inetAddress) { cat.info("Locating configuration file for "+inetAddress); // We assume that the toSting method of InetAddress returns is in // the format hostname/d1.d2.d3.d4 e.g. torino/192.168.1.1 String s = inetAddress.toString(); int i = s.indexOf("/"); if(i == -1) { cat.warn("Could not parse the inetAddress ["+inetAddress+ "]. Using default hierarchy."); return genericHierarchy(); } else { //这个是什么意思,专门取"/"符号吗?明显是错的!闭掉 // String key = s.substring(0, i); //改为 String key = s.substring(i+1); File configFile = new File(dir, key+CONFIG_FILE_EXT); if(configFile.exists()) { Hierarchy h = new Hierarchy(new RootLogger((Level) Priority.DEBUG)); hierarchyMap.put(inetAddress, h); new PropertyConfigurator().doConfigure(configFile.getAbsolutePath(), h); return h; } else { cat.warn("Could not find config file ["+configFile+"]."); return genericHierarchy(); } } } 编译文件! 打开log4j目录下的src\java\org\apache\log4j\net\SocketNode.java (改这段是因为我用的时候出错!看不出来改不改有什么区别) 改第54行 ois = new ObjectInputStream( new BufferedInputStream(socket.getInputStream())); 为 InputStream is = socket.getInputStream(); if (is != null) { ois = new ObjectInputStream(new BufferedInputStream(is)); } 文件头加 import java.io.InputStream; 编译文件! 现在为每个配置客户端编配置文件,把配置文件放到【客户端配置文件目录】中: log4j.rootCategory=,A4 log4j.appender.A4=org.apache.log4j.DailyRollingFileAppender log4j.appender.A4.file=127.0.0.1.log #为每个客户端取不同的名字 log4j.appender.A4.DatePattern='.'yyyyMMdd log4j.appender.A4.layout=org.apache.log4j.PatternLayout log4j.appender.A4.layout.ConversionPattern=\n\n[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n 保存文件名为[客户端ip地址].lcf 如192.168.0.126.lcf 2.2 客户端 客户端不用改变,太幸运了!! ok啦! 启动服务器,启动客户端,现在服务器的日志放到了server.log中,有配置文件的客户端的日志会放到相应的日志文件中,没有配置文件的客户端的日志依然放在server.log中! SocketServer.java 和 SocketNode.java两个文件可以单独做一个工程,把他们的package去掉就行了! | |