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

翻译 2005年02月28日 15:19:00
    对任何一个项目来说,日志都是一个重要的工具。日志帮助我们去理解我们的项目内部发生了什么,它也会提供审核和调试信息。想要知道更多有关日志的资料可查阅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()方法在记录日志方面很有用。

QuickServer开发指南(1)- 介绍

    QuickServer是一个免费的开源Java库,用于快速创建健壮的多线程、多客户端TCP服务器应用程序。使用QuickServer,用户可以只集中处理应用程序的逻辑/协议,从而方便的建立功能...
  • clearwater21cn
  • clearwater21cn
  • 2005-02-22 11:24:00
  • 18451

QuickServer自学笔记(一)

因为最近要写一个CS架构的程序,客户端用的Vb6.0,服务器端我用的QuickServer,因为QuickServer对我来说,是一个新的东西,所以我计划写博客写下我的学习路程。 对于QuikSe...
  • zanglaowei
  • zanglaowei
  • 2015-09-01 16:07:20
  • 2156

QuickServer--在吵闹的环境里快速搭建自己的TcpServer(Pragmatic系列)

作者:江南白衣      虽然现在已是Web Server, Web Service的天下,但偶然还是会因为性能苛刻,或者需要自定义协议的原因,很无辜的要自己做一个Multi-Thread,Multi...
  • joliny
  • joliny
  • 2008-04-13 21:09:00
  • 930

QuickServer开发指南(3)- 构建EchoServer

    学习怎样使用QuickServer库的一个好的方法是学习它提供的例子。在QuickServer安装路径下的examples文件夹里有许多典型的例子。    下面的章节里我们模仿其中的一个例子E...
  • clearwater21cn
  • clearwater21cn
  • 2005-02-24 21:12:00
  • 8890

QuickServer开发指南(8)- XML配置

    在前面的章节里我们扩展了EchoServer。我们已经在类中配置了QuickServer,在某些情况下这是可接受的。但是很多应用更希望用户能够在应用启动后动态配置应用。给QuickServer...
  • clearwater21cn
  • clearwater21cn
  • 2005-02-28 17:05:00
  • 5458

QuickServer开发指南(4)- 添加认证

    现在我们给刚刚创建的服务器添加认证功能。    查看org.quickserver.net.server.QuickServer的文档(docs文件夹下)你可以注意到里面有一个方法    pu...
  • clearwater21cn
  • clearwater21cn
  • 2005-02-25 11:39:00
  • 6433

QuickServer开发指南(6)- 远程管理支持

    我们的EchoServer可能需要修改几个服务器配置参数,如超时消息、最多验证数、最大验证时间。QuickServer支持这些功能而无须改变代码。1. 使用QSAdminServer    当...
  • clearwater21cn
  • clearwater21cn
  • 2005-02-28 11:14:00
  • 4452

QuickServer开发指南(5)- 客户数据

    既然不能在ClientCommandHandler和ServerAuthenticator类中保存客户数据,我们使用ClientData类的handleCommand()或askAuthori...
  • clearwater21cn
  • clearwater21cn
  • 2005-02-25 14:39:00
  • 6399

QuickServer开发指南

  • 2011年06月28日 13:40
  • 210KB
  • 下载

QuickServer

QuickServer是个java开元框架,很方面很容易实现多线程、多客户端TCP服务应用。今天在QuickServer网站http://www.quickserver.org/下载文档Develop...
  • educast
  • educast
  • 2013-10-28 22:25:38
  • 2143
收藏助手
不良信息举报
您举报文章:QuickServer开发指南(7)- 使用和定制日志
举报原因:
原因补充:

(最多只允许输入30个字)