C++ Log4cpp跨平台日志库使用记录(Window与Linux)
介绍log4cpp的项目用法,将在项目中常用的用法代码写下来分享!
项目中,最重要的模块之一就是日志了,今天这篇博客记录项目中log4cpp的用法!
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 // 发送到缺省系统调试器
log4cpp::NTEventLogAppender // 发送到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 - 优先级;
- %r - 该布局创建后的毫秒数;
- %R - 从1970年1月1日0时开始到目前为止的秒数;
- %u - 进程开始到目前为止的时钟周期数;
- %x - the NDC;
- %t - 线程的名字;
- 默认情况下,PatternLayout的ConversionPattern设置为“%m%n”。
3. 设置日志的输出优先级
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官网:
下载后解压进入msvc10
因为官方提供的是vs2010编译的项目,所以根据自己电脑装的vs去打开即可,例如我这里使用vs2017去打开,打开后会提示升级,升级即可。
2. 编译
3. 报错解决1
不出意外的话,会报错。
解决方法:①在log4cpp项目工程中找到NTEventLogCategories.mc文件,选择该文件上然后右键选择属性,在弹出窗口中找到“配置属性 - 自定义生成工具 - 常规 - 命令行”中修改编译命令,设置为如下命令:
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进行了重新实现,visual studio的c库对snprintf也有实现,windows中在链接时会报snprintf函数冲突,所以需要设置log4cpp的预编译项,选择使用visual stuido中c库的实现,在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";
// 优先级
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);
//设置优先级
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系统中!
或者根据自己系统的特性,使用下面链接去下载,
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* 进入文件夹
然后执行 ./configure
然后执行 make
然后执行 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.* 自己的项目路径 拷贝到自己的项目路径中去;例如,我会在项目路径中创建一个lib文件夹,将刚刚安装的log4cpp库拷贝到此文件夹中
log4cpp头文件路径在 /usr/local/include/log4cpp
可以使用命令 mv -if /usr/local/include/log4cpp 自己的项目路径 拷贝到自己的项目路径中去;例如,我会在项目路径中创建一个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";
// 优先级
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);
//设置优先级
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静态库,我将名字改成这样(在上图中可以看到),才可以正常链接到静态库;不知道为什么,链接动态库.so,编译会报错,所以只能链接静态库去完成编译运行。
-I:指定头文件路径,可以使用相对路径
-L:指定库的路径,可以使用相对路径
四、log4cpp项目用法
以下介绍的项目用法,Linux和Window环境均可使用!
一般来说,日志都是由独立的文件夹去保存的,下面为了方便就直接将日志保存在main函数同级目录了。
1. 配置文件使用log4cpp
新建项目,在项目路径下新建文件名为:log.conf
粘贴以下配置到log.conf文件中
#定义Root category的属性
log4cpp.rootCategory=DEBUG, RootLog # 优先级, 当前日志代表变量名
#定义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; // 通过此对象可以实现日志写入
};
/* 宏定义,方便调用 */
#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>
// 静态变量,需要在类外部初始化一下
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编译命令:(链接的是静态库)
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>
// 优先级
#define COUNT_PRITY log4cpp::Priority::INFO; // 控制台
#define LOG_PRITY log4cpp::Priority::DEBUG; // 本地文件
/*采用单例模式设计,包含两个category对象,一个负责输出到屏幕的信息,一个负责记录到日志的信息,
通过设置优先级差别,可以实现所有信息都记录在日志中,遇到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;//文件日志优先级
static log4cpp::Priority::PriorityLevel coutPri;//屏幕日志优先级
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();
//设置日志记录优先级
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);
// 优先级
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);
//设置优先级
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;
}
//设置日志记录优先级
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) {
// 获取系统时间 - 年月日时分秒
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编译命令:(链接的是静态库)
g++ main.cpp MyLog.h MyLog.cpp -std=c++11 -I ./inlcude/ -L ./lib/ -llog4cpp1 -lpthread -o test_log4cpp
五、总结
日志在项目中是必须使用的,如果看完此篇博客还是不太懂log4cpp日志如何使用,直接拷贝上面项目代码去到自己的项目中就可以直接使用了!
更多推荐
所有评论(0)