C++第三方日志库Pantheios

简介
在项目实践中发现一个好的日志记录非常重要,你需要借助Logging才能跟踪软件中的错误。所以这里研究下第三方C++库Pantheios的使用。

Pantheios是一个完全开源的第三方库,依赖stlsoft。具体使用方法如下:

第一步:从参考资料[1]下载pantheios-1.0.1-beta213.zip压缩包,并解压。

为pantheios配置系统环境变量,例如

PANTHEIOS_ROOT=E:\SDK\pantheios-1.0.1-beta213

其中“E:\SDK\pantheios-1.0.1-beta213”是解压后的位置

第二步:从参考资料[2]下载stlsoft-1.9.111-hdrs.zip压缩包,并解压。

为stlsoft配置系统环境变量,例如

STLSOFT=E:\SDK\stlsoft-1.9.111

里面只有些头文件,但是我们只需要头文件就足够了。

第三步:启动Visual Studio 2008 命令行,它的位置在[开始]->[ Microsoft Visual Studio 2008]->[ Visual Studio Tools]->[Visual Studio 2008 Command Prompt]。

在VS2008命令行中转到“E:\SDK\pantheios-1.0.1-beta213\build\vc9”路径,输入命令“NMAKE BUILD”开始建立Pantheios库和样例,等待编译、链接完成。

第四步:在VS2008里配置头文件路径和库文件路径

我这里分别是“E:\SDK\pantheios-1.0.1-beta213\include”

“E:\SDK\stlsoft-1.9.111\include”

“E:\SDK\pantheios-1.0.1-beta213\lib”

Pantheios调用示例

    项目运行时,Explicitly方式,需要输入依赖库名称,这时你需要“Pantheios Library Selector Tool”在参考资料[4]中下载。参考资料[5]把链接库列表从应用程序中复制出来,张贴到你的项目依赖项(库)中,实际使用碰到了很多问题(例如复制到剪贴板按钮失灵,依赖库找不到、依赖库冲突)所以本文不采用这种方式。

这里由简入繁,举了三个实例来说明Pantheios的使用,它们均是在VS2008的 Win32 Console Application向导中建立和测试通过的。

第一个例子,输出日志到文件中

只有一个源文件源码如下,编译顺利的话可以直接运行:

[cpp] view plain copy
// testFile.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"  //指定链接库.begin
#include <pantheios/implicit_link/core.h>
#include <pantheios/implicit_link/fe.simple.h>
#include <pantheios/implicit_link/be.file.h>
//指定链接库.end  #define PANTHEIOS_NO_INCLUDE_OS_AND_3PTYLIB_STRING_ACCESS // Faster compilation  /* Pantheios Header Files */
#include <pantheios/pantheios.hpp>            // Pantheios C++ main header
#include <pantheios/backends/bec.file.h>      // be.file header  /* Standard C/C++ Header Files */
#include <exception>                          // for std::exception
#include <new>                                // for std::bad_alloc
#include <string>                             // for std::string
#include <stdlib.h>                           // for exit codes  PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PANTHEIOS_LITERAL_STRING("testFile");
#define PSTR(x)         PANTHEIOS_LITERAL_STRING(x)  int _tmain(int argc, _TCHAR* argv[])
{  try  {  //设置文件名  pantheios_be_file_setFilePath(PSTR("kagula-%D-%T.log"),   PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BEID_ALL);  //打印到文件  pantheios::log_NOTICE(PSTR("stmt 1"));  pantheios::log_NOTICE(PSTR("stmt 2"));  pantheios::log_NOTICE(PSTR("stmt 3"));  pantheios::log_DEBUG(PSTR("exiting main()"));  return EXIT_SUCCESS;  }  catch(std::bad_alloc&)  {  pantheios::log_ALERT(PSTR("out of memory"));  }  catch(std::exception& x)  {  pantheios::log_CRITICAL(PSTR("Exception: "), x);  }  catch(...)  {  //如果只是打印一条字符串形式的信息,建议用下面这种形式打印日志!  pantheios::logputs(pantheios::emergency, PSTR("Unexpected unknown error"));  }  return EXIT_FAILURE;
}  第二个例子,输出日志到Windows控制台
有三个源文件组成,stdafx.h文件插入了“MY_PROCESS_ID”宏,定义当前进程名称。implicit_link.cpp文件,用来指定链接库和日志输出等级,第三个文件T2.cpp是示例代码,列举了不同水平的信息输出,和如何格式化输出信息。stdafx.h源码[cpp] view plain copy
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//  #pragma once  #include "targetver.h"  #include <stdio.h>
#include <tchar.h>  // TODO: reference additional headers your program requires here
#define MY_PROGRAM_ID "MyProgramID"
implicit_link.cpp源码[cpp] view plain copy
#include "stdafx.h"  #include <pantheios/implicit_link/core.h>  //如果定义了USER_SPECIFIED_LEVEL宏定义,则使用用户自定义的输出等级
//如果不定义“USER_SPECIFIED_LEVEL”宏,表示所有等级的信息都输出
#define USER_SPECIFIED_LEVEL  #ifndef USER_SPECIFIED_LEVEL  #include <pantheios/implicit_link/fe.simple.h>
#endif  //一旦加入下面这条include语句,程序的log输出就会转到Windows控制台
//在本例中,这条语句是必须的。
#include <pantheios/implicit_link/be.WindowsConsole.h>  #ifdef USER_SPECIFIED_LEVEL
PANTHEIOS_CALL(int) pantheios_fe_init(void*   reserved,void**  ptoken)
{  *ptoken = NULL;  return 0;
}  PANTHEIOS_CALL(void) pantheios_fe_uninit(void* token)
{}  PANTHEIOS_CALL(PAN_CHAR_T const*)  pantheios_fe_getProcessIdentity  (void *  token)
{  return PANTHEIOS_LITERAL_STRING(MY_PROGRAM_ID);
}  PANTHEIOS_CALL(int) pantheios_fe_isSeverityLogged(void* token  , int   severity  , int   backEndId)
{  //数值越小说明要输出的信息越重要,常用的越先级大小如下  //SEV_CRITICAL=2 < SEV_ERROR=3 < SEV_WARNING=4 < SEV_INFORMATIONAL=6  if(severity <= pantheios::SEV_INFORMATIONAL)  return 1;//允许输出  return 0;
}  #endif  T2.cpp源码
[cpp] view plain copy
// T2.cpp : Defines the entry point for the console application.
//  #include "stdafx.h"  #include <pantheios/pantheios.hpp>            // Pantheios C++ main header
#include <pantheios/inserters/processid.hpp>  // for pantheios::processId
#include <pantheios/inserters/threadid.hpp>   // for pantheios::threadId
#include <pantheios/inserters/integer.hpp>    //for pantheios::integer
#include <pantheios/inserters/real.hpp>       //for pantheios::real
#include <pantheios/inserters/blob.hpp>       // for pantheios::blob
#include <pantheios/inserters/hex_ptr.hpp>    // for pantheios::hex_ptr  #include <pantheios/backend.h>
#include <pantheios/backends/bec.WindowsConsole.h>  #define PSTR(x)         PANTHEIOS_LITERAL_STRING(x) 

PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PANTHEIOS_LITERAL_STRING(MY_PROGRAM_ID);

int _tmain(int argc, _TCHAR* argv[])
{
//输出当前进程ID
pantheios::log_NOTICE(PSTR(“process id: [“), pantheios::processId, PSTR(“]”));

//输出当前线程ID
pantheios::log_NOTICE(PSTR("thread id: ["), pantheios::threadId, PSTR("]"));  //演示:不同等级输出
//典型的输出格式为“MY_PROGRAM_ID.线程ID 时分秒毫秒 等级 日志信息”
//建议把MY_PROGRAM_ID替换为你的进程ID
pantheios::log_DEBUG(PSTR("debug"));
pantheios::log_INFORMATIONAL(PSTR("informational"));
pantheios::log_NOTICE(PSTR("notice"));
pantheios::log_WARNING(PSTR("warning"));
pantheios::log_ERROR(PSTR("error"));
pantheios::log_CRITICAL(PSTR("critical"));
pantheios::log_ALERT(PSTR("alert"));
pantheios::log_EMERGENCY(PSTR("emergency"));  //演示int、float格式化输出
int   i=123;
float f=4.567f;   pantheios::log_INFORMATIONAL("[[ i=", pantheios::integer(i),   " f=",pantheios::real(f),"]]");  pantheios::pantheios_logprintf(pantheios::SEV_INFORMATIONAL,PSTR("int=%d, float=%.2g"),i,f);  //演示二进制格式化输出
pantheios::uint8_t  bytes[20];
for(size_t i = 0; i < STLSOFT_NUM_ELEMENTS(bytes); ++i)
{  bytes[i] = static_cast<pantheios::uint8_t>(i);
}  //默认打印格式如右"bytes: [03020100070605040b0a09080f0e0d0c13121110]"
pantheios::log_NOTICE(PSTR("bytes: ["), pantheios::blob(bytes, sizeof(bytes)), PSTR("]"));  //四字节为一组当中以空格分隔,打印格式如右 "bytes: [03020100 07060504 0b0a0908 0f0e0d0c 13121110]"
pantheios::log_NOTICE(PSTR("bytes: ["), pantheios::blob(bytes, sizeof(bytes), 4, PSTR(" ")), PSTR("]"));  // 每字节以空格分隔,四个为一行,每行以换行符结尾和两个空格结尾
// 打印格式如下
// "bytes: [00 01 02 03
//   04 05 06 07
//   08 09 0a 0b
//   0c 0d 0e 0f
//   10 11 12 13]"
pantheios::log_NOTICE(PSTR("bytes: ["), pantheios::blob(bytes, sizeof(bytes), 1, PSTR(" "), 4, PSTR("\n  ")), PSTR("]"));  //演示打印十六进制指针
//打印格式如右"pv: [0x0012fed0]"
pantheios::log_NOTICE(PSTR("pv: ["), pantheios::hex_ptr(&i), PSTR("]"));  return EXIT_SUCCESS;

}

第三个例子,输出日志到多种流中
主要有两个源文件组成

implicit_link.cpp

[cpp] view plain copy


/* /
* Logging management
*/
enum beid_target
{
beid_Console = 1,
beid_File = 2
};

pan_be_N_t PAN_BE_N_BACKEND_LIST[] =
{
PANTHEIOS_BE_N_STDFORM_ENTRY(beid_Console, pantheios_be_WindowsConsole, 0),
PANTHEIOS_BE_N_STDFORM_ENTRY(beid_File, pantheios_be_file, 0),
PANTHEIOS_BE_N_TERMINATOR_ENTRY
};

int _tmain(int argc, _TCHAR* argv[])
{
try
{
//设置文件输出流
//如果遇到同名文件,原文件的内容会被重写
pantheios_be_file_setFilePath(PSTR(“kagula.log”),
PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BEID_ALL);

    //同时输出到两个目标(文件流和Windows控制台)中  //我重载了pantheios_fe_isSeverityLogged这样两个目标流的输出等级可以分别控制  pantheios::log_DEBUG(PSTR("stmt log_DEBUG"));   //没有输出  pantheios::log_NOTICE(PSTR("stmt log_NOTICE")); //只输出到控制台  pantheios::log_ERROR( PTSTR(L"stmt 3"));        //输出到控制台和文件流中,log_ERROR不加L会乱码奇怪  pantheios::log_EMERGENCY(PTSTR(L"stmt 4"));     //输出到控制台和文件流中,log_EMERGENCY不加L会乱码奇怪  return EXIT_SUCCESS;
}
catch(std::bad_alloc&)
{  pantheios::log(pantheios::alert, PSTR("out of memory"));
}
catch(std::exception& x)
{  pantheios::log_CRITICAL(PSTR("Exception: "), x);
}
catch(...)
{  pantheios::logputs(pantheios::emergency, PSTR("Unexpected unknown error"));
}  return EXIT_FAILURE;

}

本文章中的例子摘自http://blog.csdn.net/lee353086/article/details/7196522。

参考资料
[1]Pantheios下载地址

http://sourceforge.net/projects/pantheios/files/Pantheios%20(C%20and%20Cxx)/

[2]stlsoft下载地址

http://sourceforge.net/projects/stlsoft/files/latest/download

[3]Pantheios官网

http://pantheios.sourceforge.net/

[4]《Pantheios LibrarySelector Tool》下载

http://sourceforge.net/projects/pantheios/files/Pantheios%20Library%20Selector%20Tool/

[5] Pantheios Library Selector Tool使用

http://pantheios.sourceforge.net/tutorials_library_selector.html

C++第三方日志库Pantheios相关推荐

  1. C++第三方日志库Glog的安装与使用超详解

    目录 一.glog介绍 二.glog下载 三.环境介绍 三.glog的编译详解 3.1 利用CMake进行编译,生成VS解决方案 3.2 利用VS对项目进行编译 四.glog的基本使用 4.1 创建V ...

  2. go第三方日志库uber-go/zap、lumberjack

    uber-go/zap.lumberjack zap是uber开源的go语言高性能日志库, lumberjack是zap官方推荐的日志分割库, 结合这两个库我们可以在项目中实现完整的日志机制, 例如: ...

  3. go第三方日志库 Zap

    //官方文档 //https://pkg.go.dev/go.uber.org/zap#section-readmepackage mainimport ("encoding/json&qu ...

  4. C++plog库,轻量级日志框架(日志库)

    文章目录 为何建议程序员在项目中使用第三方日志库 第三方日志库plog的优势 plog主要头文件及使用方法解释 plog/Log.h plog/Appenders/ColorConsoleAppend ...

  5. C++ Windows下Glog日志库安装使用教程

    2018年是我写过一个关于Glog使用的教程(https://blog.csdn.net/qq_27278957/article/details/84648912),但是最近再使用时,发现和当时使用方 ...

  6. 【Android NDK 开发】NDK 交叉编译 ( Ubuntu 中交叉编译动态库 | Android Studio 中配置使用第三方动态库 )

    文章目录 I . 动态库 与 静态库 II . 编译动态库 III. Android Studio 使用第三方动态库 IV . Android Studio 关键代码 V . 博客资源 I . 动态库 ...

  7. 基于第三方开源库的OPC服务器开发指南(2)——LightOPC的编译及部署

    基于第三方开源库的OPC服务器开发指南(2)--LightOPC的编译及部署 前文已经说过,OPC基于微软的DCOM技术,所以开发OPC服务器我们要做的事情就是开发一个基于DCOM的EXE文件.一个代 ...

  8. 日志库EasyLogging++学习系列(3)—— 配置功能

    在前面的文章 <日志库Easylogging++学习系列(1) -- 简要介绍 >中,我们已经初步见识到了 Easylogging++ 日志库强大的配置功能.那么配置文件中各个字段的意义是 ...

  9. 日志库EasyLogging++学习系列(1)—— 简要介绍

    对于有开发经验的程序员来说,记录程序执行日志是一件必不可少的事情.通过查看和分析日志信息,不仅可以有效地帮助我们调试程序,而且当程序正式发布运行之后,更是可以帮助我们快速.准确地定位问题.在现在这个开 ...

最新文章

  1. 升级PHP到5.3.3的过程及注意事项
  2. 微信和QQ消息撤回可见app(仅限安卓手机系统的童鞋哟,本人亲测有效)
  3. 天翼云从业认证(4.10)网络直播场景解决方案(CDN)
  4. 前端ui 后台管理系统 简洁_Github上前端不可不知的可视化后台管理系统(1)
  5. W3wp.exe占用CPU及内存资源
  6. mysql 5.6 缓存_为什么默认情况下从MySQL 5.6开始禁用query_cache_type?
  7. jzoj5057-[GDSOI2017模拟4.13]炮塔【网络流,最大权闭合图】
  8. LeetCode 2000. 反转单词前缀
  9. ACL20 best paper荣誉提名 | DO NOT STOP Pre-training!
  10. arp 华为 查看 路由器_华为路由器运行状态查看-路由器
  11. 使用数组操作解码YOLO Core ML对象检测(三)
  12. 实践—一个3D旋转相册
  13. 大数据学习入门难,中科天玑给初学者支几招
  14. Windows10家庭版远程桌面登录——RDPWrap
  15. 某农业学校python(七)
  16. 鸿蒙系统上海,鸿蒙系统助阵 华为新一代智慧屏升级五大分布式场景
  17. 字符串Hash函数对比
  18. 接入植物识别功能快速识别万种植物花卉
  19. STM32 USB使用记录:使用CDC类虚拟串口(VCP)进行通讯
  20. [HTML]书签怎么做?

热门文章

  1. 区块链和大数据的关系
  2. 浅析语音识别技术的工作原理及发展
  3. Tableau自定义分类调色板
  4. 使用Vagrant部署虚拟分布式开发和测试环境
  5. dseo13b打开自动消失_刚安装的WIN764位系统
  6. php仿阿里巴巴,php实现的仿阿里巴巴实现同类产品翻页
  7. 双足竞走机器人的意义_双足竞走机器人设计1
  8. 数据分类分析--聚类
  9. 防火墙服务器搭建与应用(1.0)
  10. 流行的Go语言web框架简介