日志对于程序来说是非常重要的,特别是对一些大型程序而言。一旦程序被发布,在现场日志几乎是程序员唯一可以获取程序信息的手段。Poco作为一个框架类库,提供了非常多的日志种类供程序员选用。文章将分两个部分,对于Poco日志进行介绍。第一部分主要以翻译Poco文档为主,第二部分则探讨Poco日志的实现。
Poco中的日志模块主要涉及下列几个部分。
1. 消息,日志和通道
2. 格式
3. 执行效率的考量
模块框架图:
void setPriority(Priority prio)
Priority getPriority() const
void setSource(const std::string& source)
const std::string& getSource() const
void setText(const std::string& text)
const std::string& getText() const
void setTime(const Timestamp& time)
const Timestamp& getTime() const
void setThread(const std::string& threadName)
const std::string& getThread() const
void setTid(long tid)
long getTid() const
void setPid(long pid)
long getPid() const
void fatal(const std::string& text)
void critical(const std::string& text)
void error(const std::string& text)
void warning(const std::string& text)
void notice(const std::string& text)
void information(const std::string& text)
void debug(const std::string& text)
void trace(const std::string& text)
4. 使用给定的优先级和内容记录消息。消息的内容为16进制的给定Dump数据块。
bool critical() const
bool error() const
bool warning() const
bool notice() const
bool information() const
bool debug() const
bool trace() const
bool fatal() const
如果logger的日志级别等于或高于给定的日志级别,返回true
#include "Poco/Logger.h"
using Poco::Logger;
int main(int argc, char** argv)
{
Logger& logger = Logger::get("TestLogger");
logger.information("This is an informational message");
logger.warning("This is a warning message");
return 0;
}
void setProperty(const std::string& name, const std::string& value)
std::string getProperty(const sdt::string& name)
这两个函数被定义在Poco::Configurable中,Poco::Configurable为Poco::Channel的父类。
#include "Poco/Logger.h"
#include "Poco/SimpleFileChannel.h"
#include "Poco/AutoPtr.h"
using Poco::Logger;
using Poco::SimpleFileChannel;
using Poco::AutoPtr;
int main(int argc, char** argv)
{
AutoPtr pChannel(new SimpleFileChannel);
pChannel->setProperty("path", "sample.log");
pChannel->setProperty("rotation", "2 K");
Logger::root().setChannel(pChannel);
Logger& logger = Logger::get("TestLogger"); // inherits root channel
for (int i = 0; i < 100; ++i)
logger.information("Testing SimpleFileChannel");
return 0;
}
#include "Poco/Logger.h"
#include "Poco/FileChannel.h"
#include "Poco/AutoPtr.h"
using Poco::Logger;
using Poco::FileChannel;
using Poco::AutoPtr;
int main(int argc, char** argv)
{
AutoPtr pChannel(new FileChannel);
pChannel->setProperty("path", "sample.log");
pChannel->setProperty("rotation", "2 K");
pChannel->setProperty("archive", "timestamp");
Logger::root().setChannel(pChannel);
Logger& logger = Logger::get("TestLogger"); // inherits root channel
for (int i = 0; i < 100; ++i)
logger.information("Testing FileChannel");
return 0;
}
#include "Poco/Logger.h"
#include "Poco/AsyncChannel.h"
#include "Poco/ConsoleChannel.h"
#include "Poco/AutoPtr.h"
using Poco::Logger;
using Poco::AsyncChannel;
using Poco::ConsoleChannel;
using Poco::AutoPtr;
int main(int argc, char** argv)
{
AutoPtr pCons(new ConsoleChannel);
AutoPtr pAsync(new AsyncChannel(pCons));
Logger::root().setChannel(pAsync);
Logger& logger = Logger::get("TestLogger");
for (int i = 0; i < 10; ++i)
logger.information("This is a test");
return 0;
}
#include "Poco/Logger.h"
#include "Poco/SplitterChannel.h"
#include "Poco/ConsoleChannel.h"
#include "Poco/SimpleFileChannel.h"
#include "Poco/AutoPtr.h"
using Poco::Logger;
using Poco::SplitterChannel;
using Poco::ConsoleChannel;
using Poco::SimpleFileChannel;
using Poco::AutoPtr;
int main(int argc, char** argv)
{
AutoPtr pCons(new ConsoleChannel);
AutoPtr pFile(new SimpleFileChannel("test.log"));
AutoPtr pSplitter(new SplitterChannel);
pSplitter->addChannel(pCons);
pSplitter->addChannel(pFile);
Logger::root().setChannel(pSplitter);
Logger::root().information("This is a test");
return 0;
}
LogStream& priority(Message::Priority prio)
LogStream& fatal()
LogStream& critical()
LogStream& error()
LogStream& warning()
LogStream& notice()
LogStream& information()
LogStream& debug()
LogStream& trace
#include "Poco/LogStream.h"
#include "Poco/Logger.h"
using Poco::Logger;
using Poco::LogStream;
int main(int argc, char** argv)
{
Logger& logger = Logger::get("TestLogger");
LogStream lstr(logger);
lstr << "This is a test" << std::endl;
return 0;
}
#include "Poco/ConsoleChannel.h"
#include "Poco/FormattingChannel.h"
#include "Poco/PatternFormatter.h"
#include "Poco/Logger.h"
#include "Poco/AutoPtr.h"
using Poco::ConsoleChannel;
using Poco::FormattingChannel;
using Poco::PatternFormatter;
using Poco::Logger;
using Poco::AutoPtr;
int main(int argc, char** argv)
{
AutoPtr pCons(new ConsoleChannel);
AutoPtr pPF(new PatternFormatter);
pPF->setProperty("pattern", "%Y-%m-%d %H:%M:%S %s: %t");
AutoPtr pFC(new FormattingChannel(pPF, pCons));
Logger::root().setChannel(pFC);
Logger::get("TestChannel").information("This is a test");
return 0;
}
// ...
if (logger.warning())
{
std::string msg("This is a warning");
logger.warning(msg);
}
// is equivalent to
poco_warning(logger, "This is a warning");