博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
日志库EasyLogging++学习系列(11)—— 共享日志库
阅读量:3974 次
发布时间:2019-05-24

本文共 2924 字,大约阅读时间需要 9 分钟。

在前面的学习系列文章中,我们都是在单独的一个应用程序中使用 Easylogging++ 日志库。其实 Easylogging++ 日志库是可以共享给动态库、静态库以及应用程序共同使用的。在编写一些大型程序的时候,我们往往会把各个功能分别封装成一个动态库,然后再编写一个主程序来负责调用这些动态库就可以了。现在假设我们想在主程序和各个动态库中都使用 Easylogging++ 来记录日志,那么我们需要在主程序和各个动态库中的代码中都包含 Easylogging++ 的头文件,然后再分别设置主程序和各个动态库的日志配置。这是一个非常繁琐的事情,而且很容易把主程序和各个动态库中的日志配置成保存在同一个文件里,这可能会造成多个动态库同时对同一个日志文件进行写操作的情形,从而可能会使得日志内容乱成一团。但是因为主程序和各个动态库合并起来才算是一个完整的程序,我们又确实想把主程序和各个动态库中相同级别的的日志都保存在同一个文件中,那么我们只需要使用 Easylogging++ 的共享功能,就可以完美地满足我们的需求,并且还能避免上述所说的问题。

在 Easylogging++ 日志库的源码中,有一个名为 Storage 的类,这个类是负责维护 Easylogging++ 日志库数据的主要入口,比如日志记录器的管理,日志配置的管理等都是在 Storage 类中完成的。默认情况下,我们每调用一次初始化宏 INITIALIZE_EASYLOGGINGPP 就会创建一个 Storage 类对象,所以不同的程序就会有不同的 Storage 类对象在负责维护相应的日志记录器和日志配置。如果我们只创建一次 Storage 类对象,然后再将这个对象共享给其他使用 Easylogging++ 日志库的程序使用,那么就可以保证所有程序都在使用同一个 Storage 类对象维护的日志记录器和日志配置,如同在单独的应用程序中使用日志记录一样方便和安全。

为了使用共享的 Storage 类对象,在其他程序中我们不能用宏 INITIALIZE_EASYLOGGINGPP 来初始化日志库,应该改用以下两个宏定义中任意一个:

  •  INITIALIZE_NULL_EASYLOGGINGPP
  • SHARE_EASYLOGGINGPP
如果使用宏 INITIALIZE_NULL_EASYLOGGINGPP ,那么必须用函数 el::Helpers::setStorage(el::base::type::StoragePointer) 来设置共享的 Storage 类对象,否则将会运行出错;如果使用宏 SHARE_EASYLOGGINGPP ,那么必须将共享的 Storage 类对象作为参数传递进去。在 Easylogging++ V9.80 的版本中,如果使用宏 SHARE_EASYLOGGINGPP 编译会出现错误,提示无法解析的外部符号,下面是定义该宏的源码:
[plain]
  1. #define SHARE_EASYLOGGINGPP(initializedStorage)\  
  2.     namespace el {\  
  3.         namespace base {\  
  4.             el::base::type::StoragePointer elStorage(initializedStorage);\  
  5.         }\  
  6.         el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\  
  7.     }  
#define SHARE_EASYLOGGINGPP(initializedStorage)\    namespace el {\        namespace base {\            el::base::type::StoragePointer elStorage(initializedStorage);\        }\        el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\    }
解决编译出错的方法很简单,增加一个宏 ELPP_INITI_BASIC_DECLR 即可,下面是修改之后的代码:
[plain]
  1. #define SHARE_EASYLOGGINGPP(initializedStorage)\  
  2.     ELPP_INITI_BASIC_DECLR\  
  3.     namespace el {\  
  4.         namespace base {\  
  5.             el::base::type::StoragePointer elStorage(initializedStorage);\  
  6.         }\  
  7.         el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\  
  8.     }  
#define SHARE_EASYLOGGINGPP(initializedStorage)\	ELPP_INITI_BASIC_DECLR\    namespace el {\        namespace base {\            el::base::type::StoragePointer elStorage(initializedStorage);\        }\        el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\    }
其实,修改之后的代码就和另外一个宏
 
ELPP_INIT_EASYLOGGINGPP 的代码一模一样。有兴趣的小伙伴可以查看一下源码分别了解一下以下几个和初始化有关的宏定义:
  • INITIALIZE_EASYLOGGINGPP
  • ELPP_INIT_EASYLOGGINGPP
  • INITIALIZE_NULL_EASYLOGGINGPP
  • SHARE_EASYLOGGINGPP
最后通过一个完整的演示工程来说明如何只创建一个 Storage 类对象,然后再将该对象共享给其他工程使用。在演示工程有下面四个项目:

  • ShareEasylogging++项目,一个动态库工程,完成 Storage 类对象的创建,并提供获取该对象的接口,以便其他工程共享该对象。
  • ShareEasyloggingDll1项目,一个动态库工程,演示了如何使用宏 SHARE_EASYLOGGINGPP 和共享的 Storage 类对象完成初始化。
  • ShareEasyloggingDll2项目,一个动态库工程,演示了如何使用宏 SHARE_EASYLOGGINGPP 和共享的 Storage 类对象完成初始化。
  • ShareEasyloggingTest项目,演示工程主程序,演示了如何使用宏 INITIALIZE_NULL_EASYLOGGINGPP 和共享的 Storage 类对象完成初始化。
完整的演示工程代码下载:
你可能感兴趣的文章
一个不错的arm入门建议
查看>>
一篇dbus移植的点点滴滴
查看>>
linux系统中如何查看日志 (常用命令)
查看>>
推荐8个在线调试代码的网站---优秀开发工具
查看>>
测试网站速度的8款免费工具推荐
查看>>
推荐25个提高网站可用性和转化率的工具
查看>>
12款很棒的浏览器兼容性测试工具推荐
查看>>
LIBXML2库使用指南
查看>>
xml本质讨论
查看>>
libxml2如何解析xml格式的字符串
查看>>
XML文件的解析--非常详细的libxml库函数解释说明并附带实例
查看>>
Linux服务器监控方案参考
查看>>
在Linux是使用libxml2---从安装到使用
查看>>
使用libxml2实现简单合并两个不同的xml文件
查看>>
在xml里增加节点时添加回车(libxml2)
查看>>
xml文件解析--libxml2库函数解释
查看>>
30本关于asp.net相关的经典书籍推荐
查看>>
Windows下解决TerminateThread终止线程导致死锁问题
查看>>
linux下线程编程的注意到和推荐做法
查看>>
几个图论和复杂网络的程序库 —— BGL,QuickGraph,igraph和NetworkX
查看>>