在使用Poco库开发应用的时候,需要使用日志模块记录程序运行的一些信息。这里介绍一下日志模块的常见用法。
Poco::Logger & logger = Poco::Logger::get("MyApplication");
//@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);
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);
//定义独立线程
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();
}
//自定义格式化类
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);
AutoPtr<TestChannel> pChannel = new TestChannel;
//SplitChannel支持同时输出日志内容到多个管道
AutoPtr<SplitterChannel> pSplitter = new SplitterChannel;
pSplitter->addChannel(pChannel);
pSplitter->addChannel(pChannel);
//写日志
Message msg;
pSplitter->log(msg);
//自定义格式化类
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);