|
@@ -0,0 +1,1085 @@
|
|
|
+#include "progmon.h"
|
|
|
+#include <QFile>
|
|
|
+
|
|
|
+#include <iostream>
|
|
|
+
|
|
|
+#ifdef OS_UNIX
|
|
|
+#include "sys/statfs.h"
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
+#ifdef OS_WIN
|
|
|
+#include <windows.h>
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
+//extern iv::Ivlog * ivlog;
|
|
|
+//extern iv::Ivfault * ivfault;
|
|
|
+
|
|
|
+ProgMon::ProgMon(std::string path)
|
|
|
+{
|
|
|
+ UpdateCPUMemStat();
|
|
|
+
|
|
|
+ mvectorprog = loadprogunit(path);
|
|
|
+
|
|
|
+ InitLog();
|
|
|
+
|
|
|
+ mpthread_stdout = new std::thread(&ProgMon::threadstdout,this);
|
|
|
+ mpthread_errout = new std::thread(&ProgMon::threaderrout,this);
|
|
|
+}
|
|
|
+
|
|
|
+ProgMon::~ProgMon()
|
|
|
+{
|
|
|
+ std::cout<<"~ProgMon"<<std::endl;
|
|
|
+ unsigned int i;
|
|
|
+ for(i=0;i<mvectorprog.size();i++)
|
|
|
+ {
|
|
|
+ if(mvectorprog[i].mProcess != 0)
|
|
|
+ {
|
|
|
+ mvectorprog[i].mProcess->terminate();
|
|
|
+ // mvectorprog[i].mProcess->close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ QThread::msleep(300);
|
|
|
+ for(i=0;i<mvectorprog.size();i++)
|
|
|
+ {
|
|
|
+ if(mvectorprog[i].mProcess != 0)
|
|
|
+ {
|
|
|
+ mvectorprog[i].mProcess->kill();
|
|
|
+ // mvectorprog[i].mProcess->close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ std::cout<<"End Std out thread."<<std::endl;
|
|
|
+ mbstdoutrun = false;
|
|
|
+ mpthread_stdout->join();
|
|
|
+
|
|
|
+ std::cout<<"End Err out thread."<<std::endl;
|
|
|
+ mberroutrun = false;
|
|
|
+ mpthread_errout->join();
|
|
|
+
|
|
|
+ if(mbFileStdLog)
|
|
|
+ {
|
|
|
+ mbFileStdLog = false;
|
|
|
+ qint64 nsize = mFileStdLog.size();
|
|
|
+ mFileStdLog.close();
|
|
|
+
|
|
|
+ if(nsize == 0)
|
|
|
+ {
|
|
|
+ std::cout<<"Because no std log, delete std log. "<<std::endl;
|
|
|
+ mFileStdLog.remove();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if(mbFileLog)
|
|
|
+ {
|
|
|
+ mbFileLog = false;
|
|
|
+ qint64 nsize = mFileLog.size();
|
|
|
+ mFileLog.close();
|
|
|
+
|
|
|
+ if(nsize == 0)
|
|
|
+ {
|
|
|
+ std::cout<<"Because no error log, delete error log. "<<std::endl;
|
|
|
+ mFileLog.remove();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+// mvectorprog.clear();
|
|
|
+}
|
|
|
+
|
|
|
+std::vector<ProgUnit> ProgMon::loadprogunit(std::string path)
|
|
|
+{
|
|
|
+ std::vector<ProgUnit> xvectorprog;
|
|
|
+ QDomDocument doc;
|
|
|
+
|
|
|
+ qDebug()<<"path: "<<path.data();
|
|
|
+ QFile file(path.data());
|
|
|
+ if (!file.open(QIODevice::ReadOnly))
|
|
|
+ return xvectorprog;
|
|
|
+ if (!doc.setContent(&file)) {
|
|
|
+ file.close();
|
|
|
+ return xvectorprog;
|
|
|
+ }
|
|
|
+ file.close();
|
|
|
+
|
|
|
+ //遍历节点,从配置文件中获取当前有哪些模块,并拼接启动命令和启动参数_tjc
|
|
|
+ QDomElement docElem = doc.documentElement();
|
|
|
+ QDomNode n = docElem.firstChild();
|
|
|
+
|
|
|
+ std::string defdir = "./";
|
|
|
+ while(!n.isNull())
|
|
|
+ {
|
|
|
+ QDomElement e = n.toElement(); // 尝试将节点转换为元素
|
|
|
+ std::string name = e.nodeName().toStdString();
|
|
|
+ if(name == "setting")
|
|
|
+ {
|
|
|
+ QString str1 = e.attribute("defaultpath","./");
|
|
|
+ defdir = e.attribute("defaultpath","./").toStdString();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ n = n.nextSibling();
|
|
|
+ }
|
|
|
+ n = docElem.firstChild();
|
|
|
+ while(!n.isNull())
|
|
|
+ {
|
|
|
+ QDomElement e = n.toElement(); // 尝试将节点转换为元素
|
|
|
+ std::string name = e.nodeName().toStdString();
|
|
|
+
|
|
|
+ if(name == "module")
|
|
|
+ {
|
|
|
+ std::string appname = e.attribute("app","").toStdString();
|
|
|
+ std::string strdir = e.attribute("dir","").toStdString();
|
|
|
+ std::string strargs = e.attribute("args","").toStdString();
|
|
|
+ std::string strbstart = e.attribute("autostart","false").toStdString();
|
|
|
+ std::string strgroup = e.attribute("group","unknown").toStdString();
|
|
|
+ std::string strsavestd = e.attribute("savestd","false").toStdString();
|
|
|
+
|
|
|
+ ProgUnit x;
|
|
|
+ if(strbstart == "true")x.mbautostart = true;
|
|
|
+ else x.mbautostart = false;
|
|
|
+ x.strappdir = strdir;
|
|
|
+ x.strappname = appname;
|
|
|
+ x.strargs = strargs;
|
|
|
+ x.strgroup = strgroup;
|
|
|
+ x.mProcess = 0;
|
|
|
+ x.mbSavestdout = false;
|
|
|
+ if(strsavestd == "true")x.mbSavestdout = true;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if(x.strappname.length() > 0)
|
|
|
+ {
|
|
|
+ x.strcmd = x.strappdir;
|
|
|
+ if(x.strcmd.length()<1)
|
|
|
+ {
|
|
|
+ x.strcmd = defdir;
|
|
|
+ }
|
|
|
+ if(x.strcmd.length() > 0)
|
|
|
+ {
|
|
|
+ if(x.strcmd.at(x.strcmd.length() -1) != '/')
|
|
|
+ {
|
|
|
+ x.strcmd.append("/");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ x.strcmd.append(x.strappname);
|
|
|
+ if(x.strargs.length() > 0)
|
|
|
+ {
|
|
|
+ x.strcmd.append(" ");
|
|
|
+ x.strcmd.append(x.strargs);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ xvectorprog.push_back(x);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ n = n.nextSibling();
|
|
|
+ }
|
|
|
+
|
|
|
+ return xvectorprog;
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::updatexml(std::string path)
|
|
|
+{
|
|
|
+ mMutex.lock();
|
|
|
+ std::vector<ProgUnit> xvectorprog = loadprogunit(path);
|
|
|
+ int i;
|
|
|
+ int nsize = mvectorprog.size();
|
|
|
+ int nnewsize = xvectorprog.size();
|
|
|
+ //Start new xml have program.
|
|
|
+ for(i=0;i<nnewsize;i++)
|
|
|
+ {
|
|
|
+ ProgUnit * pnewPU = &(xvectorprog[i]);
|
|
|
+ int j;
|
|
|
+ bool bNew = true;
|
|
|
+ nsize = mvectorprog.size();
|
|
|
+ int noldpos = -1;
|
|
|
+ (void)noldpos;
|
|
|
+ for(j=0;j<nsize;j++)
|
|
|
+ {
|
|
|
+ if(strncmp(mvectorprog[j].strcmd.data(),pnewPU->strcmd.data(),255) == 0)
|
|
|
+ {
|
|
|
+ bNew = false;
|
|
|
+ noldpos = j;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(bNew == true)
|
|
|
+ {
|
|
|
+ mvectorprog.push_back(*pnewPU);
|
|
|
+ if(pnewPU->mbautostart) StartProc(&mvectorprog[mvectorprog.size() -1]);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::cout<<pnewPU->strcmd.data()<<" is exist. "<<std::endl;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //Stop And Delete new xml not have item.
|
|
|
+ nsize = mvectorprog.size();
|
|
|
+ for(i=0;i<static_cast<int>(mvectorprog.size()) ;i++)
|
|
|
+ {
|
|
|
+ int j;
|
|
|
+ bool bNewHave = false;
|
|
|
+ for(j=0;j<nnewsize;j++)
|
|
|
+ {
|
|
|
+ if(strncmp(mvectorprog[i].strcmd.data(),xvectorprog[j].strcmd.data(),255) == 0)
|
|
|
+ {
|
|
|
+ bNewHave = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(bNewHave == false)
|
|
|
+ {
|
|
|
+ if(mvectorprog[i].mbRun)
|
|
|
+ {
|
|
|
+ StopProc(&mvectorprog[i]);
|
|
|
+ }
|
|
|
+ mvectorprog.erase(mvectorprog.begin()+i);
|
|
|
+ i--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mMutex.unlock();
|
|
|
+// nsize = mvectorprog.size();
|
|
|
+// nsize = nsize +1-1;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void ProgMon::onProcessStarted()
|
|
|
+{
|
|
|
+// qDebug("started.");
|
|
|
+ QProcess * proc = (QProcess *)sender();
|
|
|
+
|
|
|
+ int nsize = mvectorprog.size();
|
|
|
+ int i;
|
|
|
+ for(i=0;i<nsize;i++)
|
|
|
+ {
|
|
|
+ if(proc == mvectorprog.at(i).mProcess)
|
|
|
+ {
|
|
|
+ mvectorprog.at(i).mbRun = true;
|
|
|
+#ifdef IV_OS_UNIX
|
|
|
+ mvectorprog.at(i).mpid = proc->processId();
|
|
|
+// mvectorprog.at(i).mpid = proc->pid();
|
|
|
+#endif
|
|
|
+#ifdef IV_OS_WIN
|
|
|
+
|
|
|
+ mvectorprog.at(i).mpid = proc->pid()->dwProcessId;
|
|
|
+#endif
|
|
|
+ mvectorprog.at(i).mnStartCount++;
|
|
|
+ // qDebug("program id is %ld",mvectorprog.at(i).mpid);
|
|
|
+ emit SigProcStarted(&(mvectorprog.at(i)));
|
|
|
+ break;
|
|
|
+ // qDebug("find procname is %s",mvectorprog.at(i).strcmd.data());
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//add tjc
|
|
|
+void ProgMon::onProcessErrorStarted(QProcess::ProcessError error){
|
|
|
+ qDebug("Process Error Started.");
|
|
|
+ std::string desc;
|
|
|
+ int code;
|
|
|
+ QProcess * proc = (QProcess*)sender();
|
|
|
+ int nsize = mvectorprog.size();
|
|
|
+ int i;
|
|
|
+ for(i=0;i<nsize;i++)
|
|
|
+ {
|
|
|
+ if(proc == mvectorprog.at(i).mProcess)
|
|
|
+ {
|
|
|
+ if(error == QProcess::ProcessError::FailedToStart){
|
|
|
+ //启动错误 启动失败
|
|
|
+ code = 0x0001;
|
|
|
+ }else{
|
|
|
+ //未知错误 启动失败
|
|
|
+ code = 0x0002;
|
|
|
+ }
|
|
|
+ desc = mvectorprog.at(i).strappname + ":FailedToStart";
|
|
|
+ //记录故障状态,模块启动失败
|
|
|
+ // ivfault->SetFaultState(2,code,desc.c_str());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void ProgMon::onReadStandardOutput()
|
|
|
+{
|
|
|
+ QProcess * proc = (QProcess *)sender();
|
|
|
+ QByteArray ba = proc->readAllStandardOutput();
|
|
|
+
|
|
|
+
|
|
|
+ if(mbAllNoLog == false)
|
|
|
+ {
|
|
|
+ mMutex_stdout.lock();
|
|
|
+ if(mvectorstdout.size()<1000) mvectorstdout.push_back(stdoutunit(proc,ba));
|
|
|
+ mMutex_stdout.unlock();
|
|
|
+ }
|
|
|
+// qDebug("process out: %s ",ba.data());
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::onReadStandardError()
|
|
|
+{
|
|
|
+ QProcess * proc = (QProcess *)sender();
|
|
|
+ QByteArray ba = proc->readAllStandardError();
|
|
|
+
|
|
|
+
|
|
|
+ mMutex_errout.lock();
|
|
|
+ if(mvectorerrout.size()<1000) mvectorerrout.push_back(stdoutunit(proc,ba));
|
|
|
+ mMutex_errout.unlock();
|
|
|
+
|
|
|
+ return;
|
|
|
+
|
|
|
+ if(ba.size() == 0)return;
|
|
|
+ LogError(proc,ba);
|
|
|
+
|
|
|
+// if(mbAllNoLog == false)
|
|
|
+// {
|
|
|
+// mMutex_stdout.lock();
|
|
|
+// if(mvectorstdout.size()<1000) mvectorstdout.push_back(stdoutunit(proc,ba));
|
|
|
+// mMutex_stdout.unlock();
|
|
|
+// }
|
|
|
+// qDebug("process error: %s ",ba.data());
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::onProcessEnd()
|
|
|
+{
|
|
|
+ qDebug("process end.");
|
|
|
+ QProcess * proc = (QProcess *)sender();
|
|
|
+ int nsize = mvectorprog.size();
|
|
|
+ int i;
|
|
|
+ for(i=0;i<nsize;i++)
|
|
|
+ {
|
|
|
+ ProgUnit *pu = &(mvectorprog.at(i));
|
|
|
+ if(proc == pu->mProcess)
|
|
|
+ {
|
|
|
+ pu->mbRun = false;
|
|
|
+ emit SigProcStoped(pu);
|
|
|
+
|
|
|
+ if(mbquit)
|
|
|
+ {
|
|
|
+ std::cout<<"Program "<<pu->strappname<<" quit."<<std::endl;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // delete pu->mProcess;
|
|
|
+
|
|
|
+ if(pu->mbautostart)
|
|
|
+ {
|
|
|
+ // ivfault->SetFaultState(1,0x0003,(pu->strappname + " abnormal stop").data());
|
|
|
+ // ivlog->warn("%s : process abnormal stop", pu->strappname.data());
|
|
|
+ StartProc(&(mvectorprog.at(i)));
|
|
|
+ }
|
|
|
+ //if autostart
|
|
|
+ //modify tjc
|
|
|
+// if(pu->mbautostart && pu->state && proc->exitCode() != 0)
|
|
|
+// {
|
|
|
+// //警告 进程异常关闭
|
|
|
+// ivfault->SetFaultState(1,0x0003,(pu->strappname + " abnormal stop").data());
|
|
|
+// ivlog->warn("%s : process abnormal stop", pu->strappname.data());
|
|
|
+
|
|
|
+// //两分钟内重启三次则终止该模块
|
|
|
+// if(pu->timeRec.isNull()){
|
|
|
+// pu->timeRec = QTime::currentTime();
|
|
|
+// }
|
|
|
+
|
|
|
+// int elapsed = pu->timeRec.msecsTo(QTime::currentTime());
|
|
|
+// if(elapsed > 1000 * 60 * 2){
|
|
|
+// pu->timeRec = QTime::currentTime();
|
|
|
+// pu->count = 0;
|
|
|
+// }else{
|
|
|
+// if(pu->count <= 3){
|
|
|
+// pu->count++;
|
|
|
+// }else{
|
|
|
+// //停止该模块的启动并报故障
|
|
|
+// pu->state = 0;
|
|
|
+// //故障 进程多次异常关闭,不再启动该进程
|
|
|
+// ivfault->SetFaultState(2,0x0004,(pu->strappname + " exception stop").data());
|
|
|
+// ivlog->error("%s : process exception stop", pu->strappname.data());
|
|
|
+// return;
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+// StartProc(&(mvectorprog.at(i)));
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+ break;
|
|
|
+ // qDebug("find procname is %s",mvectorprog.at(i).strcmd.data());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::onChRead()
|
|
|
+{
|
|
|
+ QProcess * proc = (QProcess *)sender();
|
|
|
+ QByteArray ba = proc->readAll();
|
|
|
+
|
|
|
+ int ncha = proc->currentWriteChannel();
|
|
|
+ (void)ncha;
|
|
|
+
|
|
|
+ if(proc->currentWriteChannel() == 1)
|
|
|
+ {
|
|
|
+ std::cout<<"Receive a Error Output."<<std::endl;
|
|
|
+ LogError(proc,ba);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#ifdef QT_DEBUG
|
|
|
+// qDebug("process INFO: %s ", ba.data());
|
|
|
+#endif
|
|
|
+
|
|
|
+ if(mbAllNoLog == false)
|
|
|
+ {
|
|
|
+ mMutex_stdout.lock();
|
|
|
+ if(mvectorstdout.size()<1000) mvectorstdout.push_back(stdoutunit(proc,ba));
|
|
|
+ mMutex_stdout.unlock();
|
|
|
+ }
|
|
|
+
|
|
|
+// qDebug("read chanel count is :%d ",proc->readChannelCount());
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::restartProc(ProgUnit *pu){
|
|
|
+ if(pu == 0)return;
|
|
|
+
|
|
|
+ //判断项目当前是否启动状态
|
|
|
+ if(checkStartState(pu)){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if(pu->mProcess == 0){
|
|
|
+ StartProc(pu);
|
|
|
+ }
|
|
|
+ pu->mProcess->start();
|
|
|
+ pu->state = 1;
|
|
|
+ // ivlog->info("start program: AppGroup - %s; AppDir - %s; AppName - %s; StartArgs - %s;", pu->strgroup.c_str(), pu->strappdir.c_str(), pu->strappname.c_str(), pu->strargs.c_str());
|
|
|
+}
|
|
|
+
|
|
|
+ProgUnit * ProgMon::FindProcByName(std::string strappname, std::string strargs)
|
|
|
+{
|
|
|
+ ProgUnit * pu = 0;
|
|
|
+ int i;
|
|
|
+ int nsize = mvectorprog.size();
|
|
|
+ for(i=0;i<nsize;i++)
|
|
|
+ {
|
|
|
+ ProgUnit * putem = &mvectorprog.at(i);
|
|
|
+ if(strargs.size()<1)
|
|
|
+ {
|
|
|
+ if(strappname == putem->strappname)
|
|
|
+ {
|
|
|
+ pu = putem;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if((strappname == putem->strappname)&&(strargs == putem->strargs))
|
|
|
+ {
|
|
|
+ pu = putem;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return pu;
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::StartProc(std::string strappname, std::string strargs)
|
|
|
+{
|
|
|
+ ProgUnit * pu = FindProcByName(strappname,strargs);
|
|
|
+
|
|
|
+ if(pu == 0)
|
|
|
+ {
|
|
|
+ qDebug("StartProc can't find app = %s args = %s",strappname.data(),strargs.data());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ pu->mbautostart = false;
|
|
|
+ StartProc(pu);
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::StopProc(std::string strappname, std::string strargs)
|
|
|
+{
|
|
|
+ ProgUnit * pu = FindProcByName(strappname,strargs);
|
|
|
+
|
|
|
+ if(pu == 0)
|
|
|
+ {
|
|
|
+ qDebug("StopProc can't find app = %s args = %s",strappname.data(),strargs.data());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ pu->mbautostart = false;
|
|
|
+ StopProc(pu);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+void ProgMon::StartProc(ProgUnit *pu)
|
|
|
+{
|
|
|
+ if(pu->mbRun)
|
|
|
+ {
|
|
|
+ qDebug("process %s is running. not need start.",pu->strappname.data());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ pu->mProcess = new QProcess(this);
|
|
|
+
|
|
|
+
|
|
|
+ connect(pu->mProcess,SIGNAL(started()),this,SLOT(onProcessStarted()));
|
|
|
+ connect(pu->mProcess,SIGNAL(finished(int)),this,SLOT(onProcessEnd()));
|
|
|
+// connect(pu->mProcess,SIGNAL(readyRead()),this,SLOT(onChRead()));
|
|
|
+ connect(pu->mProcess,SIGNAL(readyReadStandardOutput()),this,SLOT(onReadStandardOutput()));
|
|
|
+ connect(pu->mProcess,SIGNAL(readyReadStandardError()),this,SLOT(onReadStandardError()));
|
|
|
+
|
|
|
+
|
|
|
+ connect(pu->mProcess,SIGNAL(error(QProcess::ProcessError)),this,SLOT(onProcessErrorStarted(QProcess::ProcessError)));
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ pu->mProcess->start(pu->strcmd.data());
|
|
|
+ pu->state = 1;
|
|
|
+
|
|
|
+
|
|
|
+// ivlog->info("start program: AppGroup - %s; AppDir - %s; AppName - %s; StartArgs - %s;", pu->strgroup.c_str(), pu->strappdir.c_str(), pu->strappname.c_str(), pu->strargs.c_str());
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+//test
|
|
|
+void ProgMon::StopProcTest(){
|
|
|
+ int nsize = mvectorprog.size();
|
|
|
+ for (int i = 0; i < nsize; i++) {
|
|
|
+ ProgUnit * ppu = &(mvectorprog.at(i));
|
|
|
+ StopProc(ppu);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::StopProc(ProgUnit *pu)
|
|
|
+{
|
|
|
+ if(pu == 0)return;
|
|
|
+ if(pu->mProcess == 0)return;
|
|
|
+ if(!pu->mbRun)
|
|
|
+ {
|
|
|
+ qDebug("process %s is not running. not need stop.",pu->strappname.data());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ pu->mProcess->terminate();
|
|
|
+ std::this_thread::sleep_for(std::chrono::milliseconds(300));
|
|
|
+ pu->mProcess->kill();
|
|
|
+
|
|
|
+ if(!checkStartState(pu)){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ //modify tjc
|
|
|
+ //发送dbus信号使程序退出
|
|
|
+ QDBusMessage msg = QDBusMessage::createSignal("/catarc/adc", "adciv.sys.stop.interface", pu->strappname.data());
|
|
|
+ QDBusConnection::sessionBus().send(msg);
|
|
|
+// ivlog->info("dispatch %s exit", pu->strappname.c_str());
|
|
|
+ pu->state = 0;
|
|
|
+ emit checkExit(pu);
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::ForceStopProc(ProgUnit *pu){
|
|
|
+ if(pu == 0)return;
|
|
|
+ if(pu->mProcess == 0)return;
|
|
|
+ pu->mProcess->kill();
|
|
|
+ return;
|
|
|
+
|
|
|
+ if(!checkStartState(pu)){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ //modify tjc
|
|
|
+ //发送dbus信号使程序退出
|
|
|
+ QDBusMessage msg = QDBusMessage::createSignal("/catarc/adc", "adciv.sys.stop.interface", pu->strappname.data());
|
|
|
+ QDBusConnection::sessionBus().send(msg);
|
|
|
+// ivlog->info("dispatch %s exit", pu->strappname.c_str());
|
|
|
+ pu->state = 0;
|
|
|
+ emit checkExit(pu);
|
|
|
+}
|
|
|
+
|
|
|
+//void ProgMon::ForceStopProc(ProgUnit *pu){
|
|
|
+// if(pu == 0)return;
|
|
|
+// if(pu->mProcess == 0)return;
|
|
|
+// pu->mProcess->kill();
|
|
|
+//}
|
|
|
+
|
|
|
+bool ProgMon::onCheckExit(ProgUnit *pu){
|
|
|
+ int count = 0;
|
|
|
+ while(!pu->state){
|
|
|
+
|
|
|
+ if(checkStartState(pu)){
|
|
|
+ count++;
|
|
|
+ QThread::msleep(200);
|
|
|
+ if(count >= 5){
|
|
|
+ //退出延迟警告
|
|
|
+ // ivfault->SetFaultState(1,0x0005,(pu->strappname + ": process exit exception").data());
|
|
|
+ // ivlog->warn("%s : process exit exception", pu->strappname.data());
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if(count >= 15){
|
|
|
+ //模块退出故障,未能正常退出,取消退出
|
|
|
+// ivfault->SetFaultState(2,0x0006,(pu->strappname + ": process exit exception").data());
|
|
|
+ // ivlog->error("%s : process exit exception", pu->strappname.data());
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ pu->mbRun = false;
|
|
|
+ pu->UpdateResState();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+bool ProgMon::checkStartState(ProgUnit *pu){
|
|
|
+// Q_PID pid = pu->mProcess->pid();
|
|
|
+
|
|
|
+ unsigned int npid;
|
|
|
+#ifdef IV_OS_UNIX
|
|
|
+ npid = pu->mProcess->processId();
|
|
|
+// npid = pu->mProcess->pid();
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef IV_OS_WIN
|
|
|
+ npid = pu->mProcess->pid()->dwProcessId;
|
|
|
+#endif
|
|
|
+ float cput = get_proc_cpu(npid);
|
|
|
+ unsigned int memt = get_proc_mem(npid);
|
|
|
+ unsigned int threadnumt = get_proc_threadnum(npid);
|
|
|
+ if(threadnumt || memt || cput){
|
|
|
+ return true;
|
|
|
+ }else{
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::run()
|
|
|
+{
|
|
|
+ qint64 interval = 1000;
|
|
|
+ qint64 nLastUpdate = 0;
|
|
|
+ while(!QThread::isInterruptionRequested())
|
|
|
+ {
|
|
|
+ qint64 nNow = QDateTime::currentMSecsSinceEpoch();
|
|
|
+ if((nNow - nLastUpdate)< interval)
|
|
|
+ {
|
|
|
+ msleep(10);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ QString strsysinfo;
|
|
|
+ mPMS.UpdateCPUMemStat(strsysinfo);
|
|
|
+ mMutexSysinfo.lock();
|
|
|
+ mstrsysInfo = strsysinfo;
|
|
|
+ mMutexSysinfo.unlock();
|
|
|
+ nLastUpdate = nNow;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for(i=0;i<static_cast<int>(mvectorprog.size()) ;i++)
|
|
|
+ {
|
|
|
+ mMutex.lock();
|
|
|
+ mvectorprog[i].UpdateResState();
|
|
|
+ if(QThread::isInterruptionRequested())
|
|
|
+ {
|
|
|
+ mMutex.unlock();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ mMutex.unlock();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::setquit()
|
|
|
+{
|
|
|
+ mbquit = true;
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::threaderrout()
|
|
|
+{
|
|
|
+ QString strhomepath = getenv("HOME");
|
|
|
+
|
|
|
+ int nNeedCheckSpace = 0;
|
|
|
+
|
|
|
+ bool bHaveHDDSpace = true;
|
|
|
+
|
|
|
+ unsigned int i;
|
|
|
+
|
|
|
+ while(mberroutrun)
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+ std::vector<stdoutunit> xvectorerrout;
|
|
|
+ mMutex_errout.lock();
|
|
|
+ xvectorerrout= mvectorerrout;
|
|
|
+ mvectorerrout.clear();
|
|
|
+ mMutex_errout.unlock();
|
|
|
+ if(xvectorerrout.size() == 0)
|
|
|
+ {
|
|
|
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+
|
|
|
+ if(bHaveHDDSpace == false)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ for(i=0;i<xvectorerrout.size();i++)
|
|
|
+ {
|
|
|
+ unsigned int j;
|
|
|
+ std::string strappname;
|
|
|
+ std::string strarg;
|
|
|
+ bool bFind = false;
|
|
|
+ mMutex.lock();
|
|
|
+ for(j=0;j<mvectorprog.size();j++)
|
|
|
+ {
|
|
|
+ ProgUnit *pu = &(mvectorprog.at(j));
|
|
|
+ if(xvectorerrout[i].mpProc == pu->mProcess)
|
|
|
+ {
|
|
|
+ strappname = pu->strappname;
|
|
|
+ strarg = pu->strargs;
|
|
|
+ bFind = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mMutex.unlock();
|
|
|
+
|
|
|
+ if(bFind)
|
|
|
+ {
|
|
|
+
|
|
|
+ if(nNeedCheckSpace <= 0)
|
|
|
+ {
|
|
|
+ // std::cout<<"check space."<<std::endl;
|
|
|
+ nNeedCheckSpace = 1000;
|
|
|
+ int nSpace = get_path_availspace(strhomepath);
|
|
|
+
|
|
|
+ // std::cout<<"hard space is "<<nSpace<<" MB."<<std::endl;
|
|
|
+ if(nSpace<1000)
|
|
|
+ {
|
|
|
+ std::cout<<"Hard Disk No space to save std log."<<std::endl;
|
|
|
+ bHaveHDDSpace = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ nNeedCheckSpace--;
|
|
|
+ if(bHaveHDDSpace)
|
|
|
+ {
|
|
|
+ QString strlog;
|
|
|
+ strlog = QDateTime::currentDateTime().toString("(yyyy/MM/dd hh:mm:ss:zzz")
|
|
|
+ + " | " + strappname.data() + " "+ strarg.data() + ")"
|
|
|
+ +xvectorerrout[i].mba.data();
|
|
|
+ WriteLog(strlog.toLatin1().data());
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::cout<<"not found a std out 's process."<<std::endl;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ std::cout<<"threaderrout complete."<<std::endl;
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::threadstdout()
|
|
|
+{
|
|
|
+
|
|
|
+ QString strhomepath = getenv("HOME");
|
|
|
+
|
|
|
+ int nNeedCheckSpace = 0;
|
|
|
+
|
|
|
+ bool bHaveHDDSpace = true;
|
|
|
+
|
|
|
+ while(mbstdoutrun)
|
|
|
+ {
|
|
|
+ bool bAllNoLog = true;
|
|
|
+ unsigned int i;
|
|
|
+ mMutex.lock();
|
|
|
+ for(i=0;i<mvectorprog.size();i++)
|
|
|
+ {
|
|
|
+ if(mvectorprog[i].mbSavestdout)
|
|
|
+ {
|
|
|
+ bAllNoLog = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mMutex.unlock();
|
|
|
+
|
|
|
+ if(mbAllNoLog != bAllNoLog)
|
|
|
+ {
|
|
|
+ mbAllNoLog = bAllNoLog;
|
|
|
+ if(bAllNoLog == true)
|
|
|
+ {
|
|
|
+ mMutex_stdout.lock();
|
|
|
+ mvectorstdout.clear();
|
|
|
+ mMutex_stdout.unlock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(mbAllNoLog == true)
|
|
|
+ {
|
|
|
+ msleep(100);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::vector<stdoutunit> xvectorstdout;
|
|
|
+ mMutex_stdout.lock();
|
|
|
+ xvectorstdout= mvectorstdout;
|
|
|
+ mvectorstdout.clear();
|
|
|
+ mMutex_stdout.unlock();
|
|
|
+ if(xvectorstdout.size() == 0)
|
|
|
+ {
|
|
|
+ msleep(10);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+
|
|
|
+ if(bHaveHDDSpace == false)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ for(i=0;i<xvectorstdout.size();i++)
|
|
|
+ {
|
|
|
+ unsigned int j;
|
|
|
+ std::string strappname;
|
|
|
+ std::string strarg;
|
|
|
+ bool bFind = false;
|
|
|
+ bool bSave = false;
|
|
|
+ mMutex.lock();
|
|
|
+ for(j=0;j<mvectorprog.size();j++)
|
|
|
+ {
|
|
|
+ ProgUnit *pu = &(mvectorprog.at(j));
|
|
|
+ if(xvectorstdout[i].mpProc == pu->mProcess)
|
|
|
+ {
|
|
|
+ strappname = pu->strappname;
|
|
|
+ strarg = pu->strargs;
|
|
|
+ bFind = true;
|
|
|
+ bSave = pu->mbSavestdout;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mMutex.unlock();
|
|
|
+
|
|
|
+ if(bFind)
|
|
|
+ {
|
|
|
+ if(bSave)
|
|
|
+ {
|
|
|
+ if(nNeedCheckSpace <= 0)
|
|
|
+ {
|
|
|
+ // std::cout<<"check space."<<std::endl;
|
|
|
+ nNeedCheckSpace = 1000;
|
|
|
+ int nSpace = get_path_availspace(strhomepath);
|
|
|
+
|
|
|
+ // std::cout<<"hard space is "<<nSpace<<" MB."<<std::endl;
|
|
|
+ if(nSpace<1000)
|
|
|
+ {
|
|
|
+ std::cout<<"Hard Disk No space to save std log."<<std::endl;
|
|
|
+ bHaveHDDSpace = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ nNeedCheckSpace--;
|
|
|
+ if(bHaveHDDSpace)
|
|
|
+ {
|
|
|
+ QString strlog;
|
|
|
+ strlog = QDateTime::currentDateTime().toString("(yyyy/MM/dd hh:mm:ss:zzz")
|
|
|
+ + " | " + strappname.data() + " "+ strarg.data() + ")"
|
|
|
+ +xvectorstdout[i].mba.data();
|
|
|
+ WriteStdLog(strlog.toLatin1().data());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::cout<<"not found a std out 's process."<<std::endl;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ std::cout<<"threadstdout complete."<<std::endl;
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::LogError(QProcess *proc, QByteArray &ba)
|
|
|
+{
|
|
|
+// std::cout<<"error is "<<ba.data()<<std::endl;
|
|
|
+
|
|
|
+ static int nCheckSpace = 0;
|
|
|
+ static bool bSave = true;
|
|
|
+ if(bSave == false)return;
|
|
|
+ if(nCheckSpace<=0)
|
|
|
+ {
|
|
|
+ nCheckSpace = 10000;
|
|
|
+ QString strhomepath = getenv("HOME");
|
|
|
+ if(get_path_availspace(strhomepath)<100)
|
|
|
+ {
|
|
|
+ bSave = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ nCheckSpace--;
|
|
|
+ unsigned int i;
|
|
|
+ std::string strappname;
|
|
|
+ std::string strarg;
|
|
|
+ bool bFind = false;
|
|
|
+ mMutex.lock();
|
|
|
+ for(i=0;i<mvectorprog.size();i++)
|
|
|
+ {
|
|
|
+ ProgUnit *pu = &(mvectorprog.at(i));
|
|
|
+ if(proc == pu->mProcess)
|
|
|
+ {
|
|
|
+ strappname = pu->strappname;
|
|
|
+ strarg = pu->strargs;
|
|
|
+ bFind = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mMutex.unlock();
|
|
|
+
|
|
|
+ if(bFind)
|
|
|
+ {
|
|
|
+ QString strlog;
|
|
|
+ strlog = QDateTime::currentDateTime().toString("(yyyy/MM/dd hh:mm:ss:zzz")
|
|
|
+ + " | " + strappname.data() + " "+ strarg.data() + ")"
|
|
|
+ +ba.data();
|
|
|
+ WriteLog(strlog.toLatin1().data());
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::InitLog()
|
|
|
+{
|
|
|
+ QString strpath = getenv("HOME");
|
|
|
+
|
|
|
+ strpath = strpath + "/log";
|
|
|
+ QDir xDir(strpath);
|
|
|
+ if(xDir.exists() == false)
|
|
|
+ {
|
|
|
+ std::cout<<"dir "<<strpath.toLatin1().data()<<" not exist . Create it."<<std::endl;
|
|
|
+ if(xDir.mkdir(strpath) == false)
|
|
|
+ {
|
|
|
+ std::cout<<"make dir faile . dir is "<<strpath.toLatin1().data()<<std::endl;
|
|
|
+ mbFileLog = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ QString strname = "IVSysMan-errlog-" + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz.log");
|
|
|
+ QString strstdname = "IVSysMan-stdlog-" + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz.log");
|
|
|
+ QString strstdpath = strpath + "/" + strstdname;
|
|
|
+ strpath = strpath +"/" + strname;
|
|
|
+
|
|
|
+ mFileLog.setFileName(strpath);
|
|
|
+
|
|
|
+ if(mFileLog.open(QIODevice::ReadWrite))
|
|
|
+ {
|
|
|
+ mbFileLog = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::cout<<" Create error log File Fail. File Path is "<<strpath.toLatin1().data()<<std::endl;
|
|
|
+ mbFileLog = false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ mFileStdLog.setFileName(strstdpath);
|
|
|
+
|
|
|
+ if(mFileStdLog.open(QIODevice::ReadWrite))
|
|
|
+ {
|
|
|
+ mbFileStdLog = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::cout<<" Create std log File Fail. File Path is "<<strpath.toLatin1().data()<<std::endl;
|
|
|
+ mbFileStdLog = false;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::WriteLog(const char *strlog)
|
|
|
+{
|
|
|
+ if(mbFileLog)
|
|
|
+ {
|
|
|
+ mFileLog.write(strlog,strnlen(strlog,100000));
|
|
|
+// mFileLog.flush();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void ProgMon::WriteStdLog(const char *strlog)
|
|
|
+{
|
|
|
+ if(mbFileStdLog)
|
|
|
+ {
|
|
|
+ mFileStdLog.write(strlog,strnlen(strlog,100000));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int ProgMon::get_path_availspace(const QString & path)
|
|
|
+{
|
|
|
+#ifdef OS_UNIX
|
|
|
+ struct statfs diskInfo;
|
|
|
+ statfs(path.toUtf8().data(), &diskInfo);
|
|
|
+
|
|
|
+ qDebug("%s 总大小:%.0lfMB 可用大小:%.0lfMB",path.toStdString().c_str(),(diskInfo.f_blocks * diskInfo.f_bsize)/1024.0/1024.0,(diskInfo.f_bavail * diskInfo.f_bsize)/1024.0/1024.0);
|
|
|
+ return (diskInfo.f_bavail * diskInfo.f_bsize)/1024.0/1024.0;
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef OS_WIN
|
|
|
+ LPCWSTR lpcwstrDriver=(LPCWSTR)path.utf16();
|
|
|
+
|
|
|
+ ULARGE_INTEGER liFreeBytesAvailable, liTotalBytes, liTotalFreeBytes;
|
|
|
+
|
|
|
+ if( !GetDiskFreeSpaceEx( lpcwstrDriver, &liFreeBytesAvailable, &liTotalBytes, &liTotalFreeBytes) )
|
|
|
+ {
|
|
|
+ qDebug() << "ERROR: Call to GetDiskFreeSpaceEx() failed.";
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return (quint64) liTotalFreeBytes.QuadPart/1024/1024;
|
|
|
+
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+void ProgMon::UpdateCPUMemStat()
|
|
|
+{
|
|
|
+ return;
|
|
|
+ static qint64 nLastCPUTotal,nLastIdleTotal;
|
|
|
+ (void)nLastCPUTotal;
|
|
|
+ (void)nLastIdleTotal;
|
|
|
+ static std::vector<qint64> nVectorLastCPU;
|
|
|
+ static std::vector<qint64> nVectorLastIdle;
|
|
|
+
|
|
|
+ QFile xFileStat;
|
|
|
+ xFileStat.setFileName("/proc/stat");
|
|
|
+ if(xFileStat.open(QIODevice::ReadOnly))
|
|
|
+ {
|
|
|
+ QByteArray ba = xFileStat.readAll();
|
|
|
+ QList<QByteArray> xlist = ba.split('\n');
|
|
|
+ int nsize = xlist.size();
|
|
|
+ (void)nsize;
|
|
|
+ }
|
|
|
+ xFileStat.close();
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+QString ProgMon::GetSysInfo()
|
|
|
+{
|
|
|
+ QString strsysinfo;
|
|
|
+ mMutexSysinfo.lock();
|
|
|
+ strsysinfo = mstrsysInfo;
|
|
|
+ mMutexSysinfo.unlock();
|
|
|
+ return strsysinfo;
|
|
|
+}
|
|
|
+
|