| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- #include "pqlog.h"
- #include <QTime>
- #include <QEvent>
- #include <QThread>
- #include <QCoreApplication>
- #include <iostream>
- #include <QDir>
- #include <QDate>
- #include <memory>
- #include <QDebug>
- #include <QDateTime>
- #include "core/pqapppath.h"
- namespace PQ {
- static const char * LevelName[6] = {"Test","Debug","Info","Warning","Critical","Fatal"};
- void customMessageHandler(QtMsgType type, const QMessageLogContext &context,const QString & msg)
- {
- auto log = PQLogManger::this_()->qDebugLog();
- if(log == nullptr) return;
- switch (type) {
- //调试信息提示
- case QtDebugMsg:
- if (log->checkLevel(DebugMsg)) {
- LogMessage(log,context.file,context.line,DebugMsg).stream() << msg ;
- }
- break;
- //一般的warning提示
- case QtWarningMsg:
- if (log->checkLevel(WarningMsg)) {
- LogMessage(log,context.file,context.line,WarningMsg).stream() << msg ;
- }
- break;
- //严重错误提示
- case QtCriticalMsg:
- if (log->checkLevel(CriticalMsg)) {
- LogMessage(log,context.file,context.line,CriticalMsg).stream() << msg ;
- }
- break;
- //致命错误提示
- case QtFatalMsg:
- if (log->checkLevel(FatalMsg)) {
- LogMessage(log,context.file,context.line,FatalMsg).stream() << msg ;
- }
- break;
- case QtInfoMsg :
- if (log->checkLevel(InfoMsg)) {
- LogMessage(log,context.file,context.line,InfoMsg).stream() << msg ;
- }
- break;
- }
- }
- PQLogManger::PQLogManger()
- {
- _thread.start();
- auto nm = QCoreApplication::applicationName();
- _baseLog.reset(new PQLog(nm,STD_OUT));
- _baseLog->moveToThread(&_thread);
- _qtLog.reset(new PQLog("qtdebug",STD_OUT));
- _qtLog->moveToThread(&_thread);
- _logs.insert(nm,_baseLog);
- _logs.insert("qtdebug",_qtLog);
- connect(this,&PQLogManger::updateSavePath,_baseLog.data(),&PQLog::restLog,Qt::QueuedConnection);
- connect(this,&PQLogManger::updateSavePath,_qtLog.data(),&PQLog::restLog,Qt::QueuedConnection);
- setSaveFilePath(AppPath::this_()->logDir().absolutePath());
- }
- PQLogManger * PQLogManger::this_()
- {
- static PQLogManger logManger;
- return &logManger;
- }
- PQLogManger::~PQLogManger()
- {
- _thread.quit();
- _thread.wait(1000);
- if(_thread.isRunning()){
- _thread.terminate();
- }
- }
- bool PQLogManger::setSaveFilePath(const QString & path)
- {
- QDir dir(path);
- if(dir.exists() || dir.mkpath(dir.absolutePath())) {
- QFileInfo info(path);
- if(info.isWritable()){
- path_ = dir.absolutePath();
- emit updateSavePath();
- }
- }
- return false;
- }
- PQLog * PQLogManger::enbleQtMessage()
- {
- qInstallMessageHandler(customMessageHandler);
- return _qtLog.data();
- }
- PQLog * PQLogManger::getLog(const QString & name)
- {
- _locker.lockForRead();
- auto log = _logs.value(name);
- _locker.unlock();
- if(log.isNull()){
- _locker.lockForWrite();
- log = _logs.value(name);
- if(log.isNull()){
- log.reset(new PQLog(name));
- log->moveToThread(&_thread);
- connect(this,&PQLogManger::updateSavePath,log.data(),&PQLog::restLog,Qt::QueuedConnection);
- _logs.insert(name,log);
- }
- _locker.unlock();
- }
- return log.data();
- }
- class LogEvent : public QEvent
- {
- public:
- LogEvent(QString && str,LogLevel lv): QEvent(eventType),level(lv),str_(str) {}
- ~LogEvent() {}
- const QString & getString() const {return str_;}
- static QEvent::Type eventType;
- LogLevel level;
- private:
- QString str_;
- };
- QEvent::Type LogEvent::eventType = static_cast<QEvent::Type>(QEvent::registerEventType());
- class UpEventOutStatus : public QEvent
- {
- public:
- UpEventOutStatus(OutState state): QEvent(eventType),state(state) {}
- ~UpEventOutStatus() {}
- static QEvent::Type eventType;
- OutState state;
- };
- QEvent::Type UpEventOutStatus::eventType = static_cast<QEvent::Type>(QEvent::registerEventType());
- LogMessage::LogMessage(PQLog * log,const char * file, int line,LogLevel level) : log(log), ts(&str_),level_(level)
- {
- if(log == nullptr || level < log->level) return;
- if(log->writeTime){
- ts << "[" << QTime::currentTime().toString("hh:mm:ss.zzz") << "]:";
- }
- if(log->writeFileInfo) {
- ts << "[@ " << file << " : " << line << "]:";
- }
- if(log->writeLevel){
- ts << "[" << LevelName[level] << "]:";
- }
- }
- LogMessage::LogMessage(PQLog * log,LogLevel level): log(log), ts(&str_),level_(level)
- {
- if(log == nullptr || level < log->level) return;
- if(log->writeTime){
- ts << "[" << QTime::currentTime().toString("hh:mm:ss.zzz") << "]:";
- }
- if(log->writeFileInfo) {
- ts << "[@ ]:";
- }
- if(log->writeLevel){
- ts << "[" << LevelName[level] << "]:";
- }
- }
- LogMessage::~LogMessage()
- {
- if (log != nullptr && level_ >= log->level ) {
- if(log->writeEndLine)
- ts << "\r\n";
- ts.setDevice(nullptr);
- QCoreApplication::postEvent(log,new LogEvent(std::move(str_),level_));
- if (level_ == FatalMsg) {
- QCoreApplication::exit(-1);
- }
- }
- }
- PQLog::PQLog(const QString & name, OutState state)
- : QObject(nullptr),state_(state),file_(nullptr),_name(name)
- {
- level = TestMsg;
- writeTime = true;
- writeFileInfo = true;
- writeLevel = true;
- writeEndLine = true;
- fileCreateType = DayOne;
- ts_.setDevice(nullptr);
- _fileCreateId = -1;
- }
- PQLog::~PQLog()
- {
- releaseLogFile();
- }
- void PQLog::setOutState(OutState outState)
- {
- QCoreApplication::postEvent(this,new UpEventOutStatus(outState));
- }
- void PQLog::restLog()
- {
- if(state_ == File){
- releaseLogFile();
- }
- }
- void PQLog::releaseLogFile()
- {
- ts_.setDevice(nullptr);
- if(file_){
- file_->close();
- delete file_;
- file_ = nullptr;
- }
- }
- void PQLog::customEvent(QEvent * event)
- {
- if(event->type() == UpEventOutStatus::eventType){
- UpEventOutStatus * ev = static_cast<UpEventOutStatus *>(event);
- if(state_ != ev->state) {
- state_ = ev->state;
- releaseLogFile();
- }
- } else if (event->type() == LogEvent::eventType) {
- LogEvent * ev = static_cast<LogEvent *>(event);
- if(ev->level >= level) {
- switch (state_) {
- case STD_OUT :{
- std::cout << ev->getString().toStdString();
- return;
- }
- break;
- case STD_ERROR:{
- std::cerr << ev->getString().toStdString();
- return;
- }
- break;
- case File : {
- if(file_){
- int id = _fileCreateId;
- switch (fileCreateType) {
- case DayOne: {
- id = QDate::currentDate().day();
- }
- break;
- case HourOne:
- id = QTime::currentTime().hour();
- break;
- case MonthOne:
- id = QDate::currentDate().month();
- break;
- default:
- id = _fileCreateId;
- break;
- }
- if(id != _fileCreateId)
- releaseLogFile();
- }
- if(file_ == nullptr){
- QString fname = PQLogManger::this_()->getSaveFilePath() + "/" + _name;
- switch (fileCreateType) {
- case OneStartOne:{
- auto pid = QCoreApplication::applicationPid();
- fname += "_";
- fname += QDateTime::currentDateTime().toString("yyyy-MM-dd.hh-mm-ss.zzz");
- fname += "_";
- fname += QString::number(pid);
- _fileCreateId = 0;
- }
- case DayOne: {
- auto dt = QDate::currentDate();
- fname += "_";
- fname += dt.toString("yyyy-MM-dd");
- _fileCreateId = dt.day();
- }
- break;
- case HourOne:{
- auto dt = QDateTime::currentDateTime();
- fname += "_";
- fname += dt.toString("yyyy-MM-dd.hh");
- _fileCreateId = dt.time().hour();
- }
- break;
- case MonthOne:{
- auto dt = QDate::currentDate();
- fname += "_";
- fname += dt.toString("yyyy-MM");
- _fileCreateId = dt.month();
- }
- break;
- default:
- break;
- }
- fname += ".logs";
- file_ = new QFile(fname,this);
- file_->open(QFile::Append);
- ts_.setDevice(file_);
- }
- }
- break;
- default:
- break;
- }
- if (ts_.device() != nullptr) {
- ts_ << ev->getString();
- ts_.flush();
- }
- }
- }
- event->accept();
- }
- }//namespace PQLog
|