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()方法在记录日志方面很有用。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值