Linux和Windows(VS 2019)下安装使用Log4cpp日志库

2024-06-20 21:12

本文主要是介绍Linux和Windows(VS 2019)下安装使用Log4cpp日志库,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、Log4cpp简介

二、Windows下的Log4cpp的安装

1、下载网址

2、解决方案

三、Vistual Studio中使用第三方库

1、拷贝对应下图路径下的include文件进入你的项目目录下面去,并将之前编译好的库文件也放在对应项目目录下面去。

2、打开你的项目,右键项目属性

3、选择常规选项卡,在附加包含目录里面输入你之前对应的log4cpp的include文件夹路径

5、选择链接器选项卡,进行附加依赖性,输入log4cpp.lib

6、测试程序

7、实际开发中可以用的,对于log4cpp单例类

四、Linux下的Log4cpp的安装

1、安装log4cpp,执行如下指令进行编译安装

2、包含头文件

3、初始化日志输出的目的地(appenders)

4、设置日志输出的格式

5、设置类别输出的(category)和日志优先级(priority)

6、定义一个宏,方便我们更好的调用

7、使用宏定义记录日志

8、加载配置ini


一、Log4cpp简介

 Log4cpp是个基于LGPL的开源项目,移植自Java的日志处理跟踪项目log4j,并保持了API上的一致。其类似的支持库还包括Java(log4j),C++(log4cpp、log4cplus),C(log4c),python(log4p)等。

  Log4cpp有如下优点:

  •提供了可扩展的多种日志记录方式;

  •提供了NDC(嵌套诊断上下文),可用于多线程、多场景的跟踪调试;

  •提供了完整的日志动态优先级控制,可随时调整需要记录的日志优先级;

  •可通过配置文件完成所有配置并动态加载;

  •性能优秀,内存占用小,经过编译后的log4cpp.dll大小仅有160kb;

  •代码级的平台无关性,Log4cpp源代码经过编译后,适用于大多数主流的操作系统和开发工具;

  •概念清晰,学习和使用方便,熟练程序员一天之内即可很好地应用log4cpp进行开发。

二、Windows下的Log4cpp的安装

1、下载网址

http://log4cpp.sourceforge.net/icon-default.png?t=N7T8http://log4cpp.sourceforge.net/

选择图片红色圈出来的,进行下载。下载好后,解压文件并打开文件。双击打开下面的没事msvc10.sln

这里使用的是Visutal Studio 2019,注意这里的库只针对Visutal Studio 2017及其以上的IDE。点击确定

右击重新生成

报错

2、解决方案

1.双击log4cpp项目,在log4cpp项目下找到以下红色圈出来的

2.右键属性

3.在常规命令行里面输入以下命令

if not exist $(OutDir) md $(OutDir)
mc.exe -h $(OutDir) -r $(OutDir) $(ProjectDir)..\%(Filename).mc
RC.exe -r -fo $(OutDir)%(Filename).res $(OutDir)%(Filename).rc
link.exe /MACHINE:IX86 -dll -noentry -out:$(OutDir)NTEventLogAppender.dll $(OutDir)%(Filename).res

4.继续右击log4cpp项目,选择属性

5.选择C/C++下的预处理器,在预处理器定义里面的最下面添加,然后点击确定保存

HAVE_SNPRINTF

6.选择Log4cpp重新生成,发现程序成功运行

7.进入对应路径,查找我们编译好的库文件,红色圈出来的是对应查找路径,读者对应在该路径查找编译好的库文件,黄色是编译好的库文件

三、Vistual Studio中使用第三方库

1、拷贝对应下图路径下的include文件进入你的项目目录下面去,并将之前编译好的库文件也放在对应项目目录下面去。

2、打开你的项目,右键项目属性

3、选择常规选项卡,在附加包含目录里面输入你之前对应的log4cpp的include文件夹路径

4、选择链接器选项卡,附加库目录,输入对应的库文件路径(Debug路径下装的是编译好的库文件log4cpp.lib和log4cpp.dll)

5、选择链接器选项卡,进行附加依赖性,输入log4cpp.lib

6、测试程序

#include "log4cpp/Category.hh"
#include "log4cpp/Appender.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/OstreamAppender.hh"
#include "log4cpp/Layout.hh"
#include "log4cpp/BasicLayout.hh"
#include "log4cpp/Priority.hh"
#include "log4cpp/PatternLayout.hh"void testOutputConsole()
{log4cpp::Appender* appender1 = new log4cpp::OstreamAppender("console", &std::cout);appender1->setLayout(new log4cpp::BasicLayout());	// 默认配置log4cpp::Category& root = log4cpp::Category::getRoot();root.setPriority(log4cpp::Priority::DEBUG); //低于WARN类型的日志不记录  NOTSET < DEBUG < INFO < NOTICE < WARN < ERROR < CRIT < ALERT < FATAL = EMERGroot.addAppender(appender1);// 1.use of functions for logging messages	1.使用记录消息的函数root.debug("root debug");root.warn("root warn");root.error("root error");root.info("root info");// 2.printf-style for logging variables  2.printf风格的日志变量root.warn("%d + %d == %s ?", 1, 1, "two");// 3.use of streams for logging messages  3.使用流记录消息root << log4cpp::Priority::ERROR << "Streamed root error";root << log4cpp::Priority::INFO << "Streamed root info";// 4.or this way:  4.或者这样说:root.errorStream() << "Another streamed error";root.debugStream() << "Another streamed debug";log4cpp::Category::shutdown();
}

7、实际开发中可以用的,对于log4cpp单例类

头文件

#ifndef _MY_LOGGER_H_
#define _MY_LOGGER_H_#include <string>
#include <log4cpp/Category.hh>class MyLogger {
public:bool init(const std::string &log_conf_file);			// 指定加载log配置文件static MyLogger *instance() { return &_instance; };		// 单例模式,返回自己log4cpp::Category *GetHandle() { return _category; };	private:static MyLogger _instance;log4cpp::Category *_category;	// 通过此对象可以实现日志写入
};/* 宏定义,方便调用 */
#define LOG_DEBUG MyLogger::instance()->GetHandle()->debug		// 调试
#define LOG_INFO MyLogger::instance()->GetHandle()->info		// 信息,消息
#define Log_NOTICE MyLogger::instance()->GetHandle()->notice	// 通知
#define LOG_WARN MyLogger::instance()->GetHandle()->warn		// 警告
#define LOG_ERROR MyLogger::instance()->GetHandle()->error		// 错误
#define LOG_FATAL MyLogger::instance()->GetHandle()->fatal		// 致命错误/** __LINE__ : 文件中的当前行号;* __FILE__ : 文件的完整路径和文件名;如果用在包含文件中,则返回包含文件名;* __FUNCTION__ : 函数名字。*/
#define LOG(__level) log4cpp::Category::getRoot() << log4cpp::Priority::__level << "[" << __FUNCTION__ << "][" << __LINE__ << "]: "
//#define LOG(__level) log4cpp::Category::getRoot() << log4cpp::Priority::__level << "[" << __FILE__ << "][" << __FUNCTION__ << "][" << __LINE__ << "]: "#endif

源文件

#include "MyLogger.h"#include <iostream>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/PropertyConfigurator.hh>// 静态变量,需要在类外部初始化一下
MyLogger MyLogger::_instance;bool MyLogger::init(const std::string &log_conf_file) {try {log4cpp::PropertyConfigurator::configure(log_conf_file);	// 初始化log配置文件} catch (log4cpp::ConfigureFailure &f) {std::cerr << "load log config file " << log_conf_file.c_str() << " failed with result: " << f.what() << std::endl;return false;}// 初始化成功后,使用getRoot()获取操作日志的对象_category = &log4cpp::Category::getRoot();return true;
}

main文件

#include "MyLogger.h"int main(void) {if (!MyLogger::instance()->init("log.conf")) {fprintf(stderr, "init log module failed.\n");return -1;}LOG_DEBUG("测试 debug.");LOG_INFO("测试 inof.");Log_NOTICE("测试 notice.");LOG_WARN("测试 warn.");LOG_ERROR("测试 error.");LOG_FATAL("测试 fatal.");LOG_DEBUG("%d + %c == %s", 1, 'a', "1a");LOG(DEBUG) << "123";LOG(ERROR) << "ERROR";// 关闭日志log4cpp::Category::shutdown();return 0;
}

四、Linux下的Log4cpp的安装

1、安装log4cpp,执行如下指令进行编译安装

  • log4cpp的官网是:http://log4cpp.sourceforge.net/icon-default.png?t=N7T8http://log4cpp.sourceforge.net/
wget https://nchc.dl.sourceforge.net/project/log4cpp/log4cpp-1.1.x%20%28new%29/log4cpp-1.1/log4cpp-1.1.3.tar.gz
tar xzvf log4cpp-1.1.3.tar.gz
cd log4cpp-1.1.3
./configure  
make
make install

安装完毕后,log4cpp库路径在 /usr/local/lib

可以使用命令 mv -if /usr/local/lib/liblog4cpp.* 自己的项目路径 拷贝到自己的项目路径中去;例如,我会在项目路径中创建一个lib文件夹,将刚刚安装的log4cpp库拷贝到此文件夹中

log4cpp头文件路径在 /usr/local/include/log4cpp

可以使用命令 mv -if /usr/local/include/log4cpp 自己的项目路径 拷贝到自己的项目路径中去;例如,我会在项目路径中创建一个include文件夹,将刚刚安装的log4cpp头文件拷贝到此文件夹中

2、包含头文件

#include <log4cpp/Category.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/OstreamAppender.hh>

3、初始化日志输出的目的地(appenders

// 输出到std::cout
log4cpp::Appender *appender = new log4cpp::OstreamAppender("root", &std::cout);
// 输出到log文件
//log4cpp::Appender *appender = new log4cpp::FileAppender("root", "test.log");
appender有以下这些:
log4cpp::FileAppender // 输出到文件
log4cpp::RollingFileAppender // 输出到回卷文件,即当文件到达某个大小后回卷
log4cpp::OstreamAppender // 输出到一个ostream类
log4cpp::RemoteSyslogAppender // 输出到远程syslog服务器
log4cpp::StringQueueAppender // 内存队列
log4cpp::SyslogAppender // 本地syslog
log4cpp::Win32DebugAppender // 发送到缺省系统调试器
log4cpp::NTEventLogAppender // 发送到win 事件日志

  上文,我们说过日志输出到终端或者文件中实际上是很慢的,会引起IO中断,所以我们可以输出到内存里StringQueueAppender,然后从StringQueueAppender输出到其它地方,这样我们的线程执行是比较高效的。

4、设置日志输出的格式

log4cpp::PatternLayout *patternLayout = new log4cpp::PatternLayout();
patternLayout->setConversionPattern("%d [%p] - %m%n");
appender->setLayout(patternLayout);

日志输出格式控制有: PatternLayout supports following set of format characters:
%% - a single percent sign
%c - the category
%d - the date\n Date format: The date format character may be followed by a date format specifier enclosed between braces. For example, %d{%\H:%M:%S,%l} or %d{%\d %m %Y %H:%\M:%S,%l}. If no date format specifier is given then the following format is used: "Wed Jan 02 02:03:55 1980". The date format specifier admits the same syntax as the ANSI C function strftime, with 1 addition. The addition is the specifier %l for milliseconds, padded with zeros to make 3 digits.
%m - the message
%n - the platform specific line separator
%p - the priority
%r - milliseconds since this layout was created.
%R - seconds since Jan 1, 1970
%u - clock ticks since process start
%x - the NDC
%t - thread name
By default, ConversionPattern for PatternLayout is set to "%m%n".

5、设置类别输出的(category)和日志优先级(priority)

log4cpp::Category &root = log4cpp::Category::getRoot();
root.setPriority(log4cpp::Priority::NOTICE);
root.addAppender(appender);

日志的级别总共有:NOTSET < DEBUG < INFO < NOTICE < WARN < ERROR < CRIT < ALERT < FATAL = EMERG。日志级别的意思是低于该级别的日志不会被记录。

6、定义一个宏,方便我们更好的调用

#define LOG(__level) log4cpp::Category::getRoot() << log4cpp::Priority::__level << __FILE__ << " " << __LINE__ << ": "
当然也可以使用Category定义的函数:/*** Log a message with the specified priority.* @param priority The priority of this log message.* @param stringFormat Format specifier for the string to write* in the log file.* @param ... The arguments for stringFormat**/virtual void log(Priority::Value priority, const char* stringFormat,...) throw();/*** Log a message with the specified priority.* @param priority The priority of this log message.* @param message string to write in the log file**/virtual void log(Priority::Value priority,const std::string& message) throw();void debug(const char* stringFormat, ...) throw();void debug(const std::string& message) throw();void info(const char* stringFormat, ...) throw();...

7、使用宏定义记录日志

LOG(DEBUG) << "i am happy.";
LOG(INFO)  << "oh, you happy, we happy.";
LOG(NOTICE)<< "please do not contact me. ";
LOG(WARN)  << "i am very busy now.";
LOG(ERROR) << "oh, what happed?";

当然我们在使用过程中,可以封装一个单例,像上面给出的例子一样

在实际工程上应用,我们是使用日志配置文件去控制日志记录的。接下来让我们先配置一个日志配置文件,比如下面这个例子:

#定义Root category的属性
log4cpp.rootCategory=DEBUG, RootLog#定义RootLog属性
log4cpp.appender.RootLog=RollingFileAppender
log4cpp.appender.RootLog.layout=PatternLayout
#log4cpp.appender.RootLog.layout.ConversionPattern=%d{% m-%d %H:%M:%S %l} [%t][%p]%m%n
log4cpp.appender.RootLog.layout.ConversionPattern=%d{\%\m-%d %H:%M:%S %l} [%t][%p]%m%n
log4cpp.appender.RootLog.fileName=/var/log/qiniu_bike.log
log4cpp.appender.RootLog.maxFileSize=268435456 #256MB
log4cpp.appender.RootLog.fileNamePattern=qiniu_bike_%i.log
log4cpp.appender.RootLog.maxBackupIndex=256

8、加载配置ini

BOOL Logger::init(const std::string & log_conf_file)
{try{log4cpp::PropertyConfigurator::configure(log_conf_file);}catch(log4cpp::ConfigureFailure& f){std::cerr << " load log config file " << log_conf_file.c_str() << " failed with result : " << f.what()<< std::endl;return FALSE;}m_Category = &log4cpp::Category::getRoot();return TRUE;
}

这篇关于Linux和Windows(VS 2019)下安装使用Log4cpp日志库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1079270

相关文章

VScode连接远程Linux服务器环境配置图文教程

《VScode连接远程Linux服务器环境配置图文教程》:本文主要介绍如何安装和配置VSCode,包括安装步骤、环境配置(如汉化包、远程SSH连接)、语言包安装(如C/C++插件)等,文中给出了详... 目录一、安装vscode二、环境配置1.中文汉化包2.安装remote-ssh,用于远程连接2.1安装2

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

使用Python实现操作mongodb详解

《使用Python实现操作mongodb详解》这篇文章主要为大家详细介绍了使用Python实现操作mongodb的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、示例二、常用指令三、遇到的问题一、示例from pymongo import MongoClientf

SQL Server使用SELECT INTO实现表备份的代码示例

《SQLServer使用SELECTINTO实现表备份的代码示例》在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误,在SQLServer中,可以使用SELECTINT... 在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误。在 SQL Server 中,可以使用 SE

使用Python合并 Excel单元格指定行列或单元格范围

《使用Python合并Excel单元格指定行列或单元格范围》合并Excel单元格是Excel数据处理和表格设计中的一项常用操作,本文将介绍如何通过Python合并Excel中的指定行列或单... 目录python Excel库安装Python合并Excel 中的指定行Python合并Excel 中的指定列P

浅析Rust多线程中如何安全的使用变量

《浅析Rust多线程中如何安全的使用变量》这篇文章主要为大家详细介绍了Rust如何在线程的闭包中安全的使用变量,包括共享变量和修改变量,文中的示例代码讲解详细,有需要的小伙伴可以参考下... 目录1. 向线程传递变量2. 多线程共享变量引用3. 多线程中修改变量4. 总结在Rust语言中,一个既引人入胜又可

golang1.23版本之前 Timer Reset方法无法正确使用

《golang1.23版本之前TimerReset方法无法正确使用》在Go1.23之前,使用`time.Reset`函数时需要先调用`Stop`并明确从timer的channel中抽取出东西,以避... 目录golang1.23 之前 Reset ​到底有什么问题golang1.23 之前到底应该如何正确的

详解Vue如何使用xlsx库导出Excel文件

《详解Vue如何使用xlsx库导出Excel文件》第三方库xlsx提供了强大的功能来处理Excel文件,它可以简化导出Excel文件这个过程,本文将为大家详细介绍一下它的具体使用,需要的小伙伴可以了解... 目录1. 安装依赖2. 创建vue组件3. 解释代码在Vue.js项目中导出Excel文件,使用第三