项目中的log输出(QT版)
这种重定向的log输出方法,一般的程序都能hold住,但在多线程并且数据收发速度非常快的socket编程中,会报错,博主能力有限,没找出错误,请高手指正。另本人找到了另一个版本的log网址:https://blog.csdn.net/vicky_white/article/details/103142113
项目中经常用到log的日志输出,记录下来,省的每次都写。话不多说,直接上代码。
mylog.h文件:
#ifndef MYLOG_H
#define MYLOG_H
void logInit();
#endif // MYLOG_H
mylog.cpp文件:
#include "mylog.h"
#include <QString>
#include <QLoggingCategory>
#include <QIODevice>
#include <QFile>
#include <QDir>
#include <QDebug>
#include <QDateTime>
#include <QMutex>
#include <QApplication>
#include <QRegExp>
static QString logDirectory;
static QString logFileName;
static QMutex mutex;
static QFile file;
static QTextStream textStream;
void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QString text;
switch(type)
{
case QtDebugMsg:
text = QString("[Debug]");
break;
case QtInfoMsg:
text = QString("[Info]");
break;
case QtWarningMsg:
text = QString("[Warning]");
break;
case QtCriticalMsg:
text = QString("[Critical]");
break;
case QtFatalMsg:
text = QString("[Fatal]");
}
text.append(QString(" [%1] ").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")));
text.append(QString(" [%1: Line: %2] ").arg(QString(context.file)).arg(context.line));
text.append(QString(" [Function: %1] ").arg(QString(context.function)));
mutex.lock();
file.setFileName(logFileName);
file.open(QIODevice::WriteOnly | QIODevice::Append);
textStream.setDevice(&file);
textStream << text << endl << QString("Message: %1").arg(msg) << endl;
file.close();
mutex.unlock();
}
void logInit()
{
logDirectory = QApplication::applicationDirPath() + "/Log/";
QDir dir(logDirectory);
if(!dir.exists())
dir.mkdir(logDirectory);
logFileName = logDirectory + (QApplication::applicationName()+".log");
//以下这段代码的含义是初始化时检查日志文件是否存在一个月之前的日志,如果存在删除之
{
QMutexLocker locker(&mutex);
//mutex.lock();
QFile file(logFileName);
file.open(QIODevice::ReadOnly);
QTextStream textStream(&file);
QString temp;
QStringList tempList;
QRegExp regExp(".*(20\\d\\d-\\d\\d-\\d\\d).*");
while ((temp = textStream.readLine()).isEmpty() == false)
{
if(temp.indexOf(regExp) >= 0)
{
QDate date = QDate::fromString(regExp.cap(1), "yyyy-MM-dd");
QDate currentDate = QDate::currentDate();
//判断当前行所记载的日期和现今的日期天数之差是否大于记录该条日志时的那个月的天数
if(date.daysTo(currentDate) < date.day())
{
tempList << temp;
tempList << textStream.readLine();
}
}
}
file.close();
file.open(QIODevice::Truncate | QIODevice::WriteOnly);
textStream.setDevice(&file);
for(auto iterator = tempList.begin(); iterator != tempList.end(); iterator++)
{
textStream << *iterator << endl;
}
file.close();
//mutex.unlock();
}
//安装上述自定义函数
qInstallMessageHandler(outputMessage);
}
.pro文件的配置
QT -= gui
CONFIG += c++11 console
CONFIG -= app_bundle
QT += widgets
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
DEFINES += QT_MESSAGELOGCONTEXT
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mylog.cpp
HEADERS += \
mylog.h
main函数的调用
#include <QCoreApplication>
#include <QDebug>
#include "mylog.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
logInit();
qDebug()<<"lalla";
// 打印信息
qDebug("This is a debug message.");
qInfo("This is a info message.");
qWarning("This is a warning message.");
qCritical("This is a critical message.");
qFatal("This is a fatal message.");
return a.exec();
}
输出结果(在项目文件夹下有个log文件夹):
[Debug] [2019-10-12 09:54:37] [..\TestLog1\main.cpp: Line: 9] [Function: int __cdecl main(int,char *[])]
Message: lalla
[Debug] [2019-10-12 09:54:37] [..\TestLog1\main.cpp: Line: 11] [Function: int __cdecl main(int,char *[])]
Message: This is a debug message.
[Info] [2019-10-12 09:54:37] [..\TestLog1\main.cpp: Line: 12] [Function: int __cdecl main(int,char *[])]
Message: This is a info message.
[Warning] [2019-10-12 09:54:37] [..\TestLog1\main.cpp: Line: 13] [Function: int __cdecl main(int,char *[])]
Message: This is a warning message.
[Critical] [2019-10-12 09:54:37] [..\TestLog1\main.cpp: Line: 14] [Function: int __cdecl main(int,char *[])]
Message: This is a critical message.
[Fatal] [2019-10-12 09:54:37] [..\TestLog1\main.cpp: Line: 15] [Function: int __cdecl main(int,char *[])]
Message: This is a fatal message.
注意:release模式下无法打印QMessageLogContext的具体内容,因为qt默认把release给取消了,需要在pro文件里面加上DEFINES += QT_MESSAGELOGCONTEXT