http://blog.csdn.net/hmalloc/article/details/8443291

1 日志简介

程序都不可避免地会出现错误输出或崩溃的情况,这种情况往往在开发阶段很难发现,需要在特定的环境下才会出现,一旦出现这种情况,我们需要快速地定位到问题。很显然,当程序出现这种问题时,如果程序自己能够将当时出现该问题的原因记录下来,则能给我们带来莫大的效率,正是因为有了这种需求,所以就有了日志系统。所谓日志,就是程序运行时自动记录每日运行状态的一种行为,这跟我们传统说的打debug的方法有点区别,我们在刚开始学习C/C++语言的时候,接触到的只是类似于printf/cout的一些标准输入输出的东西,我们通常利用这些函数来辅助调试程序,当时也完全没有日志的概念。实际上到了真正做项目你会发现,这种传统的打debug的方式有明显的不足,不但输出的信息不美观,也不能做到实时记录,更不方便根据需求随意控制输出,这一切在日志系统中得到解决。

2 log4cplus简介

log4cplus移植于Java中的日志系统log4j,使用上也和log4j大同小异,这是一个很优秀的日志系统。log4j由三个组件构成——布局组件(Layouts)、追加组件(Appends)及真正实现日志功能的日志组件(Loggers)。布局组件用来控制日志输出的格式。追加组件定义日志输出的设备,如控制台、文件、socket、共享内存等,都可以成为追加组件,我们通常使用控制台和文件作为日志输出设备,在调试时我们将日志定位到控制台,而实际发布运行时将其定位到文件。日志组件提供对日志级别的控制,级别从高到低依次为FATAL_LOG_LEVEL、 ERROR_LOG_LEVEL、 WARN_LOG_LEVEL、 INFO_LOG_LEVEL 、DEBUG_LOG_LEVEL、 TRACE_LOG_LEVEL、 NOT_SET_LOG_LEVEL。

3 log4cplus的安装

log4cplus是开源的,源代码可在这里找到。下载源代码压缩包后解压,进入主目录。和大多数autotools工程一样,顺序执行以下命令即可完成安装。

./configure
make
make install  

安装文件将默认安装到/usr/local,库文件置于/usr/local/lib,头文件置于/usr/local/include。

是的,这里介绍的安装及下面介绍的应用都是基于linux系统。

4 log4cplus的使用

以下是官方提供的“hello, world”的示例程序:

#include <log4cplus/logger.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
#include <iomanip>
using namespace log4cplus;  int main()
{  BasicConfigurator config;  config.configure();  Logger logger = Logger::getInstance(LOG4CPLUS_TEXT("main"));  LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("Hello, World!"));  return 0;
}

程序包含了一些必要的头文件,编译时需要链接log4cplus库,将这段代码保存为 test.cpp,执行以下命令编译:

g++ test.cpp -o test -llog4cplus  

编译后生成 test 可执行文件,运行./test,得到如下输出:

WARN - Hello, World!  

这个程序使用的是log4cplus内置的默认配置选项,实际使用中一般要自己配置选项,接下来你会看到。

5 log4cplus配置

log4cplus配置就是定义appender, 定义输出的格式即 layout。以下列出两种常用配置,以供参考。

配置输出到控制台(通常用于前台程序):

log4cplus.logger.logmain = TRACE, console
log4cplus.appender.console = log4cplus::ConsoleAppender
log4cplus.appender.console.layout = log4cplus::PatternLayout
log4cplus.appender.console.layout.ConversionPattern = [%D{%m/%d/%y %H:%M:%S,%q} %-5p] - %m%n  

配置输出到文件(通常用于后台程序):

log4cplus.logger.logmain = INFO, file
log4cplus.appender.file = log4cplus::FileAppender
log4cplus.appender.file.File = /var/log/myapp.log
log4cplus.appender.file.MaxFileSize = 10M
log4cplus.appender.file.Append = true
log4cplus.appender.file.layout = log4cplus::PatternLayout
log4cplus.appender.file.layout.ConversionPattern = [%D{%m/%d/%y %H:%M:%S,%q} %-5p] - %m%n

简单说明一下,配置文件中log4cplus.logger.logmain即定义一个logmain对象,后面跟的两个字段前一个表示log级别,后一个指定使用的appender,即日志输出对象。log级别按严重程度从低到高依次为TRACE、DEBUG、INFO、WARN、ERROR、FATAL。log4cplus.appender.xxx定义具体的appender属性,如是控制台还是文件,进一步配置文件名、文件大小等。

将配置保存到一个配置文件中(如log4cplus.conf),以下你将看到如何使用配置文件。有关更详细的配置,读者可自行摸索。

6 log4cplus运用于项目

以上“hello, world”程序只是大概演示log4cplus的用法,实际项目使用要有系统观念,就是怎样用才更方便,我们可以再做点封装。我们可以定义一个全局logger对象,将log4cplus初始化配置放到一个源文件中,重新定义一些简化的宏置于头文件,比如笔者就定义了Log.h/Log.cpp两个文件,代码如下:

Log.h文件:

#pragma once
#include <log4cplus/logger.h>
#include <log4cplus/loggingmacros.h>
using namespace log4cplus;
using namespace log4cplus::helpers;
// global object
extern Logger logger;
// define some macros for simplicity
#define LOG_TRACE(logEvent)         LOG4CPLUS_TRACE(logger, logEvent)
#define LOG_DEBUG(logEvent)         LOG4CPLUS_DEBUG(logger, logEvent)
#define LOG_INFO(logEvent)          LOG4CPLUS_INFO(logger, logEvent)
#define LOG_WARN(logEvent)          LOG4CPLUS_WARN(logger, logEvent)
#define LOG_ERROR(logEvent)         LOG4CPLUS_ERROR(logger, logEvent)
#define LOG_FATAL(logEvent)         LOG4CPLUS_FATAL(logger, logEvent)  extern void InitLogger(bool daemonized); 

Log.cpp文件:

#include <log4cplus/logger.h>
#include <log4cplus/consoleappender.h>
#include <log4cplus/fileappender.h>
#include <log4cplus/layout.h>
#include <log4cplus/configurator.h>  #include "Log.h"  Logger logger = Logger::getInstance(LOG4CPLUS_TEXT("logmain"));  void InitLogger(bool daemonized)
{  if (daemonized)  PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("/your/path/log4cplusd.conf"));  else  PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("/your/path/log4cplus.conf"));
}  

将这两个文件置于你的项目中,然后在 main 函数中调用 InitLogger() 初始化 log4cplus,再在需要加log的文件中包含Log.h即可。注意InitLogger函数的参数daemonized,该参数表示应用程序是否是守护进程(后台运行),一般我们开发的应用程序大多是守护进程(linux后台服务大多是守护进程),但调试的时候会前台运行,对于守护进程,我们只需要把日志记录到某个文件中就行了,而对于前台调试运行,我们就只需要将日志输出到控制台,所以这里是一点使用技巧。做到这点我们只需分别提供两个配置文件即可,"/your/path"就是你放置配置文件的地方,一般可以设为你应用程序部署的目录下的etc目录。

至此我们可以使用log4cplus了!以下是实际的日志输出效果:

[11/05/12 10:28:36,002 INFO ] - TCPDomain - TCPDomain()
[11/05/12 10:28:36,002 INFO ] - TCPDomain - Connect server success!
[11/05/12 10:28:36,002 TRACE] - Session - Thread run.
[11/05/12 10:28:46,006 ERROR] - TCPDomain - SelectRead time out!
[11/05/12 10:28:56,016 ERROR] - TCPDomain - SelectRead time out!  

7 log4cplus交叉编译

对于嵌入式应用 ,有交叉编译这么一说。以上的介绍是基于PC的,如果你的平台是嵌入式平台如arm,则只需编译链接arm平台的log4cplus库即可,其它都一样。对于大多数autotools工程,其交叉编译方法大致如下:

./configure --prefix=/your/install/path --host=arm-linux CXX=your-toolkit-g++
make
make install  

其中--prefix即指定你的安装目录,如/opt/log4cplus,--host指定目标平台,CXX指定你的交叉编译工具(确保shell环境能找到该工具)。编译安装完后可在安装目录找到arm版本的库文件。

8 总结

日志固然好,但也不建议随意使用,用多了会导致程序性能有所下降,且代码size增加不少。以上是笔者运用log4cplus的些许经验,更深一步的原理机制有待进一步探究。

c++日志工具之——log4cplus相关推荐

  1. 细说 Java 主流日志工具库

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 作者:静默虚空 juejin.im/post/5c8f35bfe51d4545cc650567 ...

  2. 细说Java主流日志工具库

    细说 Java 主流日志工具库 日志框架 java.util.logging (JUL) Log4j Logback Log4j2 Log4j vs Logback vs Log4j2 日志门面 co ...

  3. 【工具推荐】ELMAH——可插拔错误日志工具(转)

    出处:http://www.cnblogs.com/liping13599168/archive/2011/02/23/1962625.html 今天看到一篇文章(构建ASP.NET网站十大必备工具( ...

  4. Android Studio 单刷《第一行代码》系列 02 —— 日志工具 LogCat

    前情提要(Previously) 本系列将使用 Android Studio 将<第一行代码>(书中讲解案例使用Eclipse)刷一遍,旨在为想入坑 Android 开发,并选择 Andr ...

  5. iOS轻量分组日志工具 Log4OC

    OC分级日志工具,支持4种日志级别,提供两种持久化方案 源码地址: github.com/FinderTiwk/- 使用 #import "Log4OC.h"//DEBUGLog( ...

  6. linux 系统后门检测工具,Linux系统的各种后门和日志工具详细介绍[2]

    chfn 提升本地普通用户权限的程序 运行chfn 在它提示输入新的用户名时 如果用户输入rookit密码 他的权限就被提升为root chsh 提升本地用户权限的程序 运行chsh 在它提示输入新的 ...

  7. Android入门(三) | Android 的日志工具 Logcat

    文章目录 日志工具类 android.util.Log Logcat 中的过滤器 日志工具类 android.util.Log Log 从属日志工具类 android.util.Log ,该类提供了五 ...

  8. .NET日志工具介绍

    原文:http://www.cnblogs.com/maxliu/archive/2012/08/03/2621088.html 最近项目需要一个日志工具来跟踪程序便于调试和测试,为此研究了一下.NE ...

  9. Android日志工具Log的使用

    Androi中的日志工具类是Log(android.util.Log),这个类提供了如下5种方法来供我们打印日志. 方法 作用 Log.v() 用于打印那些最为繁琐的.意义最小的日志信息.对应级别是v ...

最新文章

  1. python dlib 的安装
  2. 用Python解“爬动的蠕虫”题
  3. 【虾说区块链】入门区块链,先学分布式系统!一文说明分布式系统与区块链的关系...
  4. HTML5 蔡徐坤打篮球游戏 NMSL❤️❤️❤️
  5. java 程序分析题_java程序入门50题分析:002
  6. 基于wemos D1的无线遥控灯(433m无线模块)
  7. 四大金刚 数据结构_GIS技术在气象领域应用综述
  8. No fallback instance of type class found for feign client user-service(转)
  9. ubuntu下查看window下文本文件乱码的解决方法
  10. 面试必备:Spring 面试 63 问!
  11. 精品素材 – 24款扁平风格 PSD 格式图标免费下载
  12. Parallels中使用加密狗读取文件出现错误
  13. Azure Active Directory密码同步问题
  14. LINUX的VirtualBox安装Windows7
  15. Atitit android app 最佳实践2021目录1. Android strudio,,and viruse machine need down another... 11.1. P
  16. html网页设计插件,适用于网页设计的Photoshop插件包
  17. 小米红米手机绕过内测申请,“偷渡”升级到开发版(内测版)详细教程,告别刷分和等待!
  18. Android开发中Post方式上传文件(头像之类的)
  19. SSL1659 栈练习括弧匹配检验
  20. CTP 4097错误根源 / CTP程序运行没有反应/CTP版本说明

热门文章

  1. 7.查找——数据结构(严蔚敏 C语言版)
  2. BaiduMap---百度地图官方Demo之离线地图功能(介绍如何下载和使用离线地图)
  3. jquery 遍历java对象_jquery遍历数组、对象
  4. CUMCM-2017-problem-A
  5. linux命令行安装浏览器arm64,linux下安装google-chrome浏览器和chromedriver
  6. 网狐荣耀斗地主等15合1(美女图)
  7. Python-声明变量
  8. Love of my life吉他谱
  9. java鸡兔同笼用循环_Java使用for循环解决经典的鸡兔同笼问题示例
  10. LeetCode数据库题目汇总一(附答案)