Poco::Logger 日志库使用示例(上)

引言
日志对于程序来说是非常重要的,特别是对一些大型程序而言。一旦程序被发布,在现场日志几乎是程序员唯一可以获取程序信息的手段。

使用步骤

  • 1 生成消息
  • 2 写入logger
  • 3 导入channel
  • 4 写文件

生成消息

POCO使用Poco::Message 对象存储和传递日志信息。
#include “Poco/Message.h”

日志消息(Message)包括:

  • 优先级(priority):定义八个消息优先级
  • 消息源(source):描述一个日志的消息源
  • 文本(text):实际的消息将被记录。
  • 时间戳(timestamp):创建的日期和时间信息,微秒精度。
  • 进程和线程标识符
  • 可选参数<名称-值>对

此处只列出一个,具体查看文档

优先级(priority)
POCO的定义八个消息优先级:

  1. PRIO_FATAL (最高优先级)
  2. PRIO_CRITICAL
  3. PRIO_ERROR
  4. PRIO_WARNING
  5. PRIO_NOTICE
  6. PRIO_INFORMATION
  7. PRIO_DEBUG
  8. PRIO_TRACE (最低优先级)
 **API接口:**
//可以通过函数设置和获取消息优先级:
void setPriority(Priority prio)
Priority getPriority() const 

日志类(Logger)

POCO::Logger 是日志框架的主入口点。
#include “Poco/Logger.h”

  • 应用程序使用POCO::Logger类的实例生成日志消息。
  • 每一个日志附属通道(channel),通道用于传递消息。
  • 每一个日志都拥有一个名称,名称用于表示消息源。日志名称设置有不能改变。
    层次结构(Logger Hierarchy)
  • 日志名称可由一个或多个日志组件组成,各个日志组件有自己独立的名称范围。
  • 每个日志组件的名称都会包含上级日志组件的名称。树型结构的根是名称为空的日志组件。
  • 树型结构没有最大深度的限制。
|---- "" (the root logger)
          |
          |-----"HTTPServer"
              |
              |-----"HTTPServer.RequestHandler"
              |
              |-----"HTTPServer.RequestHandler.File"
              |
              |-----"HTTPServer.RequestHandler.CGI"
              |
              |------"HTTPServer.Listener"

//!."HTTPServer.RequestHandler.CGI" 继承"HTTPServer.RequestHandler"的级别和通道

访问日志对象

  • POCO库在内部全局管理日志。用户不用创建日志对象,只要从POCO库获取日志引用。
  • POCO根据需要创建新的日志。
  • static Logger& get(const std::string&
    name),获取POCO提供的名为name的日志引用,这个日志由POCO内部创建。保存获得的日志引用是安全的。
#include "Poco/Logger.h" 
using Poco::Logger; 
int main(int argc, char** argv) 
{ 
    Logger& logger = Logger::get("MyLogger"); 
    logger.information("This is an informational message"); 
    logger.warning("This is a warning message"); 
    return 0; 
}

通道类(Channels)

  • Poco::Channel的子类负责传递消息到目的地(如控制台、日志文件)。
  • Poco::Logger也是Poco::Channel的子类,Poco::Logger与Poco::Channel连接。
  • POCO提供有多个Poco::Channel子类,使用不同的子类可以把消息发送到控制台、日志文件或系统日志服务。
  • 用户可以定义自己的Channel类。
  • Channel使用应用计数进行内存管理(智能指针)

通道属性

  • 通道提供任意数量的可配置属性(“名称-值”对)。
void setProperty(const std::string& name, const std::string& value)

std::string getProperty(const sdt::string& name)

例如文件通道(FileChannel),使用智能指针管理内存

//name属性           说明 
//path           主文件路径 
//secondaryPath  备用文件路径。默认为<path>.1 

void setProperty(const std::string& name, const std::string& value);
  • 在文件中追加一行消息文本。
  • 文件轮换支持基于文件大小或时间间隔方式进行。
  • 支持文件自动归档、压缩和清除
#include "Poco/FileChannel.h"

//实例化
AutoPtr模板类,类型为PatternFormatter
AutoPtr<PatternFormatter> formatter(new PatternFormatter);
formatter->setProperty("times","local");
formatter->setProperty("pattern","%Y-%m-%d-%m-%d %H:%M:%s-%Y:%t");
file_channel>setProperty("path",switchFileName(logFilename));

控制台通道(ConsoleChannel)

  • Poco::ConsoleChannel是最基本的通道实现。
  • 将消息文本输出到标准输出(std::clog)不具备配置属性根日志的默认通道
AutoPtr<ConsoleChannel> console_channel(new ConsoleChannel);

分发通道(SplitterChannel)

  • Poco::SplitterChannel将消息分发到一个或多个通道。
void addChannel(Channel* pChannel)//添加一个新通道到Poco::SplitterChannel

#include "Poco/SplitterChannel.h"

AutoPtr<SplitterChannel> splitter_Channel(new SplitterChannel);
splitter_Channel->addChannel(file_channel);
splitter_Channel->addChannel(console_channel);

日志流类(LogStream)

  • Poco::LogStream给Logger提供一个流(ostream)接口。
  • 所有流(ostream)的特性都能用于格式化日志消息。
  • 日志流的消息必须以std::endl(或CR、LF字符)结尾。
#include "Poco/LogStream.h"

日志消息格式化(Message Formatting)

  • Poco::FormattingChannel与Poco::Formatter用于格式化日志消息。
  • Poco::FormattingChannel收到消息后,将消息先通过Poco::Formatter处理,然后输出到下一个通道。
  • Poco::Formatter i是所有格式化类的基类。channels,formatters都是可配置的。
#include "Poco/FormattingChannel.h"

#include "Poco/Formatter.h"
AutoPtr<PatternFormatter> pattern_formatter (new PatternFormatter("%L%H:%M:%S-code line :%u-%U : %t"));
AutoPtr<FormattingChannel> formatter_channle(new FormattingChannel(pattern_formatter , file_channel));

模式格式化类(PatternFormatter)

  • Poco::PatternFormatter使用打印模式格式化消息。

性能注意事项

  • 创建消息会消耗一些时间(需要判断当前时间、进程ID和线程ID。
  • 创建有意义的消息可能消耗更多的时间,因为需要文本拼接、格式化等必须的操作。
  • 消息文本通过通道链传输。
  • FormattingChannel和AsyncChannel会创建消息copy。
  • 记录日志经常会为每个日志启用或禁用日志(或者,更正确来说,设置日志级别),如果你拥有一个日志引用,那么使用日志引用来判断日志级别,是一个常数时间操作。
  • 通常,只需要在应用程序中做一次获取日志引用(Logger::get())操作。例如在类的构造函数中获取日志引用,然后使用日志对象的引用。
  • 用户应当避免频繁调用Logger::get()。最好是调用一次、保存下来,然后使用。
  • 日志的性能依赖于通道。
  • 构造日志消息需要一定的时间消耗。
  • 因此,建议在构造消息前,首先使用 is(), fatal(), critical()等接口核实是否需要构建。
  • POCO提供用于核实构造消息的宏:poco_fatal(msg), poco_critical(msg),poco_error(msg)等等。
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值