代码改变世界

ACE日志输出的几种重定向方式

2011-11-22 22:44  咆哮的马甲  阅读(1924)  评论(0编辑  收藏  举报

初学ACE,将自己的一些总结放在这里与大家分享,希望能有所帮助。不当之处恳请大家指正。

1. 输出到stderr

ACE输出的默认方式,将日志输出到控制台。如果希望从其他的重定向方式切换到stderr,可以采用如下的方式。

1 ACE_LOG_MSG->open (0, ACE_Log_Msg::STDERR);
2 ACE_DEBUG ((LM_INFO, ACE_TEXT ("Hello ACE Stderr Log\n")));

或者

1 ACE_LOG_MSG->clr_flags(ACE_Log_Msg::OSTREAM | ACE_Log_Msg::LOGGER);
2 ACE_LOG_MSG->set_flags (ACE_Log_Msg::STDERR);
3 ACE_DEBUG ((LM_INFO, ACE_TEXT ("Hello ACE Stderr Log\n")));

输出结果:

 

2. 输出到系统日志

1 ACE_LOG_MSG->open (0, ACE_Log_Msg::SYSLOG, "SysLog");
2 ACE_DEBUG ((LM_INFO, ACE_TEXT ("Hello ACE Sys Log\n")));

输出到系统日志不能通过set_flags(ACE_Log_Msg::SYSLOG)实现,原因是输出到系统日志需要ACE_LOG_MSG->open方法去做一些初始化的工作。同时,clr_flags方法同样不能阻止将日志输出到系统中日志中去,正确的做法是使用ACE_LOG_MSG->open方法将日志重定向到其他地方。


3. 输出到文件

1 ACE_OSTREAM_TYPE *output =  new std::ofstream ("logfile.txt");
2 ACE_LOG_MSG->msg_ostream (output, 1);
3 ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM);
4 ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER);
5 ACE_DEBUG ((LM_INFO, ACE_TEXT ("Hello ACE file Log\n")));


输出结果:


4. 输出到分布式的日志服务器

基于netsvc日志的CS构架,日志服务器用来接收其他服务器发送的日志请求。

  A. 配置并启动日志服务器

    i. 配置文件server.conf 的内容如下 

1 dynamic Logger Service_Object * ACE:_make_ACE_Logging_Strategy() "-s foobar -f  STDERR|OSTREAM|VERBOSE"
2 dynamic Server_Logging_Service Service_Object * netsvcs:_make_ACE_Server_Logging_Acceptor() active "-p 20009"

      第一行定义了logging strategy,将更详尽的(Verbose)日志输出到foobar文件和stderr中。
      第二行配置server监听20009端口

    ii. 启动日志服务器

ACE_wrappers\netsvcs\servers\ace_netsvcs.exe -f server.conf


  输出结果:

 

   B. 配置并启动客户端代理服务器

    i. 配置文件client.conf 的内容如下

dynamic Client_Logging_Service Service_Object * netsvcs:_make_ACE_Client_Logging_Acceptor() active "-p 20009 -h localhost"

             配置文件告诉client proxy server日志服务器的主机名(-h)及其所监听的端口号(-p)

    ii. 启动client proxy server

ACE_wrappers\netsvcs\servers\ace_netsvcs.exe -f clinet.conf

  

  client proxy输出结果:

  

  logging server输出结果:

 

  C. 将日志重定向到日志服务器
1 ACE_LOG_MSG->open (prog_name, ACE_Log_Msg::LOGGER, ACE_DEFAULT_LOGGER_KEY);
2 ACE_DEBUG ((LM_INFO, ACE_TEXT ("Hello ACE daemon Log\n")));

    ACE_DEFAULT_LOGGER_KEYclient proxy server的默认地址及其监听端口(localhost:20012),这个值可以在client.conf中进行配置 (通过-k参数)

  

  client proxy输出结果:

  

  logging server输出结果:

  

  logging server文件输出结果:

 

5. 使用callback在运行时修改log信息

Log信息可以通过callback的机制在运行时进行修改

  A. ACE_Log_Msg_Callback类继承一个子类,并重写log方法

 1 class MyCallback : public ACE_Log_Msg_Callback
2 {
3 public:
4 void log (ACE_Log_Record &log_record);
5 };
6
7
8 void MyCallback::log(ACE_Log_Record &log_record)
9 {
10 cerr << "Log Message Received:" << endl;
11 unsigned long msg_severity = log_record.type ();
12 ACE_Log_Priority prio = static_cast<ACE_Log_Priority>(msg_severity);
13
14 const ACE_TCHAR *prio_name = ACE_Log_Record::priority_name (prio);
15 cerr << "\tType: "
16 << ACE_TEXT_ALWAYS_CHAR (prio_name)
17 << endl;
18
19 cerr << "\tLength: " << log_record.length () << endl;
20
21 const time_t epoch = log_record.time_stamp ().sec ();
22 cerr << "\tTime_Stamp: "
23 << ACE_TEXT_ALWAYS_CHAR (ACE_OS::ctime (&epoch))
24 << flush;
25
26 cerr << "\tPid: " << log_record.pid () << endl;
27
28 ACE_CString data (">> ");
29 data += ACE_TEXT_ALWAYS_CHAR (log_record.msg_data ());
30
31 cerr << "\tMsgData: " << data.c_str () << endl;
32 }

  

  B. 创建该子类的一个对象

1 MyCallback* myCallback = new MyCallback();

  

  C. 将该对象注册到ACE_Log_Msg实例中

 1 ACE_LOG_MSG->msg_callback (myCallback);
2 if (callback == 0)
3 {
4 ACE_LOG_MSG->clr_flags (ACE_Log_Msg::MSG_CALLBACK);
5 }
6 else
7 {
8 ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER | ACE_Log_Msg::OSTREAM);
9 ACE_LOG_MSG->set_flags (ACE_Log_Msg::MSG_CALLBACK);
10 }
11 ACE_DEBUG ((LM_INFO, ACE_TEXT ("Hello ACE callback Log\n")));


  输出结果:


完整的程序示例


参考文章:

《Addison Wesley - The.ACE.Programmers.Guide》

 ACE中日志系统(Logging Facility)的基本使用 - http://blog.csdn.net/cheng168520/article/details/4396410

 ACE学习笔记(二):ACE日志系统(2) - http://masterdog.blogchina.com/blog/984024.html