多线程下可能会出问题,没有测试过
.h
#include <QFile>
#include <QMutex>
#include <QTextStream>
#define LOG_INFO 0
#define LOG_WARNING 1
#define LOG_ERROR 2
#define DETAIL_INFO QString::fromLocal8Bit("在文件%1,第%2行,函数%3记录").arg(__FILE__).arg(__LINE__).arg(__FUNCTION__)
#define LOGERROR(_log) SimpleLog::getInstance()->writeLog(_log, DETAIL_INFO, LOG_ERROR)
#define LOGINFO(_log) SimpleLog::getInstance()->writeLog(_log, DETAIL_INFO, LOG_INFO)
#define LOGWRANING(_log) SimpleLog::getInstance()->writeLog(_log, DETAIL_INFO, LOG_WARNING)
class SimpleLog
{
private:
SimpleLog();
static SimpleLog* m_instance;
public:
~SimpleLog();
static SimpleLog* getInstance();
void writeLog(QString _log, QString _details = "", int _flag = LOG_INFO);
void createDumpFile();
private:
void openNewLog();
void endLog();
private:
QFile m_log;
QMutex m_mutex;
QTextStream m_stream;
int m_index;
};
.cpp
#include "simplelog.h"
#include <QDir>
#include <QSettings>
#include <QApplication>
#include <QDebug>
#include <windows.h>
#include <dbghelp.h>
#pragma comment(lib, "dbghelp.lib")
#include <QTime>
//异常处理代码
//EXCEPTION_EXECUTE_HANDLER equ 1 表示我已经处理了异常,可以优雅地结束了
//EXCEPTION_CONTINUE_SEARCH equ 0 表示我不处理,其他人来吧,于是windows调用默认的处理程序显示一个错误框,并结束
//EXCEPTION_CONTINUE_EXECUTION equ -1 表示错误已经被修复,请从异常发生处继续执行
LONG WINAPI DumpRegister(struct _EXCEPTION_POINTERS* ExceptionInfo)
{
QDir _applicationDir(QCoreApplication::applicationDirPath());
_applicationDir.cdUp();
if (!_applicationDir.exists(_applicationDir.path() + "/log"))
{
_applicationDir.mkpath(_applicationDir.path() + "/log");
}
_applicationDir.cd("log");
QString date = QDate::currentDate().toString("yyyy-MM-dd");
QString _path = _applicationDir.path() + "/" + date;
if (!_applicationDir.exists(_path))
{
_applicationDir.mkpath(_path);
}
_applicationDir.cd(date);
QString strDumpFile = QTime::currentTime().toString("hh-mm-ss");
strDumpFile += ".dmp ";
QString fileName = _applicationDir.path() + "/" + strDumpFile;
HANDLE hFile = CreateFile(fileName.toStdWString().c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
MINIDUMP_EXCEPTION_INFORMATION ExInfo;
ExInfo.ThreadId = ::GetCurrentThreadId();
ExInfo.ExceptionPointers = ExceptionInfo;
ExInfo.ClientPointers = NULL;
// write the dump
BOOL bOK = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL);
CloseHandle(hFile);
}
//theApp.PostThreadMessage(WM_QUIT,0,0);
return EXCEPTION_EXECUTE_HANDLER;
}
SimpleLog* SimpleLog::m_instance = new SimpleLog;
SimpleLog* SimpleLog::getInstance()
{
return m_instance;
}
SimpleLog::SimpleLog()
{
QDir _applicationDir(QCoreApplication::applicationDirPath());
_applicationDir.cdUp();
if (!_applicationDir.exists(_applicationDir.path() + "/log"))
{
_applicationDir.mkpath(_applicationDir.path() + "/log");
}
_applicationDir.cd("log");
QString date = QDate::currentDate().toString("yyyy-MM-dd");
QString time = QTime::currentTime().toString("hh-mm-ss");
time += ".html";
QString _path = _applicationDir.path() + "/" + date;
if (!_applicationDir.exists(_path))
{
_applicationDir.mkpath(_path);
}
_applicationDir.cd(date);
m_index = 0;
m_log.setFileName(_applicationDir.path() + "/" + time);
if (m_log.exists())m_log.remove();
if (m_log.open(QIODevice::ReadWrite | QIODevice::Text | QFile::Append))
{
m_stream.setDevice(&m_log);
QString _logTitle = QString::fromLocal8Bit("<html>\n<head>\n<title>日志记录</title>\n</head>\n<body>\n");
m_stream << _logTitle;
}
}
SimpleLog::~SimpleLog()
{
endLog();
}
void SimpleLog::writeLog(QString _log, QString _details, int _flag)
{
QString time = QTime::currentTime().toString("hh:mm:ss");
m_mutex.lock();
if (_flag == LOG_INFO)
{
m_stream << QString::fromLocal8Bit("<br><font color=\"#000000\" family= \"微软雅黑\">") << m_index << " " << time << " " << _details << QString::fromLocal8Bit("信息 : ") << _log << "</font></br>";
}
else if (_flag == LOG_WARNING)
{
m_stream << QString::fromLocal8Bit("<br><font color=\"#0000FF\" family= \"微软雅黑\">") << m_index << " " << time << " " << _details << QString::fromLocal8Bit("警告 : ") << _log << "</font></br>";
}
else if (_flag == LOG_ERROR)
{
m_stream << QString::fromLocal8Bit("<br><font color=\"#FF0000\" family= \"微软雅黑\">") << m_index << " " << time << " " << _details << QString::fromLocal8Bit("错误 : ") << _log << "</font></br>";
}
m_stream.flush();
m_log.flush();
m_index += 1;
m_mutex.unlock();
}
void SimpleLog::createDumpFile()
{
::SetUnhandledExceptionFilter(DumpRegister);
}
void SimpleLog::endLog()
{
if (m_log.isOpen())
{
m_stream << "</body>";
m_stream.flush();
m_log.flush();
m_log.close();
}
}
使用方法
#include "simplelog"
LOGINFO(QString::fromLocal8Bit("我的订阅列表:%1").arg(_actorIDList.join(","))); //普通信息
LOGWARING(QString::fromLocal8Bit("我的订阅列表:%1").arg(_actorIDList.join(",")));//警告
LOGERROR(QString::fromLocal8Bit("我的订阅列表:%1").arg(_actorIDList.join(",")));//错误
//SimpleLog::getInstance()->createDumpFile(); //创建崩溃转储文件,与日志在同一目录下