Pantheios 是目前为止 C/C++ 领域速度最快的程序诊断日志库,功能强大,性能突出。下面做一下简单介绍。
Pantheios的本质
1. 是用于程序诊断的日志 api 库,不是诊断日志库。
2. 开源,100% 免费。
3. 依赖几个第三方库,这几个库也是开源和 100% 免费的,包括:
a. xTests 一个 c/c++ 简单的轻量级的单元/组件测试库,这个库只用在 pantheios 的单元测试中
b. b64 一个轻量级的、简单的和性能卓越的 b64 编码实现,用在 pantheios::b64 插入器中
c. shwild 是一个与 unix shell 兼容的通配符库,这个库也只用在 pantheios 的单元测试中
d. STLSOFT 它不是一个 stl 替换库,而是一个 stl 扩展库,它提供了许多系统和编译器差异兼容属性,使 pantheios 的实现更简单。
4. 它的速度非常快,比其它所有重要的日志诊断库都快。日志库性能比较测试
5. 100% 类型安全
6. 在链接时刻选择日志输出工具(比如,后端),原因是:
日志诊断库必须在代码的任何位置都可以使用,而不必等待 main 来设置日志输出。这样做的结果是,使链接设置时有些难度。
7. 扩充性好。
8. 已被一些重要的商业软件使用。
9. 可移植性好已通过各主流的 c++ 编译器的测试。
10.Pantheios 由一个非常活跃的团队开发和维护。
Pantheios的结构
由四个部分组成:
1. 应用层
应用程序使用的 log 表达式,比如 log_DEBUG(), log_INFORMATIONAL() 等等。
2. 核心层
高效地(经常,处理中不用申请任何内存)把各日志元素连在一块。
3. 前端(Front-end)
提供处理表示和检测给定级别的日志是否需要输出。(注:前端库用户可以自己实现也可以使用 Pantheios 已经实现的)
4. 后端(Back-end)
输出 Core 已经准备好的日志到输出流(比如控制台、COM 错误对象、syslog、Windows 事件日志...)。(注:后端库用户可以自己实现,或者使用 Pantheios 已经实现的)
Patheios 应用层组成
1. 每套日志函数支持 1 至 32 个参数
2. 共提供 8 套日志函数,包括:
log_DEBUG()、log_INFORMATIONAL()、log_NOTICE()、log_WARNING()、log_ERROR()、log_CRITICAL()、 log_ALERT() 和 log_EMERGENCY()。
这些与 log() 加相应的级别参数的效果相同。
3. 2 个处理数值的插入器:integer 和 real
4. 1 个处理指针的插入器:pointer
5. 1 个处理无类型内存块的插入器:blob (注:还有一个扩充类,b64,用来表示一个无类型的 Base-64 的内存块。)
通过这些函数和插入器,可以写出很简洁的诊断日志语句,比如:
l 输出一条异常日志
try
{
// ...
} catch ( std::exception& x){
pantheios::log_ERROR("Exception encountered: ", ex);
}
l 带参数的日志输出
void fun(std::string const& sq, char const* s2, struct tm const* t){
pantheios::log(pantheios::debug, "func(", s1, ", ", s2, ", ", t, ")");
l 混合类型参数日志输出
int i;
flost f;
GUID guid;
pantheios::log(pantheios::notice(99)
, "int=", pantheios::integer(i)
, " float=", pantheios::real(f)
, " HWND=", hwnd
, " GUID=", guid);
应用层,只需要头文件 pantheios/pantheios.hpp,如果使用插入器,还要使用 pantheios/inserters.hpp。
Core 层
core 层被应用层调用,在有些情况下,这些 api 对应用层是有用的。比如,
int pantheios_isSeverityLogged(pan_sev_t severity)
被用来检测指定的日志是否需要输出。
另外,通过直接使用 core 的 api,c 代码也可以直接使用 pantheios,这些函数是:
pantheios_printf()和 pantheios_vprintf()
例子如下:
int i;
float f;
pantheios_printf(PANTHEIOS_SEV_INFORMATIONAL, "int=%d, float=%g", i, f);
值得注意的是,如果直接使用这两个函数,pantheios 就不能给你提供类型安全的调用了。
Front-end(前端)
前端是一个提供 4 个函数的库,提供日志表达和检测时使用的进程标识,运行时,用来检测是否指定级别的日志需要输出:
1. PANTHEIOS_CALL(int) pantheios_fe_init(int reserved, void** ptoken);
2. PANTHEIOS_CALL(int) pantheios_fe_uninit(void* token);
3. PANTHEIOS_CALL(char const*) pantheios_fe_processIdentity(void *token);
4. PANTHEIOS_CALL(int) pantheios_fe_isSeverityLogged(void* token, int severity, int backEndId);
pantheios_fe_init()、pantheios_fe_uninit() 和 pantheios_fe_processIdentity() 在库初始化的时候只需要调用一次。
pantheios_fe_isSeverityLogged() 在输出日志时都被调用,用来检查指定级别的日志是否需要输出给 back_end。
前端的选择在软件链接时刻进行选择。
Pantheios 提供了一个前端实现:fe.simple。
fe.simple 的使用只需要两个简单的步骤:
1. 链接这个库
比如在 vc9 下,debug 你需要链接库
pantheios.1.fe.simple.vc9.mt.debug.lib
release 你需要链接
pantheios.1.fe.simple.vc9.mt.lib
如果你的编译器支持隐含链接(implicit linking,比如 vc),你只需要包括指定的头文件就可以了:
#include
2. 在你的程序中添加下面语句:
PANTHEIOS_EXTERN_C const char PANTHEIOS_FE_PROCESS_IDENTITY[] = "my-process";
这个符号 fe.simple 的函数 pantheios_fe_processIdentity() 里面需要用到。
用户自定义前端实现指导
实现一个自定义的前端的工作是相当简单的。最小的实现要求只是要求你实现的函数 pantheios_fe_processIdentit