progmon.cpp 24 KB

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