当前位置: 首页 > 工具软件 > Poco > 使用案例 >

Poco库使用:日志模块

罗俭
2023-12-01

在使用Poco库开发应用的时候,需要使用日志模块记录程序运行的一些信息。这里介绍一下日志模块的常见用法。

1.获取固定名称的日志类

Poco::Logger & logger = Poco::Logger::get("MyApplication");

2.格式化日志的输出内容

//@1设置日志输出的文件地址
//output 文件格式
AutoPtr<FormattingChannel>  GetLogFormatChannel(std::string log_file_path)
{
	//添加对应的日志输出通道
	AutoPtr<FileChannel> pChannel(new FileChannel);
	std::string logFilePath = log_file_path;
    
    //日志的文件路径
	pChannel->setProperty("path", logFilePath);
   
   //是否切换文件(防止单一文件太大)
   //这里选否,意思是所有日志内容输出到一个文件里面
	pChannel->setProperty("rotation", "never");
   
   //文件切换的时候追加的后缀类型
   //可以是数字number也可以是时间timestamp 
	pChannel->setProperty("archive", "timestamp");
  
    //是否对文件内容进行压缩
   pChannel->setProperty("compress", "false");
   
   //定时清理日志文件
   ///* <n> [seconds]
	///* <n> minutes
	///* <n> hours
	///* <n> days
	///* <n> weeks
	///* <n> months (a month 30 days)
   //10天清理一次文件
   pChannel->setProperty("purgeAge", "10 days");
   
   //日志输出的格式%Y(年格式1970)%m(月格式01~12)%d(日格式01~31)
   //小时格式%H(00~23)分钟格式%M(00~59) 秒钟格式%S(00~59)
   //日志严重程度%p(Fatal, Critical, Error, Warning, Notice, Information, Debug, Trace)
   //消息源%s  日志文本%t
	AutoPtr<PatternFormatter> pPF(new PatternFormatter("%Y-%m-%d %L%H:%M:%S %p %s:%t"));
	AutoPtr<FormattingChannel> pFC(new FormattingChannel(pPF, pChannel));
	return pFC;
}


Poco::Logger & logger = Poco::Logger::get("MyApplication");
//设置对应的输出通道
AutoPtr<FormattingChannel>  log_channel = GetLogFormatChannel(log_file_path);
//在日志类中添加日志文件地址和日志的输出格式
logger.setChannel(log_channel);

3.使用宏输出对应的日志内容

Poco::Logger & logger = Poco::Logger::get("MyApplication");

//输出不带变量的日志内容
poco_information(logger, "task start");
poco_error(logger, "run tools failed");

//输出带一个参数的日志内容
poco_error_f1(logger, "throw exception:%s", "test");

//输出带两个参数的日志内容
poco_information_f2(logger, "type is:%s,return:%d", "test", 20);

4.采用独立线程输出日志内容

//定义独立线程
class LogRunnable : public Runnable
{
public:
	LogRunnable(AutoPtr<AsyncChannel> pAsync):
		_pAsync(pAsync),
		_stop(false)
	{
	}
	void run()
	{
		Message msg;
		while (!_stop) _pAsync->log(msg);
	}
	void stop()
	{
		_stop = true;
	}
private:
	AutoPtr<AsyncChannel> _pAsync;
	std::atomic<bool> _stop;
};
//在独立线程里面运行日志
int run_log_in_thread()
{
    //定义异步管道
    AutoPtr<ConsoleChannel> pChannel = new ConsoleChannel;
    AutoPtr<AsyncChannel> pAsync = new AsyncChannel(pChannel);
    //管道放到线程里面
    LogRunnable log_runner(pAsync);
    pAsync->open();
    //运行异步线程
    Thread log_thread;
    log_thread.start(log_runner);
    //输出日志内容
    Message msg;
    pAsync->log(msg);
    pAsync->close();
    //停止执行
    log_runner.stop();
    log_thread.join();
    int msg_size = pChannel->list().size();
}

5.输出日志内容到终端

//自定义格式化类
class SimpleFormatter: public Formatter
{
public:
	void format(const Message& msg, std::string& text)
	{
		text = msg.getSource();
		text.append(": ");
		text.append(msg.getText());
	}
};

//设置终端输出管道
AutoPtr<ConsoleChannel> pChannel = new ConsoleChannel;
AutoPtr<Formatter> pFormatter = new SimpleFormatter;
AutoPtr<FormattingChannel> pFormatterChannel = new FormattingChannel(pFormatter, pChannel);

//输出日志消息
Message msg("Source", "Text", Message::PRIO_INFORMATION);
pFormatterChannel->log(msg);

6.日志内容同时输出给多个管道

AutoPtr<TestChannel> pChannel = new TestChannel;
//SplitChannel支持同时输出日志内容到多个管道
AutoPtr<SplitterChannel> pSplitter = new SplitterChannel;
pSplitter->addChannel(pChannel);
pSplitter->addChannel(pChannel);
//写日志
Message msg;
pSplitter->log(msg);

7.输出日志内容到流中

//自定义格式化类
class SimpleFormatter: public Formatter
{
public:
	void format(const Message& msg, std::string& text)
	{
		text = msg.getSource();
		text.append(": ");
		text.append(msg.getText());
	}
};
//指定流管道
std::ostringstream str;
AutoPtr<StreamChannel> pChannel = new StreamChannel(str);

//使用自定义的格式化类
AutoPtr<Formatter> pFormatter = new SimpleFormatter;
AutoPtr<FormattingChannel> pFormatterChannel = new FormattingChannel(pFormatter, pChannel);

//输出日志内容到字符流
Message msg("Source", "Text", Message::PRIO_INFORMATION);
pFormatterChannel->log(msg);
//assertTrue (str.str().find("Source: Text") == 0);
 类似资料: