详细介绍ACE日志设施
基本的日志输出设施
用来输出日志的宏有三个:ACE_DEBUG、ACE_ERROR、ACE_TRACE(这三个宏只需要用ACE_DEBUG即可)
其中前两个一模一样,仅仅是名字不同而已。
ACE_DEBUG(( severity, formatting-args ));
ACE_DEBUG(( severity, formatting-args , var_list ));
ACE_DEBUG(( 日志级别, 输出内容和格式, 输出变量列表 ));
日志级别:severity
- LM_DEBUG :你的调试信息
- LM_INFO :你的业务信息
- LM_WARNING:你的告警信息
- LM_ERROR:你的错误信息
日志级别的配置(比如)
-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
请按任意键继续. . .
多线程动态配置日志
使用ACE_Service_Configuration模式动态配置日志
切记:
让事件循环线程和写日志的线程分开(否则不打印日志)
可以更加详细的配置日志,参考: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日志策略,很多麻烦的事情你都不用管了
ACE日志策略
-s 指定文件输出时的文件名
-f 指定输出的目的地:如OSTREAM ,STDERR,LOGGER等;其中STDERR指控制台;
-p 指定输出或者禁止输出的级别,如-p DEBUG|~INFO|ERROR|~WARNING ,对四种日志界别分别指定是否打印,注意这里不是LM_DEBUG、LM_INFO等
-m 指定日志文件的最大尺寸
-N 指定创建的日志文件的最大数目
-w 让日志文件在启动和重新配置时被清除
ACE日志策略其他
你是不是觉得这种配置文件的方式过时了呢?
是的,过时了,所以ACE4.3版后就提供了XML方式的配置文件,并且提供了自动转换以前的配置文件到XML配置文件的方式
关于Linux下使用日志设施:
export LD_LIBRARY_PATH=${ROOT}/lib:/usr/local/lib:${ROOT}/lib/ace
(4.1)把你的程序需要的so放到上面设置的地址里