C++第三方日志库Pantheios

Kagula

2012-1-11

简介

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

Pantheios的架构分为前端和后端,具体概念介绍参考资料[3],这里只给出实际如何使用的源码示例。

我这里使用的环境:

[1]Windows XP SP3

[2]Visual Studio2008 + SP1

[3]pantheios-1.0.1-beta213

[4] stlsoft-1.9.111

[5]pantheios-libselw-1.9.6.52

正文

配置Pantheios使用环境

第一步:从参考资料[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向导中建立和测试通过的。

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

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

  1. // testFile.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. //指定链接库.begin
  5. #include <pantheios/implicit_link/core.h>
  6. #include <pantheios/implicit_link/fe.simple.h>
  7. #include <pantheios/implicit_link/be.file.h>
  8. //指定链接库.end
  9. #define PANTHEIOS_NO_INCLUDE_OS_AND_3PTYLIB_STRING_ACCESS // Faster compilation
  10. /* Pantheios Header Files */
  11. #include <pantheios/pantheios.hpp>            // Pantheios C++ main header
  12. #include <pantheios/backends/bec.file.h>      // be.file header
  13. /* Standard C/C++ Header Files */
  14. #include <exception>                          // for std::exception
  15. #include <new>                                // for std::bad_alloc
  16. #include <string>                             // for std::string
  17. #include <stdlib.h>                           // for exit codes
  18. PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PANTHEIOS_LITERAL_STRING("testFile");
  19. #define PSTR(x)         PANTHEIOS_LITERAL_STRING(x)
  20. int _tmain(int argc, _TCHAR* argv[])
  21. {
  22. try
  23. {
  24. //设置文件名
  25. pantheios_be_file_setFilePath(PSTR("kagula-%D-%T.log"),
  26. PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BEID_ALL);
  27. //打印到文件
  28. pantheios::log_NOTICE(PSTR("stmt 1"));
  29. pantheios::log_NOTICE(PSTR("stmt 2"));
  30. pantheios::log_NOTICE(PSTR("stmt 3"));
  31. pantheios::log_DEBUG(PSTR("exiting main()"));
  32. return EXIT_SUCCESS;
  33. }
  34. catch(std::bad_alloc&)
  35. {
  36. pantheios::log_ALERT(PSTR("out of memory"));
  37. }
  38. catch(std::exception& x)
  39. {
  40. pantheios::log_CRITICAL(PSTR("Exception: "), x);
  41. }
  42. catch(...)
  43. {
  44. //如果只是打印一条字符串形式的信息,建议用下面这种形式打印日志!
  45. pantheios::logputs(pantheios::emergency, PSTR("Unexpected unknown error"));
  46. }
  47. return EXIT_FAILURE;
  48. }

第二个例子,输出日志到Windows控制台

有三个源文件组成,stdafx.h文件插入了“MY_PROCESS_ID”宏,定义当前进程名称。

implicit_link.cpp文件,用来指定链接库和日志输出等级,第三个文件T2.cpp是示例代码,列举了不同水平的信息输出,和如何格式化输出信息。

stdafx.h源码

  1. // stdafx.h : include file for standard system include files,
  2. // or project specific include files that are used frequently, but
  3. // are changed infrequently
  4. //
  5. #pragma once
  6. #include "targetver.h"
  7. #include <stdio.h>
  8. #include <tchar.h>
  9. // TODO: reference additional headers your program requires here
  10. #define MY_PROGRAM_ID "MyProgramID"

implicit_link.cpp源码

  1. #include "stdafx.h"
  2. #include <pantheios/implicit_link/core.h>
  3. //如果定义了USER_SPECIFIED_LEVEL宏定义,则使用用户自定义的输出等级
  4. //如果不定义“USER_SPECIFIED_LEVEL”宏,表示所有等级的信息都输出
  5. #define USER_SPECIFIED_LEVEL
  6. #ifndef USER_SPECIFIED_LEVEL
  7. #include <pantheios/implicit_link/fe.simple.h>
  8. #endif
  9. //一旦加入下面这条include语句,程序的log输出就会转到Windows控制台
  10. //在本例中,这条语句是必须的。
  11. #include <pantheios/implicit_link/be.WindowsConsole.h>
  12. #ifdef USER_SPECIFIED_LEVEL
  13. PANTHEIOS_CALL(int) pantheios_fe_init(void*   reserved,void**  ptoken)
  14. {
  15. *ptoken = NULL;
  16. return 0;
  17. }
  18. PANTHEIOS_CALL(void) pantheios_fe_uninit(void* token)
  19. {}
  20. PANTHEIOS_CALL(PAN_CHAR_T const*)  pantheios_fe_getProcessIdentity  (void *  token)
  21. {
  22. return PANTHEIOS_LITERAL_STRING(MY_PROGRAM_ID);
  23. }
  24. PANTHEIOS_CALL(int) pantheios_fe_isSeverityLogged(void* token
  25. , int   severity
  26. , int   backEndId)
  27. {
  28. //数值越小说明要输出的信息越重要,常用的越先级大小如下
  29. //SEV_CRITICAL=2 < SEV_ERROR=3 < SEV_WARNING=4 < SEV_INFORMATIONAL=6
  30. if(severity <= pantheios::SEV_INFORMATIONAL)
  31. return 1;//允许输出
  32. return 0;
  33. }
  34. #endif

T2.cpp源码

  1. // T2.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #include <pantheios/pantheios.hpp>            // Pantheios C++ main header
  5. #include <pantheios/inserters/processid.hpp>  // for pantheios::processId
  6. #include <pantheios/inserters/threadid.hpp>   // for pantheios::threadId
  7. #include <pantheios/inserters/integer.hpp>    //for pantheios::integer
  8. #include <pantheios/inserters/real.hpp>       //for pantheios::real
  9. #include <pantheios/inserters/blob.hpp>       // for pantheios::blob
  10. #include <pantheios/inserters/hex_ptr.hpp>    // for pantheios::hex_ptr
  11. #include <pantheios/backend.h>
  12. #include <pantheios/backends/bec.WindowsConsole.h>
  13. #define PSTR(x)         PANTHEIOS_LITERAL_STRING(x)
  14. PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PANTHEIOS_LITERAL_STRING(MY_PROGRAM_ID);
  15. int _tmain(int argc, _TCHAR* argv[])
  16. {
  17. //输出当前进程ID
  18. pantheios::log_NOTICE(PSTR("process id: ["), pantheios::processId, PSTR("]"));
  19. //输出当前线程ID
  20. pantheios::log_NOTICE(PSTR("thread id: ["), pantheios::threadId, PSTR("]"));
  21. //演示:不同等级输出
  22. //典型的输出格式为“MY_PROGRAM_ID.线程ID 时分秒毫秒 等级 日志信息”
  23. //建议把MY_PROGRAM_ID替换为你的进程ID
  24. pantheios::log_DEBUG(PSTR("debug"));
  25. pantheios::log_INFORMATIONAL(PSTR("informational"));
  26. pantheios::log_NOTICE(PSTR("notice"));
  27. pantheios::log_WARNING(PSTR("warning"));
  28. pantheios::log_ERROR(PSTR("error"));
  29. pantheios::log_CRITICAL(PSTR("critical"));
  30. pantheios::log_ALERT(PSTR("alert"));
  31. pantheios::log_EMERGENCY(PSTR("emergency"));
  32. //演示int、float格式化输出
  33. int   i=123;
  34. float f=4.567f;
  35. pantheios::log_INFORMATIONAL("[[ i=", pantheios::integer(i),
  36. " f=",pantheios::real(f),"]]");
  37. pantheios::pantheios_logprintf(pantheios::SEV_INFORMATIONAL,PSTR("int=%d, float=%.2g"),i,f);
  38. //演示二进制格式化输出
  39. pantheios::uint8_t  bytes[20];
  40. for(size_t i = 0; i < STLSOFT_NUM_ELEMENTS(bytes); ++i)
  41. {
  42. bytes[i] = static_cast<pantheios::uint8_t>(i);
  43. }
  44. //默认打印格式如右"bytes: [03020100070605040b0a09080f0e0d0c13121110]"
  45. pantheios::log_NOTICE(PSTR("bytes: ["), pantheios::blob(bytes, sizeof(bytes)), PSTR("]"));
  46. //四字节为一组当中以空格分隔,打印格式如右 "bytes: [03020100 07060504 0b0a0908 0f0e0d0c 13121110]"
  47. pantheios::log_NOTICE(PSTR("bytes: ["), pantheios::blob(bytes, sizeof(bytes), 4, PSTR(" ")), PSTR("]"));
  48. // 每字节以空格分隔,四个为一行,每行以换行符结尾和两个空格结尾
  49. // 打印格式如下
  50. // "bytes: [00 01 02 03
  51. //   04 05 06 07
  52. //   08 09 0a 0b
  53. //   0c 0d 0e 0f
  54. //   10 11 12 13]"
  55. pantheios::log_NOTICE(PSTR("bytes: ["), pantheios::blob(bytes, sizeof(bytes), 1, PSTR(" "), 4, PSTR("\n  ")), PSTR("]"));
  56. //演示打印十六进制指针
  57. //打印格式如右"pv: [0x0012fed0]"
  58. pantheios::log_NOTICE(PSTR("pv: ["), pantheios::hex_ptr(&i), PSTR("]"));
  59. return EXIT_SUCCESS;
  60. }

第三个例子,输出日志到多种流中

主要有两个源文件组成

implicit_link.cpp

  1. #include "stdafx.h"
  2. #include <pantheios/implicit_link/core.h>
  3. #include <pantheios/implicit_link/be.N.h>
  4. #include <pantheios/implicit_link/be.WindowsConsole.h>
  5. #include <pantheios/implicit_link/be.file.h>
  6. PANTHEIOS_CALL(int) pantheios_fe_init(void*   reserved,void**  ptoken)
  7. {
  8. *ptoken = NULL;
  9. return 0;
  10. }
  11. PANTHEIOS_CALL(void) pantheios_fe_uninit(void* token)
  12. {}
  13. PANTHEIOS_CALL(PAN_CHAR_T const*)  pantheios_fe_getProcessIdentity  (void *  token)
  14. {
  15. return PANTHEIOS_LITERAL_STRING("example");
  16. }
  17. PANTHEIOS_CALL(int) pantheios_fe_isSeverityLogged(void* token
  18. , int   severity
  19. , int   backEndId)
  20. {
  21. //数值越小说明要输出的信息越重要,常用的越先级大小如下
  22. //SEV_CRITICAL=2 < SEV_ERROR=3 < SEV_WARNING=4 < SEV_INFORMATIONAL=6 < SEV_DEBUG=7
  23. //backEndId=0的时候必须返回1,这样才会进一步调用这个函数,这时会传入详细的backEndId值(1或2)。
  24. if( backEndId==0 )
  25. return 1;
  26. //Windows控制台中只记录SEV_INFORMATIONAL以上级别的信息
  27. if(severity <= pantheios::SEV_INFORMATIONAL && backEndId==1)
  28. return 1;//允许输出
  29. //文件流中只记录严重错误的信息
  30. if(severity <= pantheios::SEV_ERROR && backEndId==2)
  31. return 1;//允许输出
  32. return 0;
  33. }

testPantheios.cpp

  1. // testPantheios.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #include <pantheios/util/test/compiler_warnings_suppression.first_include.h>
  5. #define PANTHEIOS_NO_INCLUDE_OS_AND_3PTYLIB_STRING_ACCESS // Faster compilation
  6. /* Pantheios Header Files */
  7. #include <pantheios/pantheios.hpp>                  // Pantheios C++ main header
  8. #include <pantheios/backends/be.N.h>                // pan_be_N_t声明
  9. #include <pantheios/backends/bec.WindowsConsole.h>  // Include the API for bec.WindowsConsole
  10. #include <pantheios/backends/bec.file.h>            // be.file header
  11. /* Standard C/C++ Header Files */
  12. #include <exception>                                // for std::exception
  13. #include <new>                                      // for std::bad_alloc
  14. #include <string>                                   // for std::string
  15. #include <stdlib.h>                                 // for exit codes
  16. /* Windows Header Files */
  17. # include <windows.h>                               // for console colour constants
  18. #include <pantheios/util/test/compiler_warnings_suppression.last_include.h>
  19. PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PANTHEIOS_LITERAL_STRING("example");
  20. #define PSTR(x)         PANTHEIOS_LITERAL_STRING(x)
  21. /* /////////////////////////////////////////////////////////////////////////
  22. * Logging management
  23. */
  24. enum beid_target
  25. {
  26. beid_Console =   1,
  27. beid_File =   2
  28. };
  29. pan_be_N_t  PAN_BE_N_BACKEND_LIST[] =
  30. {
  31. PANTHEIOS_BE_N_STDFORM_ENTRY(beid_Console, pantheios_be_WindowsConsole, 0),
  32. PANTHEIOS_BE_N_STDFORM_ENTRY(beid_File, pantheios_be_file, 0),
  33. PANTHEIOS_BE_N_TERMINATOR_ENTRY
  34. };
  35. int _tmain(int argc, _TCHAR* argv[])
  36. {
  37. try
  38. {
  39. //设置文件输出流
  40. //如果遇到同名文件,原文件的内容会被重写
  41. pantheios_be_file_setFilePath(PSTR("kagula.log"),
  42. PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BEID_ALL);
  43. //同时输出到两个目标(文件流和Windows控制台)中
  44. //我重载了pantheios_fe_isSeverityLogged这样两个目标流的输出等级可以分别控制
  45. pantheios::log_DEBUG(PSTR("stmt log_DEBUG"));   //没有输出
  46. pantheios::log_NOTICE(PSTR("stmt log_NOTICE")); //只输出到控制台
  47. pantheios::log_ERROR( PTSTR(L"stmt 3"));        //输出到控制台和文件流中,log_ERROR不加L会乱码奇怪
  48. pantheios::log_EMERGENCY(PTSTR(L"stmt 4"));     //输出到控制台和文件流中,log_EMERGENCY不加L会乱码奇怪
  49. return EXIT_SUCCESS;
  50. }
  51. catch(std::bad_alloc&)
  52. {
  53. pantheios::log(pantheios::alert, PSTR("out of memory"));
  54. }
  55. catch(std::exception& x)
  56. {
  57. pantheios::log_CRITICAL(PSTR("Exception: "), x);
  58. }
  59. catch(...)
  60. {
  61. pantheios::logputs(pantheios::emergency, PSTR("Unexpected unknown error"));
  62. }
  63. return EXIT_FAILURE;
  64. }

参考资料

[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

http://blog.csdn.net/lee353086/article/details/7196522

C++第三方日志库Pantheios的更多相关文章

  1. Go之第三方日志库logrus使用

    文章引用自 第三方日志库logrus使用 日志是程序中必不可少的一个环节,由于Go语言内置的日志库功能比较简洁,我们在实际开发中通常会选择使用第三方的日志库来进行开发.本文介绍了logrus这个日志库 ...

  2. Go第三方日志库logrus

    日志是程序中必不可少的一个环节,由于Go语言内置的日志库功能比较简洁,我们在实际开发中通常会选择使用第三方的日志库来进行开发.本文介绍了logrus这个日志库的基本使用. logrus介绍 Logru ...

  3. 第三方日志库logrus使用

    日志是程序中必不可少的一个环节,由于Go语言内置的日志库功能比较简洁,我们在实际开发中通常会选择使用第三方的日志库来进行开发.本文介绍了logrus这个日志库的基本使用. logrus介绍 Logru ...

  4. 使用.NET 6开发TodoList应用(3)——引入第三方日志库

    需求 在我们项目开发的过程中,使用.NET 6自带的日志系统有时是不能满足实际需求的,比如有的时候我们需要将日志输出到第三方平台上,最典型的应用就是在各种云平台上,为了集中管理日志和查询日志,通常会选 ...

  5. Carthage 让项目支持及使用,第三方静态库转为动态库

    Carthage介绍 具体使用,可以查看官网的,文档地址 https://github.com/Carthage/Carthage.如果看不懂英文,可以看一下官文的翻译:https://www.jia ...

  6. C/C++log日志库比较

    事实上,在C的世界里面没有特别好的日志函数库(就像Java里面的的log4j,或者C++的log4cxx).C程序员都喜欢用自己的轮子.printf就是个挺好的轮子,但没办法通过配置改变日志的格式或者 ...

  7. C基础 多用户分级日志库 sclog

    引言 - sclog 总的设计思路 sclog在之前已经内置到simplec 简易c开发框架中一个日志库. 最近对其重新设计了一下. 减少了对外暴露的接口. 也是C开发中一个轮子. 比较简单, 非常适 ...

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

    前文已经说过,OPC基于微软的DCOM技术,所以开发OPC服务器我们要做的事情就是开发一个基于DCOM的EXE文件.一个代理/存根文件,然后就是写一个OPC客户端测试一下我们的服务器了.对于第一项工作 ...

  9. Go语言项目中使用zap日志库(翻译)

    本文先介绍了Go语言原生的日志库的使用,然后详细介绍了非常流行的Uber开源的zap日志库,同时介绍了如何搭配Lumberjack实现日志的切割和归档. 在Go语言项目中使用Uber-go的Zap L ...

随机推荐

  1. 键盘钩子监测按键后,获取键码及按键名称(MFC)

    LRESULT CALLBACK LowLevelKeyboardProc(int nCode,WPARAM wParam,LPARAM lParam){ if(nCode ==HC_ACTION & ...

  2. [Angular] Bind async requests in your Angular template with the async pipe and the "as" keyword

    Angular allows us to conveniently use the async pipe to automatically register to RxJS observables a ...

  3. jQuery 中 is() 函数常见使用方法

    依据选择器.DOM元素或 jQuery 对象来检測匹配元素集合.假设当中至少有一个元素符合这个给定的表达式就返回true. 假设没有元素符合,或者表达式无效.都返回'false'. '''注意:''' ...

  4. Nutch关于robot.txt的处理 分类: H3_NUTCH 2015-01-28 11:20 472人阅读 评论(0) 收藏

    在nutch中,默认情况下尊重robot.txt的配置,同时不提供配置项以忽略robot.txt. 以下是其中一个解释.即作为apache的一个开源项目,必须遵循某些规定,同时由于开放了源代码,可以简 ...

  5. 线程堆栈大小 pthread_attr_setstacksize 的使用

    pthread_create 创建线程时,若不指定分配堆栈大小,系统会分配默认值,查看默认值方法如下: # ulimit -s8192# 上述表示为8M:单位为KB. 也可以通过# ulimit -a ...

  6. Vue源码--深入模板渲染

    原文链接:https://geniuspeng.github.io/2018/02/07/vue-compile/ 之前整理了vue的响应式原理,在这里有一点是一直很模糊的,就是何时去new一个wat ...

  7. JAVA中try-catch异常逃逸

    有时候一些小的细节,确实比较纠结,对于try-catch-finally代码块中代码依次执行,当try中有exception抛出时,将会有catch拦截并执行,如果没有catch区块,那么except ...

  8. 计算git树上随意两点的近期切割点。

    1.git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比方: base'<--base<--A<--A' ^ | --- B<--B' 小米project师 ...

  9. Docker入门之 - 更换源为国内源,实现快速下载image

    原文:Docker入门之 - 更换源为国内源,实现快速下载image 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012055638/artic ...

  10. 【t019】window(线段树做法)

    Time Limit: 2 second Memory Limit: 256 MB [问题描述] 给你一个长度为N 的数组,一个长为K的滑动的窗体从最左移至最右端,你只能见到窗口的K个数,每次窗体向右 ...