用来输出日志的宏有三个:ACE_DEBUG、ACE_ERROR、ACE_TRACE(这三个宏只需要用ACE_DEBUG即可)
其中前两个一模一样,仅仅是名字不同而已。
ACE_DEBUG(( severity, formatting-args ));
ACE_DEBUG(( severity, formatting-args , var_list ));
ACE_DEBUG(( 日志级别, 输出内容和格式, 输出变量列表 ));
日志级别的配置(比如)
-p DEBUG|~INFO|~ERROR|~WARNING上面的配置表示输出DEBUE级别,其他的不输出),各级别都是平行的关系
formatting-args为格式化参数类似printf()函数,格式如下:
例如:
ACE_DEBUG((LM_INFO,"CPU id[%Q] find\n",id));//id 为long long 类型
ACE_DEBUG((LM_ERROR,"can't find id[%d] \n",id));//id 为int类型
日志重定向之前最好清除原来的定向
void clr_flags (u_long f);
之后设置要重定向的地方
void set_flags (u_long f);
日志重定向的参数如下:
例如:
ACE_LOG_MSG->set_flags(ACE_Log_Msg::STDERR | ACE_Log_Msg::VERBOSE);
显示如下:
2014-09-24 10:43:41.096@<local_host>@2728@LM_ERROR@ACE_INET_Addr::ACE_INET_Addr: <unknown>: Invalid argument
2014-09-24 10:43:41.097@<local_host>@2728@LM_ERROR@[2014-09-24 10:43:41.097001][line:533]ACE_Asynch_Write_Dgram::recv: address family not supported
请按任意键继续. . .
切记:
让事件循环线程和写日志的线程分开(否则不打印日志)
可以更加详细的配置日志,参考:http://blog.csdn.net/bat603/article/details/2441905
其中ACE_Service_Configuration配置的最小示例参考:http://blog.csdn.net/calmreason/article/details/21049259 其中有配置文件的存放和使用等详细信息。
示例:
#include <iostream> #include <string> #include "ace/Log_Msg.h" #include "ace/Service_Config.h" using namespace std; #include "ace/Task.h" #include "ace/Reactor.h" class TestLogTask : public ACE_Task<ACE_MT_SYNCH> { public: int open(void* n) { ACE_DEBUG((LM_DEBUG, "(%t) TestLogTask opened\n")); //Activate the Task activate(THR_NEW_LWP,*static_cast<int*>(n)); return 0; } int svc(void) { size_t line = 1000; for (size_t i =0;i<line;++i) { ACE_DEBUG((LM_ERROR,"this is line %d*************************************************************************\n",i)); ACE_DEBUG((LM_DEBUG,"this is a line %d*************************************************************************\n",i)); ACE_DEBUG((LM_WARNING,"this is a line %d*************************************************************************\n",i)); ACE_DEBUG((LM_INFO,"this is a line %d*************************************************************************\n",i)); } cout<<"run svc finished!"<<endl; return 0; } }; int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { if (ACE_Service_Config::open(argc,argv, ACE_DEFAULT_LOGGER_KEY,1,0,1) < 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%p/n"), ACE_TEXT("Service Config open")), -1); } TestLogTask t; //创建三个线程同时打印 int thread_number = 3; t.open(&thread_number); ACE_Reactor::instance()->run_reactor_event_loop(); ACE_Thread_Manager::instance()->wait(); return 0; }
dynamic Logger Service_Object * ACE:_make_ACE_Logging_Strategy() "-s log.out -f STDERR|OSTREAM|VERBOSE_LITE -p DEBUG|~INFO|~ERROR|~WARNING -i 1 -N 10 -m 20000 -o -w"由于20000指定了日志文件过大,所以没拆分,如果设置为100是会拆分的(已经验证,读者也可以自己试试);之所以设这么大,是为了方便后面验证三个线程是否都在一直打印
输出截图:(说明三个线程都打印到了最后一条)
上图是其中一个线程打印的最后一条日志
上图是剩下的两个线程打印的最后两条日志。
本示例下载地址:http://pan.baidu.com/s/1c01svcO点击打开链接
说明:
直接运行Debug目录里面的exe即可看到效果,可以先把原来的log文件删除
如果你要重新编译项目,项目VC++属性里面有include路径和library路径,你要确定这两个路径里面有ace目录和lib目录。
如果你的两个目录和我的不一样,那就替换成你自己的对应的ACE的头文件路径和库文件路径,这个两个路径只能保证你编译,不能保证运行,如果你要运行就把你自己的ACE库文件拷贝到项目的Debug目录替换我给你的默认库文件。
详细设置参考:http://blog.csdn.net/calmreason/article/details/38082009点击打开链接
切记:
让事件循环线程和写日志的线程分开
为什么要使用ACE日志策略?
因为使用ACE日志策略可以使我们以配置的方式对日志输出进行管理
更为重要的是,其利用配置参数可以控制日志输出中的各种问题,
如:可以配置当应用的日志文件到达指定尺寸是,它能够换用新的日志文件
也可也配置要保留的文件最大数目
总之,用上ACE日志策略,很多麻烦的事情你都不用管了
-m 指定日志文件的最大尺寸
-N 指定创建的日志文件的最大数目
-w 让日志文件在启动和重新配置时被清除
ACE日志策略其他
你是不是觉得这种配置文件的方式过时了呢?
是的,过时了,所以ACE4.3版后就提供了XML方式的配置文件,并且提供了自动转换以前的配置文件到XML配置文件的方式
export LD_LIBRARY_PATH=${ROOT}/lib:/usr/local/lib:${ROOT}/lib/ace(4.1)把你的程序需要的so放到上面设置的地址里