网站建设审批程序杭州前十强装修公司有哪几家
2026/4/12 10:17:23 网站建设 项目流程
网站建设审批程序,杭州前十强装修公司有哪几家,长沙网站开,手机端官网设计文章目录 1、前言2、归纳3、典型3.1、qInstallMessageHandler3.1.1、简介3.1.2、示例3.1.3、思路3.1.4、使用3.1.5、案例 3.2、Glog3.2.1、语法3.2.2、下载3.2.3、配置3.2.4、使用3.2.5、相关 3.3、Easylogging3.3.1、要领3.3.2、兼容3.3.3、注意3.3.4、示例 1、前言 最近有…文章目录1、前言2、归纳3、典型3.1、qInstallMessageHandler3.1.1、简介3.1.2、示例3.1.3、思路3.1.4、使用3.1.5、案例3.2、Glog3.2.1、语法3.2.2、下载3.2.3、配置3.2.4、使用3.2.5、相关3.3、Easylogging3.3.1、要领3.3.2、兼容3.3.3、注意3.3.4、示例1、前言最近有时间研究下C 的记录日志的方法包括各个方法的简述、使用特点、适用场景、推荐指数等。本文调研常见的18 种记录日志方法包含qInstallMessageHandler、Glog、Easylogging、Qslog、Log4qt、Log4cpp、Log4cxx、Log4c、Log4cplus、Pantheios POCO、ACE、Boost.Log、G3log、Plog、spdlog、Rsyslog等后续添加了笔者最推荐的3种典型方法的要领思路、使用方法和示例等倾注了很多精力。希望此文不要沉底请多多支持谢谢~2、归纳序号名称简述使用特点适用场景官网最新更新推荐指数1qInstallMessageHandlerQt 亲儿子可安装自定义的日志输出处理函数把日志输出到文件控制台等可查看 Qt 的帮助文档。Release 版本默认不包含文件名、函数名和行数信息需要在 .pro 文件中加入代码。Qt5.0 及以上版本 跨平台开发场景地址随 Qt 不断升级⭐⭐⭐⭐⭐2Glog谷歌 亲儿子一个 C 语言的应用级日志记录框架提供了 C 风格的流操作和各种辅助宏常常与Breakpad结合跨平台使用地址2022-04-05⭐⭐⭐⭐⭐3Easylogging巨简单。轻量级高性能 C 日志库只需要一个头文件无需任何外部依赖。支持文件配置提供了强大的自定义日志格式的能力还提供对第三方库STL容器的支持几乎所有主流平台和编译器都支持地址2023-07-20⭐⭐⭐⭐4Log4cplus一个基于 Log4j简单易用的 C 日志记录 API提供了对日志管理和配置的线程安全、灵活和任意粒度控制使用 C 跨平台开发场景地址2023-11-17⭐⭐⭐⭐5Qslog基于Qt的轻量级开源日志库使用Qt的QDebug类的易于使用的记录器。QsLog是在麻省理工学院许可下以开源形式发布的适用于Qt的多库集成场景地址2023-06-21⭐⭐⭐⭐6Log4cppLGPL的开源项目是基于 Log4j的 C 类库可以灵活地记录到文件、syslog、IDSA 和其他目的地适用 C 跨平台开发场景地址2023-03-12⭐⭐⭐7Pantheios号称 C/C 领域速度最快的程序诊断日志库一类型安全、高效、泛型和可扩展性的 C 日志 API 库适用于对速度有特别追求的场景地址2020-07-05⭐⭐⭐8PlogPlog 是一个 C 日志库其设计尽可能简单、小巧且灵活非常小。它是作为现有大型库的替代方案而创建的并提供一些独特的功能如CSV 日志格式和宽字符串支持适用于对系统空间有要求的场景地址2023-08-20⭐⭐⭐9RsyslogLinux原生日志系统Rsyslog可用于接受来自各种来源的输入做处理后将结果输出到不同的目的地适用于纯Linux场景地址2023-02-13⭐⭐⭐10ACE是一个很强大的跨平台的网络通信中间件ACE日志输出的本身格式很类似log4cpp的日志格式适用于中间件跨平台场景地址2023-12-14⭐⭐⭐11spdlog主打高性能与易用性。一个快速的 C 日志库只包含头文件是一个高速异步日志库支持多线程和旋转文件日志适用于高负载的系统地址2023-07-09⭐⭐⭐12G3log一个开源、支持跨平台的异步 C 日志框架支持自定义日志格式。基于 g2log 构建提升了性能支持自定义格式适用于对日志记录格式有特别要求的场景地址2023-12-07⭐⭐⭐13Log4qt用Trolltech Qt Framework的Apache Software Foundation Log4j包的C 端口它旨在供开源和商业Qt项目使用适用于老版本Qt4地址2009-03-01⭐⭐14Poco.Log提供了好的日志支持文档。Poco库借助了C库强大的网络和系统支持易于集成到其他应用程序中支持多个日志记录器和过滤器适用于服务端和客户端的日志模块地址2023-12-05⭐⭐15Log4c基本上都是一些纯c的东西移植性比Log4cxx、Log4cpp要好使用 C 较多的场景地址2016-01-30⭐⭐16log.cC 语言的日志功能模块代码简洁就一个 .c 和 .h 文件一共 200 行设计优雅使用 C 较多的场景地址2016-01-30⭐⭐17Boost.Log由Boost库提供的日志记录工具支持多个不同的后端日志器可以定制多种记录格式适用于任何Boost项目地址2023-12-14⭐18Log4cxxJava 社区著名的 Log4j 的 C 移植版用于为 C 程序提供日志功能以便开发者对目标程序进行调试和审计需要依赖于APR不能和Qt的qDebug和qInfo等联调适用于仅在Linux的Apache环境项目地址2023-05-01⭐3、典型3.1、qInstallMessageHandler3.1.1、简介qInstallMessageHandler 位于 - Global Qt Declarations下边属于全局函数。QtMessageHandlerqInstallMessageHandler(QtMessageHandler handler)qInstallMessageHandler 的作用 主要是是对 打印消息的控制能控制打印的输出调试信息警告严重致命错误等五个等级。Installs a Qt message handler which has been defined previously. Returns a pointer to the previous message handler.The message handler is a function that prints out debug messages, warnings, critical and fatal error messages. The Qt library (debug mode) contains hundreds of warning messages that are printed when internal errors (usually invalid function arguments) occur. Qt built in release mode also contains such warnings unless QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during compilation. If you implement your own message handler, you get total control of these messages.The default message handler prints the message to the standard output under X11 or to the debugger under Windows. If it is a fatal message, the application aborts immediately.Only one message handler can be defined, since this is usually done on an application-wide basis to control debug output.To restore the message handler, call qInstallMessageHandler(0).3.1.2、示例官方示例#includeqapplication.h#includestdio.h#includestdlib.hvoidmyMessageOutput(QtMsgType type,constQMessageLogContextcontext,constQStringmsg){QByteArray localMsgmsg.toLocal8Bit();switch(type){caseQtDebugMsg:fprintf(stderr,Debug: %s (%s:%u, %s)\n,localMsg.constData(),context.file,context.line,context.function);break;caseQtInfoMsg:fprintf(stderr,Info: %s (%s:%u, %s)\n,localMsg.constData(),context.file,context.line,context.function);break;caseQtWarningMsg:fprintf(stderr,Warning: %s (%s:%u, %s)\n,localMsg.constData(),context.file,context.line,context.function);break;caseQtCriticalMsg:fprintf(stderr,Critical: %s (%s:%u, %s)\n,localMsg.constData(),context.file,context.line,context.function);break;caseQtFatalMsg:fprintf(stderr,Fatal: %s (%s:%u, %s)\n,localMsg.constData(),context.file,context.line,context.function);abort();}}intmain(intargc,char**argv){qInstallMessageHandler(myMessageOutput);QApplicationapp(argc,argv);...returnapp.exec();}3.1.3、思路读取日志配置文件设置文件输出等级可以用做在正式项目中调试与日常关键信息打印。Log消息输出方法–输出文本。消息模块注册3.1.4、使用枚举变量–设置日志等级 0~4 5个等级enum{Fatal0,Critical,Warning,Info,Debug}LogLeaver;intLogType4;//日志等级初始化设置//初始化读取配置文件voidReadLogInit(){QFilefile(./log_conf.ini);if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){//判断文件是否可执行return;}while(!file.atEnd()){QByteArray strBuffile.readLine();if(strBuf[LOG_CONFIG]\n){strBuffile.readLine();LogTypestrBuf.mid(strBuf.size()-1,1).toInt();}}}//配置文件格式[LOG_CONFIG]LogLeaver4voidmessage_output(QtMsgType type,constQMessageLogContextcontext,constQStringmsg){//加锁避免对文件的同时读写staticQMutex mutex;mutex.lock();//读写消息QByteArray localMsgmsg.toLocal8Bit();//输出的字符串QString strOutStream;//case 生成要求格式日志文件加日志等级过滤switch(type){caseQtDebugMsg:if(LogTypeDebug){strOutStreamQString(%1 %2 %3 %4 [Debug] %5 \n).arg(QDateTime::currentDateTime().toString(yyyy-MM-dd hh:mm:ss)).arg(QString(context.file)).arg(context.line).arg(QString(context.function)).arg(QString(localMsg));}break;caseQtInfoMsg:if(LogTypeInfo){strOutStreamQString(%1 %2 %3 %4 [Info]: %5 \n).arg(QDateTime::currentDateTime().toString(yyyy-MM-dd hh:mm:ss)).arg(QString(context.file)).arg(context.line).arg(QString(context.function)).arg(QString(localMsg));}break;caseQtWarningMsg:if(LogTypeWarning){strOutStreamQString(%1 %2 %3 %4 [Warning]: %5 \n).arg(QDateTime::currentDateTime().toString(yyyy-MM-dd hh:mm:ss)).arg(QString(context.file)).arg(context.line).arg(QString(context.function)).arg(QString(localMsg));}break;caseQtCriticalMsg:if(LogTypeCritical){strOutStreamQString(%1 %2 %3 %4 [Critical]: %5 \n).arg(QDateTime::currentDateTime().toString(yyyy-MM-dd hh:mm:ss)).arg(QString(context.file)).arg(context.line).arg(QString(context.function)).arg(QString(localMsg));}break;caseQtFatalMsg:if(LogTypeFatal){strOutStreamQString(%1 %2 %3 %4 [Fatal]: %5 \n).arg(QDateTime::currentDateTime().toString(yyyy-MM-dd hh:mm:ss)).arg(QString(context.file)).arg(context.line).arg(QString(context.function)).arg(QString(localMsg));}abort();}//每天生成一个新的log日志文件文件名 yyyyMMdd.txtQString strFileNameQString(%1.txt).arg(QDateTime::currentDateTime().date().toString(yyyyMMdd));QFilelogfile(strFileName);logfile.open(QIODevice::WriteOnly|QIODevice::Append);if(strOutStream!){QTextStreamlogStream(logfile);logStreamstrOutStream\r\n;}//清楚缓存文件解锁logfile.flush();logfile.close();mutex.unlock();}intmain(intargc,char*argv[]){ReadLogInit();//读取日志等级qInstallMessageHandler(message_output);//安装消息处理函数依靠回调函数重定向全局处理QApplicationa(argc,argv);qInfo()\r\n\r\n\r\n**start**;//to doing......}3.1.5、案例开源社区日志工具类LogHandler调用 qDebug() “Hi”输出的内容会同时输出到日志文件和控制台并且日志文件如果不是当天创建的会使用它的创建日期备份起来单个日志文件例如大于 5M 后重新创建一个新的日志文件删除超过 30 天的日志使用锁确保多线程安全。涉及到的文件有main.cpp: 使用示例LogHandler.h: 自定义日志相关类的头文件LogHandler.cpp: 自定义日志相关类的实现文件LogHandler.h:#ifndefLOGHANDLER_H#defineLOGHANDLER_H#includeiostream#includeQDebug#includeQDateTime#includeQMutexLocker#includeQDir#includeQFile#includeQFileInfo#includeQTimer#includeQTextStream#includeQTextCodecconstintg_logLimitSize5;structLogHandlerPrivate{LogHandlerPrivate();~LogHandlerPrivate();// 打开日志文件 log.txt如果日志文件不是当天创建的则使用创建日期把其重命名为 yyyy-MM-dd.log并重新创建一个 log.txtvoidopenAndBackupLogFile();voidcheckLogFiles();// 检测当前日志文件大小voidautoDeleteLog();// 自动删除30天前的日志// 消息处理函数staticvoidmessageHandler(QtMsgType type,constQMessageLogContextcontext,constQStringmsg);QDir logDir;// 日志文件夹QTimer renameLogFileTimer;// 重命名日志文件使用的定时器QTimer flushLogFileTimer;// 刷新输出到日志文件的定时器QDate logFileCreatedDate;// 日志文件创建的时间staticQFile*logFile;// 日志文件staticQTextStream*logOut;// 输出日志的 QTextStream使用静态对象就是为了减少函数调用的开销staticQMutex logMutex;// 同步使用的 mutex};classLogHandler{public:voidinstallMessageHandler();// 给Qt安装消息处理函数voiduninstallMessageHandler();// 取消安装消息处理函数并释放资源staticLogHandlerGet(){staticLogHandler m_logHandler;returnm_logHandler;}private:LogHandler();LogHandlerPrivate*d;};#endif// LOGHANDLER_HLogHandler.cpp#includeLogHandler.h/************************************************************************************************************ * LogHandlerPrivate * ***********************************************************************************************************/// 初始化 static 变量QMutex LogHandlerPrivate::logMutex;QFile*LogHandlerPrivate::logFilenullptr;QTextStream*LogHandlerPrivate::logOutnullptr;LogHandlerPrivate::LogHandlerPrivate(){logDir.setPath(log);// TODO: 日志文件夹的路径为 exe 所在目录下的 log 文件夹可从配置文件读取QString logPathlogDir.absoluteFilePath(today.log);// 获取日志的路径// 获取日志文件创建的时间// QFileInfo::created(): On most Unix systems, this function returns the time of the last status change.// 所以不能运行时使用这个函数检查创建时间因为会在运行时变化于是在程序启动时保存下日志文件的最后修改时间logFileCreatedDateQFileInfo(logPath).lastModified().date();// 若日志文件不存在返回nullptr// 打开日志文件如果不是当天创建的备份已有日志文件openAndBackupLogFile();// 十分钟检查一次日志文件创建时间renameLogFileTimer.setInterval(1000*2);// TODO: 可从配置文件读取renameLogFileTimer.start();QObject::connect(renameLogFileTimer,QTimer::timeout,[this]{QMutexLockerlocker(LogHandlerPrivate::logMutex);openAndBackupLogFile();// 打开日志文件checkLogFiles();// 检测当前日志文件大小autoDeleteLog();// 自动删除30天前的日志});// 定时刷新日志输出到文件尽快的能在日志文件里看到最新的日志flushLogFileTimer.setInterval(1000);// TODO: 可从配置文件读取flushLogFileTimer.start();QObject::connect(flushLogFileTimer,QTimer::timeout,[]{// qDebug() QDateTime::currentDateTime().toString(yyyy-MM-dd hh:mm:ss); // 测试不停的写入内容到日志文件QMutexLockerlocker(LogHandlerPrivate::logMutex);if(nullptr!logOut){logOut-flush();}});}LogHandlerPrivate::~LogHandlerPrivate(){if(nullptr!logFile){logFile-flush();logFile-close();deletelogOut;deletelogFile;// 因为他们是 static 变量logOutnullptr;logFilenullptr;}}// 打开日志文件 log.txt如果不是当天创建的则使用创建日期把其重命名为 yyyy-MM-dd.log并重新创建一个 log.txtvoidLogHandlerPrivate::openAndBackupLogFile(){// 总体逻辑:// 1. 程序启动时 logFile 为 nullptr初始化 logFile有可能是同一天打开已经存在的 logFile所以使用 Append 模式// 2. logFileCreatedDate is nullptr, 说明日志文件在程序开始时不存在所以记录下创建时间// 3. 程序运行时检查如果 logFile 的创建日期和当前日期不相等则使用它的创建日期重命名然后再生成一个新的 log.txt 文件// 4. 检查日志文件超过 LOGLIMIT_NUM 个删除最早的// 备注log.txt 始终为当天的日志文件当第二天会执行第3步将使用 log.txt 的创建日期重命名它// 如果日志所在目录不存在则创建if(!logDir.exists()){logDir.mkpath(.);// 可以递归的创建文件夹}QString logPathlogDir.absoluteFilePath(today.log);// log.txt的路径// [[1]] 程序每次启动时 logFile 为 nullptrif(logFilenullptr){logFilenewQFile(logPath);logOut(logFile-open(QIODevice::WriteOnly|QIODevice::Text|QIODevice::Append))?newQTextStream(logFile):nullptr;if(logOut!nullptr)logOut-setCodec(UTF-8);// [[2]] 如果文件是第一次创建则创建日期是无效的把其设置为当前日期if(logFileCreatedDate.isNull()){logFileCreatedDateQDate::currentDate();}}// [[3]] 程序运行时如果创建日期不是当前日期则使用创建日期重命名并生成一个新的 log.txtif(logFileCreatedDate!QDate::currentDate()){logFile-flush();logFile-close();deletelogOut;deletelogFile;QString newLogPathlogDir.absoluteFilePath(logFileCreatedDate.toString(yyyy-MM-dd.log));;QFile::copy(logPath,newLogPath);// Bug: 按理说 rename 会更合适但是 rename 时最后一个文件总是显示不出来需要 killall Finder 后才出现QFile::remove(logPath);// 删除重新创建改变创建时间// 重新创建 log.txtlogFilenewQFile(logPath);logOut(logFile-open(QIODevice::WriteOnly|QIODevice::Text|QIODevice::Truncate))?newQTextStream(logFile):nullptr;logFileCreatedDateQDate::currentDate();if(logOut!nullptr)logOut-setCodec(UTF-8);}}// 检测当前日志文件大小voidLogHandlerPrivate::checkLogFiles(){// 如果 protocal.log 文件大小超过5M重新创建一个日志文件原文件存档为yyyy-MM-dd_hhmmss.logif(logFile-size()1024*g_logLimitSize){logFile-flush();logFile-close();deletelogOut;deletelogFile;QString logPathlogDir.absoluteFilePath(today.log);// 日志的路径QString newLogPathlogDir.absoluteFilePath(logFileCreatedDate.toString(yyyy-MM-dd.log));QFile::copy(logPath,newLogPath);// Bug: 按理说 rename 会更合适但是 rename 时最后一个文件总是显示不出来需要 killall Finder 后才出现QFile::remove(logPath);// 删除重新创建改变创建时间logFilenewQFile(logPath);logOut(logFile-open(QIODevice::WriteOnly|QIODevice::Text|QIODevice::Truncate))?newQTextStream(logFile):NULL;logFileCreatedDateQDate::currentDate();if(logOut!nullptr)logOut-setCodec(UTF-8);}}// 自动删除30天前的日志voidLogHandlerPrivate::autoDeleteLog(){QDateTime nowQDateTime::currentDateTime();// 前30天QDateTime dateTime1now.addDays(-30);QDateTime dateTime2;QString logPathlogDir.absoluteFilePath(today.log);// 日志的路径QDirdir(logPath);QFileInfoList fileListdir.entryInfoList();foreach(QFileInfo f,fileList){// .和..跳过if(f.baseName())continue;dateTime2QDateTime::fromString(f.baseName(),yyyy-MM-dd);if(dateTime2dateTime1){// 只要日志时间小于前30天的时间就删除dir.remove(f.absoluteFilePath());}}}// 消息处理函数voidLogHandlerPrivate::messageHandler(QtMsgType type,constQMessageLogContextcontext,constQStringmsg){QMutexLockerlocker(LogHandlerPrivate::logMutex);QString level;switch(type){caseQtDebugMsg:levelDEBUG;break;caseQtInfoMsg:levelINFO ;break;caseQtWarningMsg:levelWARN ;break;caseQtCriticalMsg:levelERROR;break;caseQtFatalMsg:levelFATAL;break;default:break;}// 输出到标准输出: Windows 下 std::cout 使用 GB2312而 msg 使用 UTF-8但是程序的 Local 也还是使用 UTF-8#ifdefined(Q_OS_WIN)QByteArray localMsgQTextCodec::codecForName(GB2312)-fromUnicode(msg);//msg.toLocal8Bit();#elseQByteArray localMsgmsg.toLocal8Bit();#endifstd::coutstd::string(localMsg)std::endl;if(nullptrLogHandlerPrivate::logOut){return;}// 输出到日志文件, 格式: 时间 - [Level] (文件名:行数, 函数): 消息QString fileNamecontext.file;intindexfileName.lastIndexOf(QDir::separator());fileNamefileName.mid(index1);(*LogHandlerPrivate::logOut)QString(%1 - [%2] (%3:%4, %5): %6\n).arg(QDateTime::currentDateTime().toString(yyyy-MM-dd hh:mm:ss)).arg(level).arg(fileName).arg(context.line).arg(context.function).arg(msg);}/************************************************************************************************************ * LogHandler * ***********************************************************************************************************/LogHandler::LogHandler():d(nullptr){}// 给Qt安装消息处理函数voidLogHandler::installMessageHandler(){QMutexLockerlocker(LogHandlerPrivate::logMutex);// 类似C11的lock_guard析构时自动解锁if(nullptrd){dnewLogHandlerPrivate();qInstallMessageHandler(LogHandlerPrivate::messageHandler);// 给 Qt 安装自定义消息处理函数}}// 取消安装消息处理函数并释放资源voidLogHandler::uninstallMessageHandler(){QMutexLockerlocker(LogHandlerPrivate::logMutex);qInstallMessageHandler(nullptr);deleted;dnullptr;}main.cpp#includeLogHandler.h#includeQApplication#includeQDebug#includeQTime#includeQPushButtonintmain(intargc,char*argv[]){QApplicationapp(argc,argv);// [[1]] 安装消息处理函数LogHandler::Get().installMessageHandler();// [[2]] 输出测试查看是否写入到文件qDebug()Hello;qDebug()当前时间是: QTime::currentTime().toString(hh:mm:ss);qInfo()QString(God bless you!);QPushButton*buttonnewQPushButton(退出);button-show();QObject::connect(button,QPushButton::clicked,[app]{qDebug()退出;app.quit();});// [[3]] 取消安装自定义消息处理然后启用LogHandler::Get().uninstallMessageHandler();qDebug()........;// 不写入日志LogHandler::Get().installMessageHandler();intretapp.exec();// 事件循环结束// [[4]] 程序结束时释放 LogHandler 的资源例如刷新并关闭日志文件LogHandler::Get().uninstallMessageHandler();returnret;}运行效果Hello当前时间是: “16:29:42”“God bless you!”…退出日志文件exe 所在目录的 log 目录下的 log.txt16:29:42 - [Debug] (main.cpp:15, int main(int, char **)): Hello16:29:42 - [Debug] (main.cpp:16, int main(int, char **)): 当前时间是: “16:29:42”16:29:42 - [Info ] (main.cpp:17, int main(int, char **)): “God bless you!”16:29:46 - [Debug] (main.cpp:22, auto main(int, char **)::(anonymous class)::operator()() const): 退出注意Release 版本默认不包含文件名、函数名和行数信息需要在 .pro 文件中加入一行代码重新 make 运行后生效。DEFINESQT_MESSAGELOGCONTEXT3.2、Glog3.2.1、语法1、错误类型enumSeverityLevel{google::INFO0,google::WARNING1,google::ERROR2,google::FATAL3,};2、常用函数google::SetLogDestination(google::GLOG_INFO,log/prefix_);//设置特定严重级别的日志的输出目录和前缀。第一个参数为日志级别第二个参数表示输出目录及日志文件名前缀google::SetLogFilenameExtension(logExtension);//在日志文件名中级别后添加一个扩展名。适用于所有严重级别google::SetStderrLogging(google::GLOG_INFO);//大于指定级别的日志都输出到标准输出3、常用参数FlagsFLAGS_logtostderrtrue;//设置日志消息是否转到标准输出而不是日志文件FLAGS_alsologtostderrtrue;//设置日志消息除了日志文件之外是否去标准输出FLAGS_colorlogtostderrtrue;//设置记录到标准输出的颜色消息如果终端支持FLAGS_log_prefixtrue;//设置日志前缀是否应该添加到每行输出FLAGS_logbufsecs0;//设置可以缓冲日志的最大秒数0指实时输出FLAGS_max_log_size10;//设置最大日志文件大小以MB为单位FLAGS_stop_logging_if_full_disktrue;//设置是否在磁盘已满时避免日志记录到磁盘4、条件输出LOG_IF(INFO,num_cookies10)Got lots of cookies;//当条件满足时输出日志LOG_EVERY_N(INFO,10)Got the google::COUNTERth cookie;//google::COUNTER 记录该语句被执行次数从1开始在第一次运行输出日志之后每隔 10 次再输出一次日志信息LOG_IF_EVERY_N(INFO,(size1024),10)Got the google::COUNTERth big cookie;//上述两者的结合不过要注意是先每隔 10 次去判断条件是否满足如果滞则输出日志而不是当满足某条件的情况下每隔 10 次输出一次日志信息LOG_FIRST_N(INFO,20)Got the google::COUNTERth cookie;//当此语句执行的前 20 次都输出日志然后不再输出5、输出日志LOG(INFO)info test;//输出一个Info日志LOG(WARNING)warning test;//输出一个Warning日志LOG(ERROR)error test;//输出一个Error日志LOG(FATAL)fatal test;//输出一个Fatal日志这是最严重的日志并且输出之后会中止程序6、日志类型LOG()//内置日志VLOG()//自定义日志DLOG()//DEBUG模式可输出的日志DVLOG()//DEBUG模式可输出的自定义日志SYSLOG()//系统日志同时通过 syslog() 函数写入到 /var/log/message 文件PLOG()//perror风格日志设置errno状态并输出到日志中RAW_LOG()//线程安全的日志需要#include glog/raw_logging.h3.2.2、下载Glog的地址 从https://code.google.com/p/google-glog/ 变为了https://github.com/google/glog请从该链接地址下载最新版。官方文档http://google-glog.googlecode.com/svn/trunk/doc/glog.html3.2.3、配置在Qt下项目中添加对应Glog的库、头文件。很简单这里不做赘述但有个区别请注意MSVC编译器把glog/logging.h填到工程下MINGW编译器把glog文件夹以及下面的文件和config.h以及glog-master\src\glog目录下的log_severity.h添加到Qt工程。3.2.4、使用#ifndefGLOG_NO_ABBREVIATED_SEVERITIES#defineGLOG_NO_ABBREVIATED_SEVERITIES// 如果不加这个宏定义代码就会报错#endif#includeQApplication#includeglog/logging.h#pragmacomment(lib,glog.lib)...intmain(intargc,char*argv[]){FLAGS_logtostderrtrue;FLAGS_colorlogtostderrtrue;//是否启用不同颜色显示(如果终端支持)google::InitGoogleLogging(argv[0]);//使用glog之前必须先初始化库仅需执行一次括号内为程序名//google::SetLogDestination(google::GLOG_INFO, E:\\logs\\INFO_);//INFO级别的日志都存放到logs目录下且前缀为INFO_LOG(INFO)info;LOG(WARNING)warning;LOG(ERROR)error;QApplicationa(argc,argv);returna.exec();}3.2.5、相关我之前写的抓取崩溃信息的文章Breakpad也是谷歌的通常和Glog结合使用。地址Qt开发 之 抓取崩溃信息读这一篇就够了3.3、Easylogging3.3.1、要领最新的 Easylogging 版本是V9.96如果编译器不支持C11的话是无法编译的对于Visual Studio系列来说必须是VS2012或以上版本才行。如果还停留在VS2010、VS2008VS2005的小伙伴可以考虑使用EasyLogging V8.91版本。需要注意的是不同的版本在使用方法和功能支持上都会有所差异。为了开始配置日志库您必须了解严重性级别。Easylogging 故意不使用分层日志记录以便完全控制启用和禁用的内容。话虽这么说仍然可以选择使用分层日志记录LoggingFlag::HierarchicalLogging。Easylogging 有以下级别按层次级别排序等级描述Global代表所有级别的通用级别。在为所有级别设置全局配置时很有用。Trace可用于回溯某些事件的信息 - 比调试日志更有用。Debug对于开发人员调试应用程序最有用的信息事件。仅当未定义 NDEBUG对于非 VC或定义 _DEBUG对于 VC时才适用。Fatal非常严重的错误事件可能会导致应用程序中止。Error错误信息但会继续应用程序继续运行。Warning表示应用程序中出现错误的信息但应用程序将继续运行。Info主要用于表示当前应用程序的进度。Verbose非常有用且随详细日志记录级别而变化的信息。详细日志记录不适用于分层日志记录。Unknown仅适用于分层日志记录用于完全关闭日志记录。3.3.2、兼容Easylogging 需要一个像样的 C0x 兼容编译器。下表显示了一些已知可与 v9.0 一起使用的编译器对于旧版本请参阅 github 上相应版本的自述文件支持的操作系统如下表所示。Easylogging 应该可以在列表中未列出的其他主要操作系统上运行Easylogging 还支持以下 C 库3.3.3、注意加入到qt项目中报错括号问题135行建议直接自己指定这个宏136和138选择一个放开135-139其它都屏蔽这个意思是你QT的版本136 QT5.0及以上 这行5.0以上可以放开138 QT5.0以下包含4.X如果项目是Unicode编码格式那么输出中文log可能报错。使用VS推荐办法在项目-属性-C±预处理-预处理定义加入宏ELPP_UNICODE使用Qt推荐方法3.3.4、示例只需要将头文件加入短短几行代码即可输出项目当前文件夹下的logs文件下生成log文件

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询