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. 21、IIS声卡驱动程序

    声卡芯片的数据通道一般都是IIS接口,但是控制音量等控制信息的接口都不相同 (新内核在linux-3.4.2\sound\soc\codecs\uda134x.c) uda134x_codec_pro ...

  2. [TypeStyle] Generate static css + html files using TypeStyle

    You can easily use TypeStyle to build static html files with encapsulated CSS. You can use this patt ...

  3. ZOJ 3204 Connect them 继续MST

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3367 题目大意: 让你求最小生成树,并且按照字典序输出哪些点连接.无解输出-1 ...

  4. Vue.js如何划分组件

    常见的一些页面,大家坐在一起敲代码就可以了,做完这个页面再做别的页面,但是作为一个功能复杂的系统,尤其是使用一些适合模块化开发的框架,这样会显得效率很低,那么我们就单纯的看在Vue里面如何划分组件的. ...

  5. js进阶 11-19 jquery如何查找选择器的第一个父亲元素和第一个定位的父元素

    js进阶 11-19 jquery如何查找选择器的第一个父亲元素和第一个定位的父元素 一.总结 一句话总结:closest()方法获得匹配选择器的第一个祖先元素,从当前元素开始沿 DOM 树向上.of ...

  6. 【codeforces 742C】Arpa's loud Owf and Mehrdad's evil plan

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  7. NSString与int和float的相互转换

    NSString *tempA = @"123"; NSString *tempB = @"456"; 1,字符串拼接 NSString *newString ...

  8. oracle中imp导入数据中文乱码问题(转)

    (转自  http://blog.chinaunix.net/uid-186064-id-2823338.html) oracle中imp导入数据中文乱码问题 用imp命令向oracle中导入数据后, ...

  9. 【matlab】GPU 显卡版本与计算能力(compute capability)兼容性问题

    MathWorks - Bug Reports 1. 问题说明 当运行 alexnet 等卷积神经网络需要使用 GPU 加速时,matlab 如果提示如下的警告信息: GPUs of compute ...

  10. Java循环输出一个菱形与阶乘倒数

    package javafirst; public class HomeWork { public static void main(String[] args){ System.out.printl ...