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

对任何一个项目来说,日志都是一个重要的工具。日志帮助我们去理解我们的项目内部发生了什么,它也会提供审核和调试信息。想要知道更多有关日志的资料可查阅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()方法在记录日志方面很有用。
 原文地址 http://tb.blog.csdn.net/TrackBack.aspx?PostId=305338
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值