#include "progmon.h" #include #include #ifdef OS_UNIX #include "sys/statfs.h" #endif #ifdef OS_WIN #include #endif extern iv::Ivlog * ivlog; extern iv::Ivfault * ivfault; ProgMon::ProgMon(std::string path) { mvectorprog = loadprogunit(path); InitLog(); mpthread_stdout = new std::thread(&ProgMon::threadstdout,this); } ProgMon::~ProgMon() { mbstdoutrun = false; mpthread_stdout->join(); if(mbFileStdLog) { mbFileStdLog = false; qint64 nsize = mFileStdLog.size(); mFileStdLog.close(); if(nsize == 0) { std::cout<<"Because no std log, delete std log. "<kill(); // mvectorprog[i].mProcess->close(); } } mvectorprog.clear(); } std::vector ProgMon::loadprogunit(std::string path) { std::vector xvectorprog; QDomDocument doc; qDebug()<<"path: "< 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(); } } void ProgMon::updatexml(std::string path) { mMutex.lock(); std::vector xvectorprog = loadprogunit(path); int i; int nsize = mvectorprog.size(); int nnewsize = xvectorprog.size(); //Start new xml have program. for(i=0;istrcmd.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<strcmd.data()<<" is exist. "<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;iSetFaultState(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(); 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;imProcess) { pu->mbRun = false; emit SigProcStoped(pu); if(mbquit) { std::cout<<"Program "<strappname<<" quit."<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(); if(proc->currentWriteChannel() == 1) { std::cout<<"Receive a Error Output."<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;istrappname) { 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->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->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(100); continue; } nLastUpdate = nNow; int i; for(i=0;i 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;imProcess) { 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."<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 "<