C++第三方日志库Pantheios
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向导中建立和测试通过的。
第一个例子,输出日志到文件中
只有一个源文件源码如下,编译顺利的话可以直接运行:
- // 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源码
- // 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源码
- #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源码
- // 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
- #include "stdafx.h"
- #include <pantheios/implicit_link/core.h>
- #include <pantheios/implicit_link/be.N.h>
- #include <pantheios/implicit_link/be.WindowsConsole.h>
- #include <pantheios/implicit_link/be.file.h>
- 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("example");
- }
- PANTHEIOS_CALL(int) pantheios_fe_isSeverityLogged(void* token
- , int severity
- , int backEndId)
- {
- //数值越小说明要输出的信息越重要,常用的越先级大小如下
- //SEV_CRITICAL=2 < SEV_ERROR=3 < SEV_WARNING=4 < SEV_INFORMATIONAL=6 < SEV_DEBUG=7
- //backEndId=0的时候必须返回1,这样才会进一步调用这个函数,这时会传入详细的backEndId值(1或2)。
- if( backEndId==0 )
- return 1;
- //Windows控制台中只记录SEV_INFORMATIONAL以上级别的信息
- if(severity <= pantheios::SEV_INFORMATIONAL && backEndId==1)
- return 1;//允许输出
- //文件流中只记录严重错误的信息
- if(severity <= pantheios::SEV_ERROR && backEndId==2)
- return 1;//允许输出
- return 0;
- }
testPantheios.cpp
- // testPantheios.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <pantheios/util/test/compiler_warnings_suppression.first_include.h>
- #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/be.N.h> // pan_be_N_t声明
- #include <pantheios/backends/bec.WindowsConsole.h> // Include the API for bec.WindowsConsole
- #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
- /* Windows Header Files */
- # include <windows.h> // for console colour constants
- #include <pantheios/util/test/compiler_warnings_suppression.last_include.h>
- PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PANTHEIOS_LITERAL_STRING("example");
- #define PSTR(x) PANTHEIOS_LITERAL_STRING(x)
- /* /////////////////////////////////////////////////////////////////////////
- * 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;
- }
参考资料
[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的更多相关文章
- Go之第三方日志库logrus使用
文章引用自 第三方日志库logrus使用 日志是程序中必不可少的一个环节,由于Go语言内置的日志库功能比较简洁,我们在实际开发中通常会选择使用第三方的日志库来进行开发.本文介绍了logrus这个日志库 ...
- Go第三方日志库logrus
日志是程序中必不可少的一个环节,由于Go语言内置的日志库功能比较简洁,我们在实际开发中通常会选择使用第三方的日志库来进行开发.本文介绍了logrus这个日志库的基本使用. logrus介绍 Logru ...
- 第三方日志库logrus使用
日志是程序中必不可少的一个环节,由于Go语言内置的日志库功能比较简洁,我们在实际开发中通常会选择使用第三方的日志库来进行开发.本文介绍了logrus这个日志库的基本使用. logrus介绍 Logru ...
- 使用.NET 6开发TodoList应用(3)——引入第三方日志库
需求 在我们项目开发的过程中,使用.NET 6自带的日志系统有时是不能满足实际需求的,比如有的时候我们需要将日志输出到第三方平台上,最典型的应用就是在各种云平台上,为了集中管理日志和查询日志,通常会选 ...
- Carthage 让项目支持及使用,第三方静态库转为动态库
Carthage介绍 具体使用,可以查看官网的,文档地址 https://github.com/Carthage/Carthage.如果看不懂英文,可以看一下官文的翻译:https://www.jia ...
- C/C++log日志库比较
事实上,在C的世界里面没有特别好的日志函数库(就像Java里面的的log4j,或者C++的log4cxx).C程序员都喜欢用自己的轮子.printf就是个挺好的轮子,但没办法通过配置改变日志的格式或者 ...
- C基础 多用户分级日志库 sclog
引言 - sclog 总的设计思路 sclog在之前已经内置到simplec 简易c开发框架中一个日志库. 最近对其重新设计了一下. 减少了对外暴露的接口. 也是C开发中一个轮子. 比较简单, 非常适 ...
- 基于第三方开源库的OPC服务器开发指南(2)——LightOPC的编译及部署
前文已经说过,OPC基于微软的DCOM技术,所以开发OPC服务器我们要做的事情就是开发一个基于DCOM的EXE文件.一个代理/存根文件,然后就是写一个OPC客户端测试一下我们的服务器了.对于第一项工作 ...
- Go语言项目中使用zap日志库(翻译)
本文先介绍了Go语言原生的日志库的使用,然后详细介绍了非常流行的Uber开源的zap日志库,同时介绍了如何搭配Lumberjack实现日志的切割和归档. 在Go语言项目中使用Uber-go的Zap L ...
随机推荐
- Java 网络I/O模型
网络I/O模型 人多了,就会有问题.web刚出现的时候,光顾的人很少.近年来网络应用规模逐渐扩大,应用的架构也需要随之改变.C10k的问题,让工程师们需要思考服务的性能与应用的并发能力. 网络应用需要 ...
- perl对比两个文件的行
perl对比两个文件的行 对比两个文件的各行,得到A与B相同的行/A与B不相同的行 主要功能 得到相同行 得到A中包含,B不包含的行 得到B中包含,A中不包含的行 具体执行情况 Perl代码 #!/u ...
- Web全栈工程师修养
全栈工程师现在是个很热的话题,如何定义全栈工程师?在著名的问答网站Quora上有人提出了这个问题,其中一个获得了高票的回答是: 全栈工程师是指,一个能处理数据库.服务器.系统工程和客户端的所有工作的工 ...
- 在SSMS查询分析器中显示行号
有网友问及,看到Insus.NET帮他解决问题分享的截屏时,发现代码中有显示行号.而他的没有. Step1: Go to Tools > Options Step2: In the Option ...
- [Jenkins] Define a pipeline
node{ stage 'checkout' git '[github_url]' def project_path="[project_path]" // everythin i ...
- Java环境搭建若干问题
0.总体说明 本次搭建环境,为了偷懒,使用的是,阿里云镜像. 自带了Nginx.Tomcat.JDK等. 比较坑爹的是,虽然镜像带了很多安装好的软件,但是也有各种问题,比如它修改了tomc ...
- AE中网络分析的实现 的各个类之间的关系
原文AE中网络分析的实现 的各个类之间的关系 1. 创建网络数据集 在ArcCatalog中勾选网络分析模块,新建个人地理信息数据库—>新建要素数据集—>批量导入要素—>创建 ...
- redis持久化,主从及数据备份
http://blog.csdn.net/lang_man_xing/article/details/38386113 现在在项目里已经大量使用redis了,为了提高redis的性能和可靠性我们需要知 ...
- NOIP模拟 Work - 二分 + 树状数组 / ???
题目分析 如果没有最后的注意事项,此题就是二分裸题.有了注意事项,会有两种思路: 在线:二分天数t,并在主席树上求1~t天中大于d(浪费的时间)的时间之和以及数量,答案即为:sum - d * cnt ...
- 机房重构所遇问题"未能载入文件或程序集“DAL”或它的某一个依赖项。系统找不到指定的文件"的解决的方法集锦
敲七层登录的时候.忽然间认为敲三层搞清的思路瞬间又凌乱了.花了一天的时间边敲边梳理,最终整完了,执行的时候弹出了这种错误:未能载入文件或程序集"DAL"或它的某一个依赖项. 系统找 ...