progmon.cpp 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  1. #include "progmon.h"
  2. #include <QFile>
  3. #include <iostream>
  4. #ifdef OS_UNIX
  5. #include "sys/statfs.h"
  6. #endif
  7. #ifdef OS_WIN
  8. #include <windows.h>
  9. #endif
  10. extern iv::Ivlog * ivlog;
  11. extern iv::Ivfault * ivfault;
  12. ProgMon::ProgMon(std::string path)
  13. {
  14. UpdateCPUMemStat();
  15. mvectorprog = loadprogunit(path);
  16. InitLog();
  17. mpthread_stdout = new std::thread(&ProgMon::threadstdout,this);
  18. mpthread_errout = new std::thread(&ProgMon::threaderrout,this);
  19. }
  20. ProgMon::~ProgMon()
  21. {
  22. std::cout<<"~ProgMon"<<std::endl;
  23. unsigned int i;
  24. for(i=0;i<mvectorprog.size();i++)
  25. {
  26. if(mvectorprog[i].mProcess != 0)
  27. {
  28. mvectorprog[i].mProcess->terminate();
  29. // mvectorprog[i].mProcess->close();
  30. }
  31. }
  32. QThread::msleep(300);
  33. for(i=0;i<mvectorprog.size();i++)
  34. {
  35. if(mvectorprog[i].mProcess != 0)
  36. {
  37. mvectorprog[i].mProcess->kill();
  38. // mvectorprog[i].mProcess->close();
  39. }
  40. }
  41. std::cout<<"End Std out thread."<<std::endl;
  42. mbstdoutrun = false;
  43. mpthread_stdout->join();
  44. std::cout<<"End Err out thread."<<std::endl;
  45. mberroutrun = false;
  46. mpthread_errout->join();
  47. if(mbFileStdLog)
  48. {
  49. mbFileStdLog = false;
  50. qint64 nsize = mFileStdLog.size();
  51. mFileStdLog.close();
  52. if(nsize == 0)
  53. {
  54. std::cout<<"Because no std log, delete std log. "<<std::endl;
  55. mFileStdLog.remove();
  56. }
  57. }
  58. if(mbFileLog)
  59. {
  60. mbFileLog = false;
  61. qint64 nsize = mFileLog.size();
  62. mFileLog.close();
  63. if(nsize == 0)
  64. {
  65. std::cout<<"Because no error log, delete error log. "<<std::endl;
  66. mFileLog.remove();
  67. }
  68. }
  69. // mvectorprog.clear();
  70. }
  71. std::vector<ProgUnit> ProgMon::loadprogunit(std::string path)
  72. {
  73. std::vector<ProgUnit> xvectorprog;
  74. QDomDocument doc;
  75. qDebug()<<"path: "<<path.data()<<endl;
  76. QFile file(path.data());
  77. if (!file.open(QIODevice::ReadOnly))
  78. return xvectorprog;
  79. if (!doc.setContent(&file)) {
  80. file.close();
  81. return xvectorprog;
  82. }
  83. file.close();
  84. //遍历节点,从配置文件中获取当前有哪些模块,并拼接启动命令和启动参数_tjc
  85. QDomElement docElem = doc.documentElement();
  86. QDomNode n = docElem.firstChild();
  87. std::string defdir = "./";
  88. while(!n.isNull())
  89. {
  90. QDomElement e = n.toElement(); // 尝试将节点转换为元素
  91. std::string name = e.nodeName().toStdString();
  92. if(name == "setting")
  93. {
  94. defdir = e.attribute("defaultpath","./").toStdString();
  95. break;
  96. }
  97. n = n.nextSibling();
  98. }
  99. n = docElem.firstChild();
  100. while(!n.isNull())
  101. {
  102. QDomElement e = n.toElement(); // 尝试将节点转换为元素
  103. std::string name = e.nodeName().toStdString();
  104. if(name == "module")
  105. {
  106. std::string appname = e.attribute("app","").toStdString();
  107. std::string strdir = e.attribute("dir","").toStdString();
  108. std::string strargs = e.attribute("args","").toStdString();
  109. std::string strbstart = e.attribute("autostart","false").toStdString();
  110. std::string strgroup = e.attribute("group","unknown").toStdString();
  111. std::string strsavestd = e.attribute("savestd","false").toStdString();
  112. ProgUnit x;
  113. if(strbstart == "true")x.mbautostart = true;
  114. else x.mbautostart = false;
  115. x.strappdir = strdir;
  116. x.strappname = appname;
  117. x.strargs = strargs;
  118. x.strgroup = strgroup;
  119. x.mProcess = 0;
  120. x.mbSavestdout = false;
  121. if(strsavestd == "true")x.mbSavestdout = true;
  122. if(x.strappname.length() > 0)
  123. {
  124. x.strcmd = x.strappdir;
  125. if(x.strcmd.length()<1)
  126. {
  127. x.strcmd = defdir;
  128. }
  129. if(x.strcmd.length() > 0)
  130. {
  131. if(x.strcmd.at(x.strcmd.length() -1) != '/')
  132. {
  133. x.strcmd.append("/");
  134. }
  135. }
  136. x.strcmd.append(x.strappname);
  137. if(x.strargs.length() > 0)
  138. {
  139. x.strcmd.append(" ");
  140. x.strcmd.append(x.strargs);
  141. }
  142. xvectorprog.push_back(x);
  143. }
  144. }
  145. n = n.nextSibling();
  146. }
  147. }
  148. void ProgMon::updatexml(std::string path)
  149. {
  150. mMutex.lock();
  151. std::vector<ProgUnit> xvectorprog = loadprogunit(path);
  152. int i;
  153. int nsize = mvectorprog.size();
  154. int nnewsize = xvectorprog.size();
  155. //Start new xml have program.
  156. for(i=0;i<nnewsize;i++)
  157. {
  158. ProgUnit * pnewPU = &(xvectorprog[i]);
  159. int j;
  160. bool bNew = true;
  161. nsize = mvectorprog.size();
  162. int noldpos = -1;
  163. for(j=0;j<nsize;j++)
  164. {
  165. if(strncmp(mvectorprog[j].strcmd.data(),pnewPU->strcmd.data(),255) == 0)
  166. {
  167. bNew = false;
  168. noldpos = j;
  169. break;
  170. }
  171. }
  172. if(bNew == true)
  173. {
  174. mvectorprog.push_back(*pnewPU);
  175. if(pnewPU->mbautostart) StartProc(&mvectorprog[mvectorprog.size() -1]);
  176. }
  177. else
  178. {
  179. std::cout<<pnewPU->strcmd.data()<<" is exist. "<<std::endl;
  180. }
  181. }
  182. //Stop And Delete new xml not have item.
  183. nsize = mvectorprog.size();
  184. for(i=0;i<mvectorprog.size();i++)
  185. {
  186. int j;
  187. bool bNewHave = false;
  188. for(j=0;j<nnewsize;j++)
  189. {
  190. if(strncmp(mvectorprog[i].strcmd.data(),xvectorprog[j].strcmd.data(),255) == 0)
  191. {
  192. bNewHave = true;
  193. break;
  194. }
  195. }
  196. if(bNewHave == false)
  197. {
  198. if(mvectorprog[i].mbRun)
  199. {
  200. StopProc(&mvectorprog[i]);
  201. }
  202. mvectorprog.erase(mvectorprog.begin()+i);
  203. i--;
  204. }
  205. }
  206. mMutex.unlock();
  207. // nsize = mvectorprog.size();
  208. // nsize = nsize +1-1;
  209. }
  210. void ProgMon::onProcessStarted()
  211. {
  212. // qDebug("started.");
  213. QProcess * proc = (QProcess *)sender();
  214. int nsize = mvectorprog.size();
  215. int i;
  216. for(i=0;i<nsize;i++)
  217. {
  218. if(proc == mvectorprog.at(i).mProcess)
  219. {
  220. mvectorprog.at(i).mbRun = true;
  221. #ifdef IV_OS_UNIX
  222. mvectorprog.at(i).mpid = proc->pid();
  223. #endif
  224. #ifdef IV_OS_WIN
  225. mvectorprog.at(i).mpid = proc->pid()->dwProcessId;
  226. #endif
  227. mvectorprog.at(i).mnStartCount++;
  228. // qDebug("program id is %ld",mvectorprog.at(i).mpid);
  229. emit SigProcStarted(&(mvectorprog.at(i)));
  230. break;
  231. // qDebug("find procname is %s",mvectorprog.at(i).strcmd.data());
  232. }
  233. }
  234. }
  235. //add tjc
  236. void ProgMon::onProcessErrorStarted(QProcess::ProcessError error){
  237. qDebug("Process Error Started.");
  238. std::string desc;
  239. int code;
  240. QProcess * proc = (QProcess*)sender();
  241. int nsize = mvectorprog.size();
  242. int i;
  243. for(i=0;i<nsize;i++)
  244. {
  245. if(proc == mvectorprog.at(i).mProcess)
  246. {
  247. if(error == QProcess::ProcessError::FailedToStart){
  248. //启动错误 启动失败
  249. code = 0x0001;
  250. }else{
  251. //未知错误 启动失败
  252. code = 0x0002;
  253. }
  254. desc = mvectorprog.at(i).strappname + ":FailedToStart";
  255. //记录故障状态,模块启动失败
  256. ivfault->SetFaultState(2,code,desc.c_str());
  257. }
  258. }
  259. }
  260. void ProgMon::onReadStandardOutput()
  261. {
  262. QProcess * proc = (QProcess *)sender();
  263. QByteArray ba = proc->readAllStandardOutput();
  264. if(mbAllNoLog == false)
  265. {
  266. mMutex_stdout.lock();
  267. if(mvectorstdout.size()<1000) mvectorstdout.push_back(stdoutunit(proc,ba));
  268. mMutex_stdout.unlock();
  269. }
  270. // qDebug("process out: %s ",ba.data());
  271. }
  272. void ProgMon::onReadStandardError()
  273. {
  274. QProcess * proc = (QProcess *)sender();
  275. QByteArray ba = proc->readAllStandardError();
  276. mMutex_errout.lock();
  277. if(mvectorerrout.size()<1000) mvectorerrout.push_back(stdoutunit(proc,ba));
  278. mMutex_errout.unlock();
  279. return;
  280. if(ba.size() == 0)return;
  281. LogError(proc,ba);
  282. // if(mbAllNoLog == false)
  283. // {
  284. // mMutex_stdout.lock();
  285. // if(mvectorstdout.size()<1000) mvectorstdout.push_back(stdoutunit(proc,ba));
  286. // mMutex_stdout.unlock();
  287. // }
  288. // qDebug("process error: %s ",ba.data());
  289. }
  290. void ProgMon::onProcessEnd()
  291. {
  292. qDebug("process end.");
  293. QProcess * proc = (QProcess *)sender();
  294. int nsize = mvectorprog.size();
  295. int i;
  296. for(i=0;i<nsize;i++)
  297. {
  298. ProgUnit *pu = &(mvectorprog.at(i));
  299. if(proc == pu->mProcess)
  300. {
  301. pu->mbRun = false;
  302. emit SigProcStoped(pu);
  303. if(mbquit)
  304. {
  305. std::cout<<"Program "<<pu->strappname<<" quit."<<std::endl;
  306. break;
  307. }
  308. // delete pu->mProcess;
  309. if(pu->mbautostart)
  310. {
  311. ivfault->SetFaultState(1,0x0003,(pu->strappname + " abnormal stop").data());
  312. ivlog->warn("%s : process abnormal stop", pu->strappname.data());
  313. StartProc(&(mvectorprog.at(i)));
  314. }
  315. //if autostart
  316. //modify tjc
  317. // if(pu->mbautostart && pu->state && proc->exitCode() != 0)
  318. // {
  319. // //警告 进程异常关闭
  320. // ivfault->SetFaultState(1,0x0003,(pu->strappname + " abnormal stop").data());
  321. // ivlog->warn("%s : process abnormal stop", pu->strappname.data());
  322. // //两分钟内重启三次则终止该模块
  323. // if(pu->timeRec.isNull()){
  324. // pu->timeRec = QTime::currentTime();
  325. // }
  326. // int elapsed = pu->timeRec.msecsTo(QTime::currentTime());
  327. // if(elapsed > 1000 * 60 * 2){
  328. // pu->timeRec = QTime::currentTime();
  329. // pu->count = 0;
  330. // }else{
  331. // if(pu->count <= 3){
  332. // pu->count++;
  333. // }else{
  334. // //停止该模块的启动并报故障
  335. // pu->state = 0;
  336. // //故障 进程多次异常关闭,不再启动该进程
  337. // ivfault->SetFaultState(2,0x0004,(pu->strappname + " exception stop").data());
  338. // ivlog->error("%s : process exception stop", pu->strappname.data());
  339. // return;
  340. // }
  341. // }
  342. // StartProc(&(mvectorprog.at(i)));
  343. // }
  344. break;
  345. // qDebug("find procname is %s",mvectorprog.at(i).strcmd.data());
  346. }
  347. }
  348. }
  349. void ProgMon::onChRead()
  350. {
  351. QProcess * proc = (QProcess *)sender();
  352. QByteArray ba = proc->readAll();
  353. int ncha = proc->currentWriteChannel();
  354. if(proc->currentWriteChannel() == 1)
  355. {
  356. std::cout<<"Receive a Error Output."<<std::endl;
  357. LogError(proc,ba);
  358. }
  359. #ifdef QT_DEBUG
  360. // qDebug("process INFO: %s ", ba.data());
  361. #endif
  362. if(mbAllNoLog == false)
  363. {
  364. mMutex_stdout.lock();
  365. if(mvectorstdout.size()<1000) mvectorstdout.push_back(stdoutunit(proc,ba));
  366. mMutex_stdout.unlock();
  367. }
  368. // qDebug("read chanel count is :%d ",proc->readChannelCount());
  369. }
  370. void ProgMon::restartProc(ProgUnit *pu){
  371. if(pu == 0)return;
  372. //判断项目当前是否启动状态
  373. if(checkStartState(pu)){
  374. return;
  375. }
  376. if(pu->mProcess == 0){
  377. StartProc(pu);
  378. }
  379. pu->mProcess->start();
  380. pu->state = 1;
  381. 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());
  382. }
  383. ProgUnit * ProgMon::FindProcByName(std::string strappname, std::string strargs)
  384. {
  385. ProgUnit * pu = 0;
  386. int i;
  387. int nsize = mvectorprog.size();
  388. for(i=0;i<nsize;i++)
  389. {
  390. ProgUnit * putem = &mvectorprog.at(i);
  391. if(strargs.size()<1)
  392. {
  393. if(strappname == putem->strappname)
  394. {
  395. pu = putem;
  396. break;
  397. }
  398. }
  399. else
  400. {
  401. if((strappname == putem->strappname)&&(strargs == putem->strargs))
  402. {
  403. pu = putem;
  404. break;
  405. }
  406. }
  407. }
  408. return pu;
  409. }
  410. void ProgMon::StartProc(std::string strappname, std::string strargs)
  411. {
  412. ProgUnit * pu = FindProcByName(strappname,strargs);
  413. if(pu == 0)
  414. {
  415. qDebug("StartProc can't find app = %s args = %s",strappname.data(),strargs.data());
  416. return;
  417. }
  418. pu->mbautostart = false;
  419. StartProc(pu);
  420. }
  421. void ProgMon::StopProc(std::string strappname, std::string strargs)
  422. {
  423. ProgUnit * pu = FindProcByName(strappname,strargs);
  424. if(pu == 0)
  425. {
  426. qDebug("StopProc can't find app = %s args = %s",strappname.data(),strargs.data());
  427. return;
  428. }
  429. pu->mbautostart = false;
  430. StopProc(pu);
  431. }
  432. void ProgMon::StartProc(ProgUnit *pu)
  433. {
  434. if(pu->mbRun)
  435. {
  436. qDebug("process %s is running. not need start.",pu->strappname.data());
  437. return;
  438. }
  439. pu->mProcess = new QProcess(this);
  440. connect(pu->mProcess,SIGNAL(started()),this,SLOT(onProcessStarted()));
  441. connect(pu->mProcess,SIGNAL(finished(int)),this,SLOT(onProcessEnd()));
  442. // connect(pu->mProcess,SIGNAL(readyRead()),this,SLOT(onChRead()));
  443. connect(pu->mProcess,SIGNAL(readyReadStandardOutput()),this,SLOT(onReadStandardOutput()));
  444. connect(pu->mProcess,SIGNAL(readyReadStandardError()),this,SLOT(onReadStandardError()));
  445. connect(pu->mProcess,SIGNAL(error(QProcess::ProcessError)),this,SLOT(onProcessErrorStarted(QProcess::ProcessError)));
  446. pu->mProcess->start(pu->strcmd.data());
  447. pu->state = 1;
  448. 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());
  449. }
  450. //test
  451. void ProgMon::StopProcTest(){
  452. int nsize = mvectorprog.size();
  453. for (int i = 0; i < nsize; i++) {
  454. ProgUnit * ppu = &(mvectorprog.at(i));
  455. StopProc(ppu);
  456. }
  457. }
  458. void ProgMon::StopProc(ProgUnit *pu)
  459. {
  460. if(pu == 0)return;
  461. if(pu->mProcess == 0)return;
  462. if(!pu->mbRun)
  463. {
  464. qDebug("process %s is not running. not need stop.",pu->strappname.data());
  465. return;
  466. }
  467. pu->mProcess->terminate();
  468. std::this_thread::sleep_for(std::chrono::milliseconds(300));
  469. pu->mProcess->kill();
  470. if(!checkStartState(pu)){
  471. return;
  472. }
  473. //modify tjc
  474. //发送dbus信号使程序退出
  475. QDBusMessage msg = QDBusMessage::createSignal("/catarc/adc", "adciv.sys.stop.interface", pu->strappname.data());
  476. QDBusConnection::sessionBus().send(msg);
  477. ivlog->info("dispatch %s exit", pu->strappname.c_str());
  478. pu->state = 0;
  479. emit checkExit(pu);
  480. }
  481. void ProgMon::ForceStopProc(ProgUnit *pu){
  482. if(pu == 0)return;
  483. if(pu->mProcess == 0)return;
  484. pu->mProcess->kill();
  485. return;
  486. if(!checkStartState(pu)){
  487. return;
  488. }
  489. //modify tjc
  490. //发送dbus信号使程序退出
  491. QDBusMessage msg = QDBusMessage::createSignal("/catarc/adc", "adciv.sys.stop.interface", pu->strappname.data());
  492. QDBusConnection::sessionBus().send(msg);
  493. ivlog->info("dispatch %s exit", pu->strappname.c_str());
  494. pu->state = 0;
  495. emit checkExit(pu);
  496. }
  497. //void ProgMon::ForceStopProc(ProgUnit *pu){
  498. // if(pu == 0)return;
  499. // if(pu->mProcess == 0)return;
  500. // pu->mProcess->kill();
  501. //}
  502. bool ProgMon::onCheckExit(ProgUnit *pu){
  503. int count = 0;
  504. while(!pu->state){
  505. if(checkStartState(pu)){
  506. count++;
  507. QThread::msleep(200);
  508. if(count >= 5){
  509. //退出延迟警告
  510. ivfault->SetFaultState(1,0x0005,(pu->strappname + ": process exit exception").data());
  511. ivlog->warn("%s : process exit exception", pu->strappname.data());
  512. return false;
  513. }
  514. if(count >= 15){
  515. //模块退出故障,未能正常退出,取消退出
  516. ivfault->SetFaultState(2,0x0006,(pu->strappname + ": process exit exception").data());
  517. ivlog->error("%s : process exit exception", pu->strappname.data());
  518. }
  519. }else{
  520. pu->mbRun = false;
  521. pu->UpdateResState();
  522. return true;
  523. }
  524. }
  525. }
  526. bool ProgMon::checkStartState(ProgUnit *pu){
  527. // Q_PID pid = pu->mProcess->pid();
  528. unsigned int npid;
  529. #ifdef IV_OS_UNIX
  530. npid = pu->mProcess->pid();
  531. #endif
  532. #ifdef IV_OS_WIN
  533. npid = pu->mProcess->pid()->dwProcessId;
  534. #endif
  535. float cput = get_proc_cpu(npid);
  536. unsigned int memt = get_proc_mem(npid);
  537. unsigned int threadnumt = get_proc_threadnum(npid);
  538. if(threadnumt || memt || cput){
  539. return true;
  540. }else{
  541. return false;
  542. }
  543. }
  544. void ProgMon::run()
  545. {
  546. qint64 interval = 1000;
  547. qint64 nLastUpdate = 0;
  548. while(!QThread::isInterruptionRequested())
  549. {
  550. qint64 nNow = QDateTime::currentMSecsSinceEpoch();
  551. if((nNow - nLastUpdate)< interval)
  552. {
  553. msleep(10);
  554. continue;
  555. }
  556. QString strsysinfo;
  557. mPMS.UpdateCPUMemStat(strsysinfo);
  558. mMutexSysinfo.lock();
  559. mstrsysInfo = strsysinfo;
  560. mMutexSysinfo.unlock();
  561. nLastUpdate = nNow;
  562. int i;
  563. for(i=0;i<mvectorprog.size();i++)
  564. {
  565. mMutex.lock();
  566. mvectorprog[i].UpdateResState();
  567. if(QThread::isInterruptionRequested())
  568. {
  569. mMutex.unlock();
  570. break;
  571. }
  572. mMutex.unlock();
  573. }
  574. }
  575. }
  576. void ProgMon::setquit()
  577. {
  578. mbquit = true;
  579. }
  580. void ProgMon::threaderrout()
  581. {
  582. QString strhomepath = getenv("HOME");
  583. int nNeedCheckSpace = 0;
  584. bool bHaveHDDSpace = true;
  585. unsigned int i;
  586. while(mberroutrun)
  587. {
  588. std::vector<stdoutunit> xvectorerrout;
  589. mMutex_errout.lock();
  590. xvectorerrout= mvectorerrout;
  591. mvectorerrout.clear();
  592. mMutex_errout.unlock();
  593. if(xvectorerrout.size() == 0)
  594. {
  595. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  596. }
  597. else
  598. {
  599. if(bHaveHDDSpace == false)
  600. {
  601. continue;
  602. }
  603. for(i=0;i<xvectorerrout.size();i++)
  604. {
  605. unsigned int j;
  606. std::string strappname;
  607. std::string strarg;
  608. bool bFind = false;
  609. mMutex.lock();
  610. for(j=0;j<mvectorprog.size();j++)
  611. {
  612. ProgUnit *pu = &(mvectorprog.at(j));
  613. if(xvectorerrout[i].mpProc == pu->mProcess)
  614. {
  615. strappname = pu->strappname;
  616. strarg = pu->strargs;
  617. bFind = true;
  618. break;
  619. }
  620. }
  621. mMutex.unlock();
  622. if(bFind)
  623. {
  624. if(nNeedCheckSpace <= 0)
  625. {
  626. // std::cout<<"check space."<<std::endl;
  627. nNeedCheckSpace = 1000;
  628. int nSpace = get_path_availspace(strhomepath);
  629. // std::cout<<"hard space is "<<nSpace<<" MB."<<std::endl;
  630. if(nSpace<1000)
  631. {
  632. std::cout<<"Hard Disk No space to save std log."<<std::endl;
  633. bHaveHDDSpace = false;
  634. }
  635. }
  636. nNeedCheckSpace--;
  637. if(bHaveHDDSpace)
  638. {
  639. QString strlog;
  640. strlog = QDateTime::currentDateTime().toString("(yyyy/MM/dd hh:mm:ss:zzz")
  641. + " | " + strappname.data() + " "+ strarg.data() + ")"
  642. +xvectorerrout[i].mba.data();
  643. WriteLog(strlog.toLatin1().data());
  644. }
  645. }
  646. else
  647. {
  648. std::cout<<"not found a std out 's process."<<std::endl;
  649. }
  650. }
  651. }
  652. }
  653. std::cout<<"threaderrout complete."<<std::endl;
  654. }
  655. void ProgMon::threadstdout()
  656. {
  657. QString strhomepath = getenv("HOME");
  658. int nNeedCheckSpace = 0;
  659. bool bHaveHDDSpace = true;
  660. while(mbstdoutrun)
  661. {
  662. bool bAllNoLog = true;
  663. unsigned int i;
  664. mMutex.lock();
  665. for(i=0;i<mvectorprog.size();i++)
  666. {
  667. if(mvectorprog[i].mbSavestdout)
  668. {
  669. bAllNoLog = false;
  670. break;
  671. }
  672. }
  673. mMutex.unlock();
  674. if(mbAllNoLog != bAllNoLog)
  675. {
  676. mbAllNoLog = bAllNoLog;
  677. if(bAllNoLog == true)
  678. {
  679. mMutex_stdout.lock();
  680. mvectorstdout.clear();
  681. mMutex_stdout.unlock();
  682. }
  683. }
  684. if(mbAllNoLog == true)
  685. {
  686. msleep(100);
  687. continue;
  688. }
  689. std::vector<stdoutunit> xvectorstdout;
  690. mMutex_stdout.lock();
  691. xvectorstdout= mvectorstdout;
  692. mvectorstdout.clear();
  693. mMutex_stdout.unlock();
  694. if(xvectorstdout.size() == 0)
  695. {
  696. msleep(10);
  697. }
  698. else
  699. {
  700. if(bHaveHDDSpace == false)
  701. {
  702. continue;
  703. }
  704. for(i=0;i<xvectorstdout.size();i++)
  705. {
  706. unsigned int j;
  707. std::string strappname;
  708. std::string strarg;
  709. bool bFind = false;
  710. bool bSave = false;
  711. mMutex.lock();
  712. for(j=0;j<mvectorprog.size();j++)
  713. {
  714. ProgUnit *pu = &(mvectorprog.at(j));
  715. if(xvectorstdout[i].mpProc == pu->mProcess)
  716. {
  717. strappname = pu->strappname;
  718. strarg = pu->strargs;
  719. bFind = true;
  720. bSave = pu->mbSavestdout;
  721. break;
  722. }
  723. }
  724. mMutex.unlock();
  725. if(bFind)
  726. {
  727. if(bSave)
  728. {
  729. if(nNeedCheckSpace <= 0)
  730. {
  731. // std::cout<<"check space."<<std::endl;
  732. nNeedCheckSpace = 1000;
  733. int nSpace = get_path_availspace(strhomepath);
  734. // std::cout<<"hard space is "<<nSpace<<" MB."<<std::endl;
  735. if(nSpace<1000)
  736. {
  737. std::cout<<"Hard Disk No space to save std log."<<std::endl;
  738. bHaveHDDSpace = false;
  739. }
  740. }
  741. nNeedCheckSpace--;
  742. if(bHaveHDDSpace)
  743. {
  744. QString strlog;
  745. strlog = QDateTime::currentDateTime().toString("(yyyy/MM/dd hh:mm:ss:zzz")
  746. + " | " + strappname.data() + " "+ strarg.data() + ")"
  747. +xvectorstdout[i].mba.data();
  748. WriteStdLog(strlog.toLatin1().data());
  749. }
  750. }
  751. }
  752. else
  753. {
  754. std::cout<<"not found a std out 's process."<<std::endl;
  755. }
  756. }
  757. }
  758. }
  759. std::cout<<"threadstdout complete."<<std::endl;
  760. }
  761. void ProgMon::LogError(QProcess *proc, QByteArray &ba)
  762. {
  763. // std::cout<<"error is "<<ba.data()<<std::endl;
  764. static int nCheckSpace = 0;
  765. static bool bSave = true;
  766. if(bSave == false)return;
  767. if(nCheckSpace<=0)
  768. {
  769. nCheckSpace = 10000;
  770. QString strhomepath = getenv("HOME");
  771. if(get_path_availspace(strhomepath)<100)
  772. {
  773. bSave = false;
  774. return;
  775. }
  776. }
  777. nCheckSpace--;
  778. unsigned int i;
  779. std::string strappname;
  780. std::string strarg;
  781. bool bFind = false;
  782. mMutex.lock();
  783. for(i=0;i<mvectorprog.size();i++)
  784. {
  785. ProgUnit *pu = &(mvectorprog.at(i));
  786. if(proc == pu->mProcess)
  787. {
  788. strappname = pu->strappname;
  789. strarg = pu->strargs;
  790. bFind = true;
  791. break;
  792. }
  793. }
  794. mMutex.unlock();
  795. if(bFind)
  796. {
  797. QString strlog;
  798. strlog = QDateTime::currentDateTime().toString("(yyyy/MM/dd hh:mm:ss:zzz")
  799. + " | " + strappname.data() + " "+ strarg.data() + ")"
  800. +ba.data();
  801. WriteLog(strlog.toLatin1().data());
  802. }
  803. }
  804. void ProgMon::InitLog()
  805. {
  806. QString strpath = getenv("HOME");
  807. strpath = strpath + "/log";
  808. QDir xDir(strpath);
  809. if(xDir.exists() == false)
  810. {
  811. std::cout<<"dir "<<strpath.toLatin1().data()<<" not exist . Create it."<<std::endl;
  812. if(xDir.mkdir(strpath) == false)
  813. {
  814. std::cout<<"make dir faile . dir is "<<strpath.toLatin1().data()<<std::endl;
  815. mbFileLog = false;
  816. return;
  817. }
  818. }
  819. QString strname = "IVSysMan-errlog-" + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz.log");
  820. QString strstdname = "IVSysMan-stdlog-" + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz.log");
  821. QString strstdpath = strpath + "/" + strstdname;
  822. strpath = strpath +"/" + strname;
  823. mFileLog.setFileName(strpath);
  824. if(mFileLog.open(QIODevice::ReadWrite))
  825. {
  826. mbFileLog = true;
  827. }
  828. else
  829. {
  830. std::cout<<" Create error log File Fail. File Path is "<<strpath.toLatin1().data()<<std::endl;
  831. mbFileLog = false;
  832. }
  833. mFileStdLog.setFileName(strstdpath);
  834. if(mFileStdLog.open(QIODevice::ReadWrite))
  835. {
  836. mbFileStdLog = true;
  837. }
  838. else
  839. {
  840. std::cout<<" Create std log File Fail. File Path is "<<strpath.toLatin1().data()<<std::endl;
  841. mbFileStdLog = false;
  842. }
  843. }
  844. void ProgMon::WriteLog(const char *strlog)
  845. {
  846. if(mbFileLog)
  847. {
  848. mFileLog.write(strlog,strnlen(strlog,100000));
  849. // mFileLog.flush();
  850. }
  851. }
  852. void ProgMon::WriteStdLog(const char *strlog)
  853. {
  854. if(mbFileStdLog)
  855. {
  856. mFileStdLog.write(strlog,strnlen(strlog,100000));
  857. }
  858. }
  859. int ProgMon::get_path_availspace(const QString & path)
  860. {
  861. #ifdef OS_UNIX
  862. struct statfs diskInfo;
  863. statfs(path.toUtf8().data(), &diskInfo);
  864. 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);
  865. return (diskInfo.f_bavail * diskInfo.f_bsize)/1024.0/1024.0;
  866. #endif
  867. #ifdef OS_WIN
  868. LPCWSTR lpcwstrDriver=(LPCWSTR)path.utf16();
  869. ULARGE_INTEGER liFreeBytesAvailable, liTotalBytes, liTotalFreeBytes;
  870. if( !GetDiskFreeSpaceEx( lpcwstrDriver, &liFreeBytesAvailable, &liTotalBytes, &liTotalFreeBytes) )
  871. {
  872. qDebug() << "ERROR: Call to GetDiskFreeSpaceEx() failed.";
  873. return 0;
  874. }
  875. return (quint64) liTotalFreeBytes.QuadPart/1024/1024;
  876. #endif
  877. }
  878. void ProgMon::UpdateCPUMemStat()
  879. {
  880. return;
  881. static qint64 nLastCPUTotal,nLastIdleTotal;
  882. static std::vector<qint64> nVectorLastCPU;
  883. static std::vector<qint64> nVectorLastIdle;
  884. QFile xFileStat;
  885. xFileStat.setFileName("/proc/stat");
  886. if(xFileStat.open(QIODevice::ReadOnly))
  887. {
  888. QByteArray ba = xFileStat.readAll();
  889. QList<QByteArray> xlist = ba.split('\n');
  890. int nsize = xlist.size();
  891. }
  892. xFileStat.close();
  893. }
  894. QString ProgMon::GetSysInfo()
  895. {
  896. QString strsysinfo;
  897. mMutexSysinfo.lock();
  898. strsysinfo = mstrsysInfo;
  899. mMutexSysinfo.unlock();
  900. return strsysinfo;
  901. }