您的位置:首页 > 产品设计 > UI/UE

QuickServer开发指南(7)- 使用和定制日志

2005-02-28 15:19 197 查看
对任何一个项目来说,日志都是一个重要的工具。日志帮助我们去理解我们的项目内部发生了什么,它也会提供审核和调试信息。想要知道更多有关日志的资料可查阅Sun公司的网站
http://java.sun.com/j2se/1.4.0/docs/guide/util/logging/overview.html
QuickServer目前只支持Java Logging API (java.util.logging)。1.4版的Java已加入logging。如果你还在使用旧的版本,你可以安装Lumberjack库提供的可选的实现(http://javalogging.sourceforge.net/)。
让我们给我们的EchoServer做一个日志器。QuickServer默认已可以使用日志器,但是除了ConsoleHandler和设置INFO的级别之外它什么也没有处理。因而无论何时我们在EchoServer关闭和客户端的连接,我们都会在控制台看见一些相似的信息
Feb 16, 2000 10:11:25 PM ClientHandler sendSystemMsg
INFO: Closing connection : /127.0.0.1
上面的信息指明IP为127.0.0.1的客户端关闭了连接。这条消息的显示使用了ClientHalder类的sendSystemMsg()方法.
让我们看看我们怎样在我们的项目中控制日志。使用java logging必须先在类中导入java.util.logging包。
从上面的日志,我们发现某些客户端关闭了连接或掉线,但是它是怎样显示的,我们并没有写任何有关日志的命令。它会显示是因为QuickServer使用了内部的日志器ClientHandler类的sendSystemMsg()方法。
查看QuickServer文档可以找到sendSystemMsg(),如果没有指定级别,它默认使用INFO。你可以在ClientCommandHandler或Authenticator或任何类中使用sendSystemMsg()来记录一个事件。

1. 简单的日志
现在我们来记录每一个连接EchoServer的客户端IP地址。编辑EchoCommandHandler.java文件。在gotConnected(ClientHandler handler)后添加
handler.sendSystemMsg("New Client : " +
handler.getSocket().getInetAddress().getHostAddress(),
Level.INFO);
还要导入包import java.util.logging.*;
编译并运行,连接到EchoServer,你将看到当客户端连接时控制台会显示你的地址。
让QuickServer将日志记录到文件中(XML格式)。下面是修改的文件:

01 package echoserver;
02
03 import org.quickserver.net.*;
04 import org.quickserver.net.server.*;
05
06 import java.io.*;
07 import java.util.logging.*;
08
09 public class EchoServer {
10 public static void main(String s[]) {
11
12 String cmd = "echoserver.EchoCommandHandler";
13 String auth = "echoserver.EchoServerQuickAuthenticator";
14 String data = "echoserver.EchoServerPoolableData"; //Poolable
15
16 QuickServer myServer = new QuickServer();
17
18 //setup logger to log to file
19 Logger logger = null;
20 FileHandler xmlLog = null;
21 File log = new File("./log/");
22 if(!log.canRead())
23 log.mkdir();
24 try {
25 logger = Logger.getLogger(""); //get root logger
26 logger.setLevel(Level.INFO);
27 xmlLog = new FileHandler("log/EchoServer.xml");

28 logger.addHandler(xmlLog);
29 } catch(IOException e){
30 System.err.println("Could not create xmlLog FileHandler : "+e);
31 }
32 //set logging level to fine
33 myServer setConsoleLoggingLevel(Level INFO);
34
35
36 myServer.setClientCommandHandler(cmd);
37 myServer.setAuthenticator(auth);
38 myServer.setClientData(data);
39
40 myServer.setPort(4123);
41 myServer.setName("Echo Server v 1.0");
42
43 //store data needed to be changed by QSAdminServer
44 Object[] store = new Object[]{"12.00"};
45 myServer.setStoreObjects(store);
46
47 //config QSAdminServer
48 myServer.setQSAdminServerPort(4124);
49 myServer.getQSAdminServer().getServer().setName("EchoAdmin v 1.0");
50 try {
51 //add command plugin
52 myServer.getQSAdminServer().setCommandPlugin(
53 "echoserver.QSAdminCommandPlugin");
54 myServer.startQSAdminServer();
55 myServer.startServer();
56 } catch(AppException e){
57 System.out.println("Error in server : "+e);
58 } catch(Exception e){
59 System.out.println("Error : "+e);
60 }
61 }
62 }
在上面的代码中,我们首先检查是否存在一个日志文件夹(21、22行),如果没有先创建它。
在25行,我们尝试获得一个日志器,28行,添加一个新的FileHandler,这里我们没有指定格式因为默认的格式就是XML的。
在33行,我们设置日志的控制级别为INFO。
接下来修改EchoCommandHandler.java

01 // EchoCommandHandler.java
02 package echoserver;

03
04 import java.net.*;
05 import java.io.*;
06 import org.quickserver.net.server.ClientCommandHandler;
07 import org.quickserver.net.server.ClientHandler;
08 import java.util.logging.*;
09
10 public class EchoCommandHandler implements ClientCommandHandler {
11
12 public void gotConnected(ClientHandler handler)
13 throws SocketTimeoutException, IOException {
14 handler.sendSystemMsg("New Client : "+
15 handler.getSocket().getInetAddress().getHostAddress(),
16 Level.INFO);
17 handler.sendClientMsg("+++++++++++++++++++++++++++++++");
18 handler.sendClientMsg("| Welcome to EchoServer v 1.0 |");
19 handler.sendClientMsg("| Note: Password = Username |");
20 handler.sendClientMsg("| Send 'Quit' to exit |");
21 handler.sendClientMsg("+++++++++++++++++++++++++++++++");
22 }
23 public void lostConnection(ClientHandler handler)
24 throws IOException {
25 handler.sendSystemMsg("Connection lost : " +
26 handler.getSocket().getInetAddress());
27 }
28 public void closingConnection(ClientHandler handler)
29 throws IOException {
30 handler.sendSystemMsg("Closing connection : " +
31 handler.getSocket().getInetAddress());
32 }
33
34 public void handleCommand(ClientHandler handler, String command)
35 throws SocketTimeoutException, IOException {
36 if(command.equals("Quit")) {
37 handler.sendClientMsg("Bye ;-)");
38 handler.closeConnection();
39 return;
40 }
41 if(command.equals("What's interest?")) {
42 handler.sendClientMsg("Interest is : "+
43 (String)handler.getServer().getStoreObjects()[0]+
44 "%");
45 } else if(command.equalsIgnoreCase("hello")) {
46 EchoServerData data = (EchoServerData) handler.getClientData();
47 data.setHelloCount(data.getHelloCount()+1);
48 if(data.getHelloCount()==1) {
49 handler.sendClientMsg("Hello "+data.getUsername());
50 } else {
51 handler.sendClientMsg("You told Hello "+data.getHelloCount()+
52 " times. ");
53 }
54 } else {
55 handler.sendClientMsg("Echo : "+command);
56 }
57 }
58 }
编译并运行程序,现在尝试连接,你将看到它会同时在控制台和xml文件记录你的IP地址。
让我们使用QSAdminGUI设置日志级别为FINEST,观察日志内容的变化。日志记录增加了。另外一个改变日志级别的方法是修改代码,可以使用logger.setLevel()或者QuickServer的方法setLoggingLevel()来设置所有句柄的日志级别。

2. 日志的高级应用
当我们设置日志级别为FINEST时,会记录很多信息。一个可能的需要是分离QuickServer和应用的日志。下面的代码允许你这么做。

01 package echoserver;
02
03 import org.quickserver.net.*;
04 import org.quickserver.net.server.*;
05
06 import java.io.*;
07 import java.util.logging.*;
08
09 public class EchoServer {
10 public static void main(String s[]) {
11
12 String cmd = "echoserver.EchoCommandHandler";
13 String auth = "echoserver.EchoServerQuickAuthenticator";
14 String data = "echoserver.EchoServerPoolableData"; //Poolable
15
16 QuickServer myServer = new QuickServer();
17
18 //setup logger to log to file
19 Logger logger = null;
20 FileHandler xmlLog = null;
21 FileHandler txtLog = null;

22 File log = new File("./log/");
23 if(!log.canRead())
24 log.mkdir();
25 try {
26 logger = Logger.getLogger("org.quickserver.net"); //get QS logger
27 logger.setLevel(Level.FINEST);
28 xmlLog = new FileHandler("log/EchoServer.xml");
29 logger.addHandler(xmlLog);
30
31 logger = Logger.getLogger("echoserver"); //get App logger
32 logger.setLevel(Level.FINEST);
33 txtLog = new FileHandler("log/EchoServer.txt");
34 txtLog.setFormatter(new SimpleFormatter());
35 logger.addHandler(txtLog);
36 myServer.setAppLogger(logger); //img : Sets logger to be used for app.
37 } catch(IOException e){
38 System.err.println("Could not create xmlLog FileHandler : "+e);
39 }
40 //set logging level to fine
41 myServer.setConsoleLoggingLevel(Level.INFO);
42
43
44 myServer.setClientCommandHandler(cmd);
45 myServer.setAuthenticator(auth);
46 myServer.setClientData(data);
47
48 myServer.setPort(4123);
49 myServer.setName("Echo Server v 1.0");
50
51 //store data needed to be changed by QSAdminServer
52 Object[] store = new Object[]{"12.00"};
53 myServer.setStoreObjects(store);
54
55 //config QSAdminServer
56 myServer.setQSAdminServerPort(4124);
57 myServer.getQSAdminServer().getServer().setName("EchoAdmin v 1.0");
58 try {
59 //add command plugin
60 myServer.getQSAdminServer().setCommandPlugin(
61 "echoserver.QSAdminCommandPlugin");
62 myServer.startQSAdminServer();
63 myServer.startServer();
64 } catch(AppException e){
65 System.out.println("Error in server : "+e);

66 } catch(Exception e){
67 System.out.println("Error : "+e);
68 }
69 }
70 }
代码中的注释说明的很清楚了。编译并运行,连接后你将看见QuickServer内部的日志记录到了xml文件,应用级别的日志记录到了我们想要的txt文件。

注意:
要尽量减少控制台中的日志数量,使用文件记录详细的日志,并降低日志的级别。这样可以改善应用的性能。避免使用System.out.println(),用logging代替。ClientHandler中的sendSystemMsg()方法在记录日志方面很有用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: