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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/30733.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nacos 配置修改.代码实时刷新

再类上用 RefreshScope 更新Value(“${uniqlo.privacy.url:https://wsurl.cc/yourls-api.php}”) private String shortLinkGenerateUrl;的数据可以实时更新 2.再配置类上次用 ConfigurationProperties(prefix “test.privacy”) 和nacos的配置一直 Data Component Configu…

华为云EI生态

1、人工智能技术趋势 2、华为AI发展思路 3、华为云EI&#xff1a;让企业更智能 4、华为云服务全景图 5、基础平台类服务 6、MLS:解决特性到模型应用的完整过程 7.DLS 8.GES超大规模一体化图分析与查询 9、EI视觉认知 10、EI语音语义 11、OCR&#xff1a;提供高精度光学文字自动…

C++初学者指南第一步---9.函数

C初学者指南第一步—9.函数 文章目录 C初学者指南第一步---9.函数1.输入和输出1.1第一个例子1.2返回类型1.3函数参数常量参数默认值参数 1.4函数重载 2.函数执行2.1递归2.2 声明和定义 3.函数设计3.1约定3.2 特性[[nodiscard]] &#xff08;C17&#xff09;3.3 不抛出异常保证&…

【Python驯化-01】python中set去重数据每次结果不一致问题解决

【Python驯化-01】python中set去重数据每次结果不一致问题解决 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 免费获取相关内容文档关注…

考研计组chap2数据的表示和运算

3一、进位计数制 1.r进制 第i位表示r进制的权为i 2.进制转换 &#xff08;1&#xff09;r->10 对应位置数*权值 &#xff08;2&#xff09;2 -> 16 or 8 每三位2进制数可表示1位16进制 每四位2进制数可表示1位16进制 so 分开之后转为16进制即可 eg&#xff1a;1…

基于51单片机恒温箱设计

基于51单片机恒温箱设计 &#xff08;程序&#xff0b;原理图&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 本设计由STC89C52单片机电路数字温度传感器DS18B20电路按键电路蜂鸣器报警电路继电器控制电路LCD1602液晶显示电路电源电路组成。 1.LCD1602液…

偏微分方程算法之抛物型方程差分格式编程示例四(Richardson外推)

目录 一、研究问题 二、C++代码 三、结果分析 一、研究问题 已知其精确解为。分别取以下三种步长: ①

树形dp,CF 1926 G - Vlad and Trouble at MIT

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - G - Codeforces 二、解题报告 1、思路分析 考虑每个结点最终状态只可能为和P连通或者和S连通 我们我们自然而然的将问题划分为这样的状态 f[x][0]代表结点x和P连通需要割掉最少的边 f[x][1]代…

Windows Server配置NFS,做ESXI共享存储

1:登录wINDOWS系统&#xff0c;点击添加角色和功能。 2:根据向导提示&#xff0c;一路下一步。在服务器角色中选择文件和存储服务器在文件和iSCSI服务中勾选NFS服务器。 3&#xff1a;按照提示一路下一步&#xff0c;安装NFS。 4&#xff1a;安装完成后关闭安装界面。 5&#x…

代码随想录算法训练营第六十五天 | 岛屿数量 深搜、岛屿数量 广搜、岛屿的最大面积

岛屿数量 深搜 题目链接&#xff1a;99. 岛屿数量 文字讲解&#xff1a;99. 岛屿数量 | 代码随想录 解题思路 本题已经说明&#xff0c;只有水平方向和竖直方向才能组成岛屿 本题思路&#xff0c;是遇到一个没有遍历过的节点陆地&#xff0c;计数器就加一&#xff0c;然后把…

为电脑小白推荐的5款实用工具软件

​ 电脑上的各类软件有很多&#xff0c;除了那些常见的大众化软件&#xff0c;还有很多不为人知的小众软件&#xff0c;专注于实用功能&#xff0c;简洁干净、功能强悍。 1.磁盘空间分析——TreeSize Free ​ TreeSize Free是一款免费的磁盘空间分析工具&#xff0c;能够扫描…

Sip协议(四) -注册流程

Sip协议(四) -注册流程 本文主要介绍下sip协议中, agent的注册流程. 一: 流程图 简单的流程图如下: agent发起注册fs 返回401 ,并携带WWW-Authenticateagent第二次发起注册,增加Authorizationfs返回授权成功, 或者失败. 二: sip流程 发起注册REGISTER 首先agent发起注册请求…

重磅!鹅厂大牛带你30分钟玩转AI智能结对编程!

在大模型时代&#xff0c;人工智能技术的突破性进展正重塑着软件开发的面貌。AI的融入不仅优化了代码编写过程&#xff0c;更开启了智能编程的新纪元&#xff0c;为开发者带来了前所未有的工作效率和创新可能。AI结对编程不仅能够极大提升研发效率&#xff0c;还能通过智能分析…

【查缺补漏】python

python查缺补漏 底板除 还有一种除法是//&#xff0c;称为地板除&#xff0c;两个整数的除法仍然是整数&#xff1a; >>> 10 // 3 3你没有看错&#xff0c;整数的地板除//永远是整数&#xff0c;即使除不尽。要做精确的除法&#xff0c;使用/就可以。 因为//除法只…

rsa加签验签C#和js、java、微信小程序互通

js实现rsa加签验签 https://github.com/kjur/jsrsasign 11.1.0版本 解压选择需要的版本&#xff0c;这里选择all版本了 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>JS RSA加签验签</title&g…

有趣网站分享 - 生成 O‘Reilly 类型封面

文章目录 网站介绍效果 网站介绍 –> O’RLY 封面工厂 https://orly.nanmu.me 你可以… 设置文本内容 选择图片 选择颜色 效果 2024-06-20&#xff08;四&#xff09;

前端网页开发学习(HTML+CSS+JS)有这一篇就够!

目录 HTML教程 ▐ 概述 ▐ 基础语法 ▐ 文本标签 ▐ 列表标签 ▐ 表格标签 ▐ 表单标签 CSS教程 ▐ 概述 ▐ 基础语法 ▐ 选择器 ▐ 修饰文本 ▐ 修饰背景 ▐ 透明度 ▐ 伪类 ▐ 盒子模型 ▐ 浮动 ▐ 定位 JavaScript教程 ▐ 概述 ▐ 基础语法 ▐ 函数 …

契约锁电子签章平台 add 远程命令执行漏洞复现(XVE-2023-23720)

0x01 产品简介 契约锁电子签章平台是上海亘岩网络科技有限公司推出的一套数字签章解决方案。契约锁为中大型组织提供“数字身份、电子签章、印章管控以及数据存证服务”于一体的数字可信基础解决方案,可无缝集成各类系统,让其具有电子化签署的能力,实现组织全程数字化办公。通…

还在为Android开发找不到图片测试资源发愁吗? DummyImage来助你加速开发

使用 DummyImage 模拟电影应用数据 在开发和测试过程中&#xff0c;模拟数据是不可或缺的工具。它可以帮助我们在没有真实数据的情况下测试应用程序的功能和性能。本文将介绍如何使用 [DummyImage]https://dummyimage.com生成占位符图像来模拟电影应用的数据&#xff0c;并深入…

专家观点∣企企通采购供应链数字化总监于海生:如何利用数字化技术重构采购流程,推动企业降本增效?

摘要 数字化转型现已成为企业提升竞争力、实现降本增效的必由之路。企业应主动参与到数字经济的建设中&#xff0c;以数据资源为关键要素&#xff0c;以现代信息网络为主要载体&#xff0c;以信息通信技术的有效使用作为效率提升和经济结构优化的重要推动力的一系列经济活动&a…