欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++?Log4cpp跨平臺日志庫的使用小結

 更新時間:2025年07月07日 11:23:09   作者:cpp_learners  
Log4cpp是c++類庫,本文詳細介紹了C++日志庫log4cpp的使用方法,及設置日志輸出格式和優(yōu)先級,具有一定的參考價值,感興趣的可以了解一下

項目中,最重要的模塊之一就是日志了,今天這篇博客記錄項目中l(wèi)og4cpp的用法!

Log4cpp是c++類庫,用于靈活地記錄文件、syslog、IDSA和其他目的地。它是在Log4j Java庫之后建模的,盡可能地接近它們的API。

一、介紹

1. log4cpp的日志方式

log4cpp::FileAppender                            // 輸出到文件(常用)
log4cpp::RollingFileAppender                 // 輸出到回卷文件,即當文件到達某個大小后回卷(常用)
log4cpp::OstreamAppender                   // 輸出到一個ostream類(常用)
log4cpp::RemoteSyslogAppender          // 輸出到遠程syslog服務器
log4cpp::StringQueueAppender             // 內存隊列
log4cpp::SyslogAppender                      // 本地syslog
log4cpp::Win32DebugAppender            // 發(fā)送到缺省系統(tǒng)調試器
log4cpp::NTEventLogAppender             // 發(fā)送到win 事件日志

2.設置日志輸出的格式

log4cpp::FileAppender* appender = new log4cpp::FileAppender("appender", "text.log");     

例如:

PatternLayout:自定義日志格式

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

PatternLayout支持以下一組格式字符:

  • %% - 一個百分號;
  • %c - the category;
  • %d - date日期格式:日期格式字符后面可以跟著花括號括起來的日期格式說明符。例如,%d              {% H: % M: % S、l %}或% d {% d % M H % Y %: % M: % S、l %}。如果沒有給出日期          格式說明符,則使用以下格式:"Wed Jan 02 02:03:55 1980"。日期格式說明符承認與              ANSI C函數strftime相同的語法,只是增加了1個。加號是以毫秒為單位的說明符%l,用          0填充為3位數字;
  • %m - 你要輸出的日志信息;
  • %n - 換行符;
  • %p - 優(yōu)先級;
  • %r - 該布局創(chuàng)建后的毫秒數;
  • %R - 從1970年1月1日0時開始到目前為止的秒數;
  • %u - 進程開始到目前為止的時鐘周期數;
  • %x - the NDC;
  • %t - 線程的名字;
  • 默認情況下,PatternLayout的ConversionPattern設置為“%m%n”。

3. 設置日志的輸出優(yōu)先級

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

日志的級別總共有:

NOTSET < DEBUG < INFO < NOTICE < WARN < ERROR < CRIT < ALERT < FATAL = EMERG

日志級別的意思是低于該級別的日志不會被記錄。

二、Window

1. 下載log4cpp

log4cpp官網:

Log for C++ Project

下載后解壓進入msvc10

因為官方提供的是vs2010編譯的項目,所以根據自己電腦裝的vs去打開即可,例如我這里使用vs2017去打開,打開后會提示升級,升級即可。

2. 編譯

3. 報錯解決1

 不出意外的話,會報錯。

解決方法:①在log4cpp項目工程中找到NTEventLogCategories.mc文件,選擇該文件上然后右鍵選擇屬性,在彈出窗口中找到“配置屬性 - 自定義生成工具 - 常規(guī) - 命令行”中修改編譯命令,設置為如下命令:

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

然后再次右鍵log4cpp,選擇重新編譯!

 不出意外的話,再次報錯。

4. 報錯解決2

解決方法:由于log4cpp中對snprintf進行了重新實現(xiàn),visual studio的c庫對snprintf也有實現(xiàn),windows中在鏈接時會報snprintf函數沖突,所以需要設置log4cpp的預編譯項,選擇使用visual stuido中c庫的實現(xiàn),在log4cpp工程上點右鍵選屬性,在”配置屬性 - C/C++ - 預處理器 - 預處理器定義"中增加一條預處理定義 。

HAVE_SNPRINTF

再次編譯!

5. 編譯成功

不出意外的話,編譯通過!

進入路徑log4cpp-1.1.3\log4cpp\msvc10\log4cpp\Debug,編譯好的庫就在這里。

頭文件路徑:log4cpp-1.1.3\log4cpp 

 注意,這是編譯x86(Win32)的庫,如果需要編譯x64的庫,在項目中添加x64的庫后進行編譯即可;編譯好的庫路徑:log4cpp-1.1.3\log4cpp\msvc10\x64\Debug

 Release庫編譯方式與上面方式一樣!

6. 測試

官方例子,稍作修改

新建項目,將上面編譯好的 log4cpp.dll 和 log4cpp.lib 和 /include 文件夾拷貝到項目路徑中去

#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"


int main(void) {

	/* 1.日志輸出到控制臺 */
	{
		log4cpp::Appender *appender1 = new log4cpp::OstreamAppender("console", &std::cout);
		appender1->setLayout(new log4cpp::BasicLayout());	// 默認配置

		log4cpp::Category& root = log4cpp::Category::getRoot();
		root.setPriority(log4cpp::Priority::WARN);
		root.addAppender(appender1);

		// 1.use of functions for logging messages	
		root.debug("root debug");
		root.warn("root warn");
		root.error("root error");
		root.info("root info");

		// 2.printf-style for logging variables
		root.warn("%d + %d == %s ?", 1, 1, "two");

		// 3.use of streams for logging messages
		root << log4cpp::Priority::ERROR << "Streamed root error";
		root << log4cpp::Priority::INFO << "Streamed root info";

		// 4.or this way:
		root.errorStream() << "Another streamed error";
		root.debugStream() << "Another streamed debug";
	}
	
	/* 2.日志輸出到控制臺和本地文件 */
	{
		log4cpp::Appender *appender2 = new log4cpp::FileAppender("default", "program.log");
		appender2->setLayout(new log4cpp::BasicLayout());

		log4cpp::Category& sub1 = log4cpp::Category::getInstance(std::string("sub1"));
		sub1.addAppender(appender2);

		sub1.error("sub1 error");
		sub1.warn("sub1 warn");

		sub1 << log4cpp::Priority::ERROR << "Streamed sub1 error";
		sub1 << log4cpp::Priority::WARN << "Streamed sub1 warn";
	}

	/* 3.日志輸出到本地文件 */
	{
		std::string logFileName = "test.log";

		// 優(yōu)先級
		log4cpp::Priority::PriorityLevel logPri = log4cpp::Priority::DEBUG;		
		
		// 自定義布局
		log4cpp::PatternLayout* logLayout = new log4cpp::PatternLayout();
		logLayout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S} [%p] : %m%n");

		// 日志輸出到本地文件
		log4cpp::FileAppender* logFile = new log4cpp::FileAppender("default", logFileName);
		logFile->setLayout(logLayout);	// 設置自定義布局

		// 輸出日志的操作類
		log4cpp::Category& logCat = log4cpp::Category::getInstance("logCat");
		logCat.addAppender(logFile);
		
		//設置優(yōu)先級
		logCat.setPriority(logPri);

		logCat.error("測試 error");	
		logCat.debug("測試 debug");

		logCat.warn("%d + %d == %s ?", 1, 1, "two");

		logCat << log4cpp::Priority::ERROR << "Streamed root error";
		logCat << log4cpp::Priority::INFO << "Streamed root info";

		logCat.errorStream() << "Another streamed error";
		logCat.debugStream() << "Another streamed debug";
	}

	// 關閉日志
	log4cpp::Category::shutdown();

	return 0;
}

三、Linux

1. 下載Log4cpp

可以通過上面的官網去下載,然后再拷入Linux系統(tǒng)中!

或者根據自己系統(tǒng)的特性,使用下面鏈接去下載,

https://nchc.dl.sourceforge.net/project/log4cpp/log4cpp-1.1.x%20%28new%29/log4cpp-1.1/log4cpp-1.1.3.tar.gz

例如Ubuntu: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 -zxvf log4cpp*.tar.gz 去解壓。

2. 編譯安裝

然后 cd log4cpp* 進入文件夾

然后執(zhí)行 ./configure

然后執(zhí)行 make

然后執(zhí)行 make install 

即可安裝成功!

命令匯總:

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.* 自己的項目路徑 拷貝到自己的項目路徑中去;例如,我會在項目路徑中創(chuàng)建一個lib文件夾,將剛剛安裝的log4cpp庫拷貝到此文件夾中

log4cpp頭文件路徑在 /usr/local/include/log4cpp

可以使用命令 mv -if /usr/local/include/log4cpp 自己的項目路徑 拷貝到自己的項目路徑中去;例如,我會在項目路徑中創(chuàng)建一個include文件夾,將剛剛安裝的log4cpp頭文件拷貝到此文件夾中

3. 測試

#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"


int main(int argc, char **argv) {

	/* 1.日志輸出到控制臺 */
	{
		log4cpp::Appender *appender1 = new log4cpp::OstreamAppender("console", &std::cout);
		appender1->setLayout(new log4cpp::BasicLayout());	// 默認配置

		log4cpp::Category& root = log4cpp::Category::getRoot();
		root.setPriority(log4cpp::Priority::WARN);
		root.addAppender(appender1);

		// 1.use of functions for logging messages	
		root.debug("root debug");
		root.warn("root warn");
		root.error("root error");
		root.info("root info");

		// 2.printf-style for logging variables
		root.warn("%d + %d == %s ?", 1, 1, "two");

		// 3.use of streams for logging messages
		root << log4cpp::Priority::ERROR << "Streamed root error";
		root << log4cpp::Priority::INFO << "Streamed root info";

		// 4.or this way:
		root.errorStream() << "Another streamed error";
		root.debugStream() << "Another streamed debug";
	}
	
	/* 2.日志輸出到控制臺和本地文件 */
	{
		log4cpp::Appender *appender2 = new log4cpp::FileAppender("default", "program.log");
		appender2->setLayout(new log4cpp::BasicLayout());

		log4cpp::Category& sub1 = log4cpp::Category::getInstance(std::string("sub1"));
		sub1.addAppender(appender2);

		sub1.error("sub1 error");
		sub1.warn("sub1 warn");

		sub1 << log4cpp::Priority::ERROR << "Streamed sub1 error";
		sub1 << log4cpp::Priority::WARN << "Streamed sub1 warn";
	}

	/* 3.日志輸出到本地文件 */
	{
		std::string logFileName = "test.log";

		// 優(yōu)先級
		log4cpp::Priority::PriorityLevel logPri = log4cpp::Priority::DEBUG;		
		
		// 自定義布局
		log4cpp::PatternLayout* logLayout = new log4cpp::PatternLayout();
		logLayout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S} [%p] : %m%n");

		// 日志輸出到本地文件
		log4cpp::FileAppender* logFile = new log4cpp::FileAppender("default", logFileName);
		logFile->setLayout(logLayout);	// 設置自定義布局

		// 輸出日志的操作類
		log4cpp::Category& logCat = log4cpp::Category::getInstance("logCat");
		logCat.addAppender(logFile);
		
		//設置優(yōu)先級
		logCat.setPriority(logPri);

		logCat.error("測試 error");	
		logCat.debug("測試 debug");

		logCat.warn("%d + %d == %s ?", 1, 1, "two");

		logCat << log4cpp::Priority::ERROR << "Streamed root error";
		logCat << log4cpp::Priority::INFO << "Streamed root info";

		logCat.errorStream() << "Another streamed error";
		logCat.debugStream() << "Another streamed debug";
	}

	// 關閉日志
	log4cpp::Category::shutdown();

	return 0;
}

編譯:

g++ test_log4cpp.cpp -I ./inlcude/ -L ./lib/  -llog4cpp1 -lpthread -o test_log4cpp

log4cpp1:是log4cpp.a靜態(tài)庫,我將名字改成這樣(在上圖中可以看到),才可以正常鏈接到靜態(tài)庫;不知道為什么,鏈接動態(tài)庫.so,編譯會報錯,所以只能鏈接靜態(tài)庫去完成編譯運行。

-I:指定頭文件路徑,可以使用相對路徑
-L:指定庫的路徑,可以使用相對路徑

四、log4cpp項目用法

以下介紹的項目用法,Linux和Window環(huán)境均可使用! 

一般來說,日志都是由獨立的文件夾去保存的,下面為了方便就直接將日志保存在main函數同級目錄了。 

1. 配置文件使用log4cpp

新建項目,在項目路徑下新建文件名為:log.conf

粘貼以下配置到log.conf文件中

#定義Root category的屬性
log4cpp.rootCategory=DEBUG, RootLog     # 優(yōu)先級, 當前日志代表變量名

#定義RootLog屬性
#log4cpp.appender.RootLog = FileAppender           # 輸出到文件
log4cpp.appender.RootLog = RollingFileAppender    # 回卷
log4cpp.appender.RootLog.layout = PatternLayout   # 自定義輸出日志格式

# 日志輸出格式
log4cpp.appender.RootLog.layout.ConversionPattern = %d{%Y-%m-%d %H:%M:%S.%l} [%t][%p] %m%n 

# 日志名
log4cpp.appender.RootLog.fileName = ./test.log

# 單個日志文件大小
log4cpp.appender.RootLog.maxFileSize = 268435456 #256MB

# 回卷日志個數名
log4cpp.appender.RootLog.fileNamePattern = test_%i.log

# 日志個數
log4cpp.appender.RootLog.maxBackupIndex = 256

# append=true 信息追加到上面指定的日志文件中,false表示將信息覆蓋指定文件內容
log4cpp.appender.RootLog.append = true

在項目中新建文件MyLogger.h

#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;	// 通過此對象可以實現(xiàn)日志寫入
};

/* 宏定義,方便調用 */
#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

在項目中新建文件MyLogger.cpp

#include "MyLogger.h"

#include <iostream>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/PropertyConfigurator.hh>


// 靜態(tài)變量,需要在類外部初始化一下
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編譯命令:(鏈接的是靜態(tài)庫)

g++ main.cpp MyLogger.h MyLogger.cpp -std=c++11 -I ./inlcude/ -L ./lib/  -llog4cpp1 -lpthread -o test_log4cpp

2. 純代碼使用log4cpp

網上找的代碼,感覺挺不錯的,拷貝過來做了修改,改成自己以后做項目可能會這樣使用! 

MyLog.h

#ifndef _MY_LOG_H_
#define _MY_LOG_H_

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

#include <string>


// 優(yōu)先級
#define COUNT_PRITY			log4cpp::Priority::INFO;		// 控制臺
#define LOG_PRITY			log4cpp::Priority::DEBUG;		// 本地文件


/*采用單例模式設計,包含兩個category對象,一個負責輸出到屏幕的信息,一個負責記錄到日志的信息,
通過設置優(yōu)先級差別,可以實現(xiàn)所有信息都記錄在日志中,遇到error及以上的信息時打印到屏幕上*/
class MyLog {
private:
	MyLog(bool b) {
		outToScreen = b;
	}
	~MyLog() {}
	static MyLog * log;
	bool outToScreen;//是否輸出日志信息到屏幕
	static std::string _screenInfo;//屏幕日志信息
	static std::string _logName;//文件日志名稱

	static log4cpp::Category& logCat;
	static log4cpp::Category& coutCat;

	static log4cpp::FileAppender* logFile;//文件日志輸入
	static log4cpp::OstreamAppender* logScreen;//屏幕日志輸入
	static log4cpp::RollingFileAppender *rollLogFile;	/* 回卷用這個 */

	static log4cpp::Priority::PriorityLevel logPri;//文件日志優(yōu)先級
	static log4cpp::Priority::PriorityLevel coutPri;//屏幕日志優(yōu)先級

	static log4cpp::PatternLayout* logLayout;//日志布局 
	static log4cpp::PatternLayout* screenLayout;//屏幕布局 
	static log4cpp::PatternLayout* logLayout2;	/* 回卷用這個 */

private:
	// 返回當前年月日時分秒
	static std::string getCurrentTime(std::string& year, std::string& month, std::string& day, std::string& hour, std::string& min, std::string& sec);

public:
	// 初始化日志配置信息
	static bool init(std::string logName = "time", bool toScreen = false);
	//獲取日志函數,默認參數選擇是否輸出到屏幕
	static MyLog* getLog(bool toScreen = false);
	//銷毀日志對象
	static void destoryLog();
	//設置日志記錄優(yōu)先級
	static void setPri(log4cpp::Priority::PriorityLevel coutLevel, log4cpp::Priority::PriorityLevel logLevel);
	//記錄日志,調用參數 __LINE__ ,__FUNCTION__
	void warn(const char * msg, int line = __LINE__, const char *function = "warn");
	void error(const char * msg, int line = __LINE__, const char *function = "error");
	void debug(const char * msg, int line = __LINE__, const char *function = "debug");
	void info(const char * msg, int line = __LINE__, const char *function = "info");
};

//為避免每次調用都要填寫參數__LINE__和__FUNCTION__,可以使用帶參數的宏定義
#define  MyLogWARN(msg) MyLog::getLog()->warn(msg,__LINE__,__FUNCTION__);
#define  MyLogINFO(msg) MyLog::getLog()->info(msg,__LINE__,__FUNCTION__);
#define  MyLogERROR(msg) MyLog::getLog()->error(msg,__LINE__,__FUNCTION__);
#define  MyLogDEBUG(msg) MyLog::getLog()->debug(msg,__LINE__,__FUNCTION__);

#endif

MyLog.cpp

#include "MyLog.h"

#include <time.h>

MyLog* MyLog::log = NULL;
std::string MyLog::_screenInfo = "screenInfo";
std::string MyLog::_logName = "log";

log4cpp::Category& root = log4cpp::Category::getRoot();
log4cpp::Category& MyLog::logCat = root.getInstance(MyLog::_logName);
log4cpp::Category& MyLog::coutCat = root.getInstance(MyLog::_screenInfo);

// 優(yōu)先級
log4cpp::Priority::PriorityLevel MyLog::coutPri = COUNT_PRITY;		// 控制臺
log4cpp::Priority::PriorityLevel MyLog::logPri = LOG_PRITY;		// 本地文件

log4cpp::PatternLayout* MyLog::logLayout = NULL;
log4cpp::PatternLayout* MyLog::screenLayout = NULL;
log4cpp::PatternLayout* MyLog::logLayout2 = NULL;	/* 回卷用這個 */

log4cpp::FileAppender* MyLog::logFile = NULL;//文件日志輸入
log4cpp::OstreamAppender* MyLog::logScreen = NULL;//屏幕日志輸入
log4cpp::RollingFileAppender *MyLog::rollLogFile;	/* 回卷用這個 */

bool MyLog::init(std::string logName, bool toScreen) {

	// 判斷如果傳入文件名參數為空,或為默認參數,則使用當前年月日.log作為日志文件名
	if (logName.empty() || logName == "time") {
		std::string year, month, day, hour, min, sec;
		getCurrentTime(year, month, day, hour, min, sec);
		logName = year + month + day + ".log";
	}

	if (MyLog::log == NULL) {
		MyLog::log = new MyLog(toScreen);

		MyLog::_logName = logName;

		log4cpp::Category& logCat = root.getInstance(MyLog::_logName);
		log4cpp::Category& coutCat = root.getInstance(MyLog::_screenInfo);

		logScreen = new log4cpp::OstreamAppender("logScreen", &std::cout);
		logFile = new log4cpp::FileAppender("logFile", MyLog::_logName);								/* 然后注釋這個 */
		//rollLogFile = new log4cpp::RollingFileAppender("rollLogFile", MyLog::_logName, 1024*1024, 5);	/* 回卷用這個 */	// 單個日志文件大小1M,5個回卷


		//設置布局
		MyLog::logLayout = new log4cpp::PatternLayout();	/* 然后注釋這個 */
		MyLog::screenLayout = new log4cpp::PatternLayout();
		MyLog::logLayout2 = new log4cpp::PatternLayout();	/* 回卷用這個 */
		logLayout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S} [%p] %m%n");
		screenLayout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S} [%p] %m%n");
		logLayout2->setConversionPattern("%d{%Y-%m-%d %H:%M:%S} [%p] %m%n");
		MyLog::logScreen->setLayout(screenLayout);
		MyLog::logFile->setLayout(logLayout);			/* 然后注釋這個 */
		//MyLog::rollLogFile->setLayout(logLayout2);	/* 回卷用這個 */


		//追加到目錄	
		MyLog::logCat.addAppender(MyLog::logFile);			/* 然后注釋這個 */
		//MyLog::logCat.addAppender(MyLog::rollLogFile);	/* 回卷用這個 */
		MyLog::coutCat.addAppender(MyLog::logScreen);
		
		//設置優(yōu)先級
		MyLog::logCat.setPriority(MyLog::logPri);
		MyLog::coutCat.setPriority(MyLog::coutPri);
	}
	MyLog::log->outToScreen = toScreen;


	return true;
}

//獲取日志函數,默認參數選擇是否輸出到屏幕
MyLog* MyLog::getLog(bool toScreen) {
	MyLog::log->outToScreen = toScreen;

	if (NULL == MyLog::log) {
		printf("MyLog::log is NULL, please use MyLog::init!\n");
		return NULL;
	}

	return MyLog::log;
}
//銷毀日志對象
void MyLog::destoryLog() {
	log4cpp::Category::shutdown();
	delete MyLog::log;
}
//設置日志記錄優(yōu)先級
void MyLog::setPri(log4cpp::Priority::PriorityLevel coutLevel, log4cpp::Priority::PriorityLevel logLevel) {
	MyLog::logPri = logLevel;
	MyLog::coutPri = coutLevel;
	MyLog::logCat.setPriority(MyLog::logPri);
	MyLog::coutCat.setPriority(MyLog::coutPri);
}
//記錄日志,調用參數__FILE__, __LINE__ ,__FUNCTION__
void MyLog::warn(const char * msg, int line, const char *function) {
	char info[4096] = { 0 };
	sprintf(info, "[%s][%d]: %s", function, line, msg);
	if (this->outToScreen) {
		logCat.warn(info);
		coutCat.warn(info);
	} else {
		logCat.warn(info);
	}
}
void MyLog::error(const char * msg, int line, const char *function) {
	char info[4096] = { 0 };
	sprintf(info, "[%s][%d]: %s", function, line, msg);
	if (this->outToScreen) {
		logCat.error(info);
		coutCat.error(info);
	} else {
		logCat.error(info);
	}
}
void MyLog::debug(const char * msg, int line, const char *function) {
	char info[4096] = { 0 };
	sprintf(info, "[%s][%d]: %s", function, line, msg);
	if (this->outToScreen) {
		logCat.debug(info);
		coutCat.debug(info);
	} else {
		logCat.debug(info);
	}
}
void MyLog::info(const char * msg, int line, const char *function) {
	char info[4096] = { 0 };
	sprintf(info, "[%s][%d]: %s", function, line, msg);

	if (this->outToScreen) {
		logCat.info(info);
		coutCat.info(info);
	} else {
		logCat.info(info);
	}
}

std::string MyLog::getCurrentTime(std::string& year, std::string& month, std::string& day, std::string& hour, std::string& min, std::string& sec) {
	// 獲取系統(tǒng)時間 - 年月日時分秒
	time_t _time;
	struct tm* target_time;
	time(&_time);
	target_time = localtime(&_time);


	year = std::to_string(target_time->tm_year + 1900);
	month = target_time->tm_mon + 1 > 9 ? std::to_string(target_time->tm_mon + 1) : "0" + std::to_string(target_time->tm_mon + 1);
	day = target_time->tm_mday > 9 ? std::to_string(target_time->tm_mday) : "0" + std::to_string(target_time->tm_mday);
	hour = target_time->tm_hour > 9 ? std::to_string(target_time->tm_hour) : "0" + std::to_string(target_time->tm_hour);
	min = target_time->tm_min > 9 ? std::to_string(target_time->tm_min) : "0" + std::to_string(target_time->tm_min);
	sec = target_time->tm_sec > 9 ? std::to_string(target_time->tm_sec) : "0" + std::to_string(target_time->tm_sec);

	return year + month + day + hour + min + sec;
}

main函數測試

#include "MyLog.h"


int main(void) {

	if (!MyLog::init("")) {
		fprintf(stderr, "init log module failed.\n");
		return -1;
	}

	MyLogWARN("警告");
	MyLogINFO("信息");
	MyLogERROR("錯誤");
	MyLogDEBUG("調試");
	
    // 關閉日志
	log4cpp::Category::shutdown();

	return 0;
}

運行結果:

Linux編譯命令:(鏈接的是靜態(tài)庫)

g++ main.cpp MyLog.h MyLog.cpp -std=c++11 -I ./inlcude/ -L ./lib/  -llog4cpp1 -lpthread -o test_log4cpp

五、總結

日志在項目中是必須使用的,如果看完此篇博客還是不太懂log4cpp日志如何使用,直接拷貝上面項目代碼去到自己的項目中就可以直接使用了!

到此這篇關于C++ Log4cpp跨平臺日志庫使用記錄(Window與Linux)的文章就介紹到這了,更多相關C++ Log4cpp內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 基于easyx的C++實現(xiàn)貪吃蛇

    基于easyx的C++實現(xiàn)貪吃蛇

    這篇文章主要為大家詳細介紹了基于easyx的C++實現(xiàn)貪吃蛇,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • Qt音視頻開發(fā)之音頻播放QAudioOutput的實現(xiàn)

    Qt音視頻開發(fā)之音頻播放QAudioOutput的實現(xiàn)

    這篇文章主要為大家詳細介紹了如何利用Qt實現(xiàn)音頻播放QAudioOutput功能,文中的示例代碼講解詳細,對我們學習Qt開發(fā)有一定的幫助,需要的可以參考一下
    2023-03-03
  • 深入淺析STL vector用法

    深入淺析STL vector用法

    這篇文章給大家介紹 stl vector用法,主要知識點在如何恰當的使用它們的成員函數,涉及到條件函數和函數指針在迭代算法中的使用,對stl vector用法感興趣的朋友可以參考下本文
    2015-10-10
  • C語言字母轉換大小寫的3種方法圖文詳解

    C語言字母轉換大小寫的3種方法圖文詳解

    我們在C語言入門的時候都會遇到要求寫大小寫轉換的題目,所以下面這篇文章主要給大家介紹了關于C語言字母轉換大小寫的3種方法,文中給了詳細的代碼示例,需要的朋友可以參考下
    2023-10-10
  • C語言 語義陷阱超詳細梳理總結

    C語言 語義陷阱超詳細梳理總結

    這篇文章主要介紹了C語言常見的一些語義陷阱,梳理的比較全面,對我們做開發(fā)的過程中有一定幫助,感興趣的朋友快來看看吧
    2022-03-03
  • C++?BoostAsyncSocket實現(xiàn)異步反彈通信的案例詳解

    C++?BoostAsyncSocket實現(xiàn)異步反彈通信的案例詳解

    這篇文章主要為大家詳細介紹了C++?BoostAsyncSocket如何實現(xiàn)異步反彈通信,文中的示例代碼講解詳細,具有一定的學習價值,感興趣的可以了解一下
    2023-03-03
  • C語言求解無向圖頂點之間的所有最短路徑

    C語言求解無向圖頂點之間的所有最短路徑

    這篇文章主要為大家詳細介紹了C語言求解無向圖頂點之間的所有最短路徑,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C++編程模板匹配超詳細的識別手寫數字實現(xiàn)示例

    C++編程模板匹配超詳細的識別手寫數字實現(xiàn)示例

    大家好!本篇文章是關于手寫數字識別的,接下來我將在這里記錄我的手寫數字識別的從零到有,我在這里把我自己的寫代碼過程發(fā)出來,希望能幫到和我一樣努力求知的人
    2021-10-10
  • C++11/14 線程調用類對象和線程傳參的方法

    C++11/14 線程調用類對象和線程傳參的方法

    這篇文章主要介紹了C++11/14 線程調用類對象和線程傳參的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • 深入理解C++的多態(tài)性

    深入理解C++的多態(tài)性

    本篇文章是對C++的多態(tài)性進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05

最新評論