1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597 |
- /*##############################################################################
- Copyright (C) 2011 HPCC Systems.
- All rights reserved. This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- ############################################################################## */
- #include "ws_workunitsService.hpp"
- #include "jlib.hpp"
- #include "daclient.hpp"
- #include "dalienv.hpp"
- #include "dadfs.hpp"
- #include "daaudit.hpp"
- #include "exception_util.hpp"
- #include "wujobq.hpp"
- #include "eventqueue.hpp"
- #include "fileview.hpp"
- #include "hqlerror.hpp"
- #include "sacmd.hpp"
- #include "wuwebview.hpp"
- #include "portlist.h"
- #include "dllserver.hpp"
- #include "schedulectrl.hpp"
- #include "scheduleread.hpp"
- bool getClusterJobQueueXLS(StringBuffer &xml, const char* cluster, const char* startDate, const char* endDate, const char* showType)
- {
- CDateTime fromTime;
- if(notEmpty(startDate))
- fromTime.setString(startDate, NULL, false);
- CDateTime toTime;
- if(notEmpty(endDate))
- toTime.setString(endDate, NULL, false);
- xml.append("<XmlSchema name=\"MySchema\">"
- "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n"
- "<xs:element name=\"Dataset\">"
- "<xs:complexType>"
- "<xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n"
- "<xs:element name=\"Row\">"
- "<xs:complexType>"
- "<xs:sequence>\n");
- xml.append("<xs:element name=\"datetime\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"running\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"queued\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"connected\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"waiting\" type=\"xs:string20\"/>\n");
- xml.append("<xs:element name=\"idlecount\" type=\"xs:string20\"/>\n");
- xml.append("<xs:element name=\"running_wuid1\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"running_wuid2\" type=\"xs:string\"/>\n");
- xml.append( "</xs:sequence>"
- "</xs:complexType>"
- "</xs:element>\n"
- "</xs:sequence>"
- "</xs:complexType>"
- "</xs:element>\n");
- xml.append("<xs:simpleType name=\"string20\"><xs:restriction base=\"xs:string\"><xs:maxLength value=\"20\"/></xs:restriction></xs:simpleType>\n");
- xml.append("</xs:schema>");
- xml.append("</XmlSchema>").newline();
- xml.append("<Dataset");
- xml.append(" name=\"data\" xmlSchema=\"MySchema\" ");
- xml.append(">").newline();
- StringBuffer filter("ThorQueueMonitor");
- if (notEmpty(cluster))
- filter.appendf(",%s", cluster);
- StringAttrArray lines;
- queryAuditLogs(fromTime, toTime, filter.str(), lines);
- unsigned longest = 0;
- unsigned maxConnected = 0;
- unsigned maxDisplay = 0;
- unsigned showVal = (showType && strieq(showType, "InGraph")) ? 1 : 0;
- IArrayOf<IEspThorQueue> items;
- WsWuJobQueueAuditInfo jq;
- ForEachItemIn(idx, lines)
- {
- const char* line = lines.item(idx).text;
- if(isEmpty(line))
- continue;
- bool isLast = (idx == (lines.length() - 1));
- jq.getAuditLineInfo(lines.item(idx).text, longest, maxConnected, maxDisplay, (isLast && showVal==1) ? 2 : showVal, items);
- }
- ForEachItemIn(i,items)
- {
- IEspThorQueue& tq = items.item(i);
- xml.append(" <Row>");
- appendXMLTag(xml, "datetime", tq.getDT());
- appendXMLTag(xml, "running", tq.getRunningWUs());
- appendXMLTag(xml, "queued", tq.getQueuedWUs());
- appendXMLTag(xml, "connected", tq.getConnectedThors());
- appendXMLTag(xml, "waiting", tq.getWaitingThors());
- appendXMLTag(xml, "idlecount", tq.getIdledThors());
- if (notEmpty(tq.getRunningWU1()))
- appendXMLTag(xml, "running_wuid1", tq.getRunningWU1());
- if (notEmpty(tq.getRunningWU2()))
- appendXMLTag(xml, "running_wuid2", tq.getRunningWU2());
- xml.append("</Row>");
- xml.newline();
- }
- xml.append("</Dataset>").newline();
- return true;
- }
- static const long LOGFILESIZELIMIT = 500000; //Limit page size to 500k
- inline float timeStrToFloat(const char *timestr, float &val)
- {
- if (!timestr)
- return val;
- int hours = 0;
- int mins = 0;
- while(isdigit(*timestr))
- {
- hours = 10 * hours + *timestr - '0';
- timestr++;
- }
- if(*timestr == ':')
- timestr++;
- while(isdigit(*timestr))
- {
- mins = 10 * mins + (*timestr - '0');
- timestr++;
- }
- val = hours + mins/60.0F;
- return val;
- }
- StringBuffer &getNextStrItem(StringBuffer &s, const char *&finger, const char delim=',')
- {
- if (!finger)
- return s;
- const char *endp = strchr(finger, delim);
- if (endp)
- {
- s.append(endp - finger, finger);
- finger = endp+1;
- }
- else
- {
- s.append(finger);
- finger=NULL;
- }
- return s;
- }
- IEspECLJob* createEclJobFromAuditLine(double version, const char* str)
- {
- if(isEmpty(str))
- return NULL;
- Owned<IEspECLJob> job = createECLJob("", "");
- StringBuffer sdate;
- getNextStrItem(sdate, str);
- if (sdate.length()>=9)
- sdate.setCharAt(10, 'T');
- if(!str)
- return job.getClear();
- StringBuffer s;
- getNextStrItem(s, str);
- if(!str)
- return job.getClear();
- getNextStrItem(s.clear(), str);
- if(!str)
- return job.getClear();
- job->setCluster(getNextStrItem(s.clear(), str).str());
- if(!str)
- return job.getClear();
- job->setWuid(getNextStrItem(s.clear(), str).str());
- if(!str)
- return job.getClear();
- getNextStrItem(s.clear(), str);
- if (version > 1.05)
- job->setGraphNum(s.str());
- StringBuffer graph("graph");
- job->setGraph(graph.append(s).str());
- if(!str)
- return job.getClear();
- getNextStrItem(s.clear(), str);
- if (version > 1.05)
- job->setSubGraphNum(s.str());
- if(!str)
- return job.getClear();
- getNextStrItem(s.clear(), str);
- if (version > 1.05)
- job->setNumOfRuns(s.str());
- if(!str)
- return job.getClear();
- getNextStrItem(s.clear(), str);
- if (version > 1.05)
- job->setDuration(atoi(s.str()) / 1000);
- if(!str)
- return job.getClear();
- if(!strncmp("FAILED", getNextStrItem(s.clear(), str).str(), 6))
- job->setState("failed");
- else
- job->setState("finished");
- CDateTime endDT;
- endDT.setString(sdate.str(), NULL, true);
- CDateTime startDT;
- startDT.set(endDT.getSimple() - job->getDuration());
- job->setStartedDate(startDT.getString(s.clear(), false).append('Z').str());
- job->setFinishedDate(endDT.getString(s.clear(), false).append('Z').str());
- return job.getClear();
- }
- bool getClusterJobXLS(double version, StringBuffer &xml, const char* cluster, const char* startDate, const char* endDate, bool showall, const char* busStartStr, const char* busEndStr)
- {
- float busStart = 0;
- float busEnd = 24;
- if(showall)
- {
- timeStrToFloat(busStartStr, busStart);
- timeStrToFloat(busEndStr, busEnd);
- if(busStart <= 0 || busStart > 24 || busStart >= busEnd)
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "Invalid business hours");
- }
- CDateTime fromTime;
- if(notEmpty(startDate))
- fromTime.setString(startDate, NULL, false);
- CDateTime toTime;
- if(notEmpty(endDate))
- toTime.setString(endDate, NULL, false);
- xml.append("<XmlSchema name=\"MySchema\">");
- xml.append("<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n"
- "<xs:element name=\"Dataset\">"
- "<xs:complexType>"
- "<xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n"
- "<xs:element name=\"Row\">"
- "<xs:complexType>"
- "<xs:sequence>\n");
- xml.append("<xs:element name=\"wuid\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"graph\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"sub-graph\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"runs\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"started\" type=\"xs:string20\"/>\n");
- xml.append("<xs:element name=\"finished\" type=\"xs:string20\"/>\n");
- xml.append("<xs:element name=\"duration\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"cluster\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"state\" type=\"xs:string\"/>\n");
- xml.append( "</xs:sequence>"
- "</xs:complexType>"
- "</xs:element>\n"
- "</xs:sequence>"
- "</xs:complexType>"
- "</xs:element>\n");
- xml.append("<xs:simpleType name=\"string20\"><xs:restriction base=\"xs:string\"><xs:maxLength value=\"20\"/></xs:restriction></xs:simpleType>\n");
- xml.append("</xs:schema>");
- xml.append("</XmlSchema>").newline();
- xml.append("<Dataset name=\"data\" xmlSchema=\"MySchema\">").newline();
- StringBuffer filter("Timing,ThorGraph");
- if(notEmpty(cluster))
- filter.append(',').append(cluster);
- StringAttrArray jobs;
- queryAuditLogs(fromTime, toTime, filter.str(), jobs);
- IArrayOf<IEspECLJob> jobList;
- ForEachItemIn(idx, jobs)
- {
- if(jobs.item(idx).text.isEmpty())
- continue;
- Owned<IEspECLJob> job = createEclJobFromAuditLine(version, jobs.item(idx).text.get());
- CDateTime tTime;
- unsigned year, month, day, hour, minute, second, nano;
- tTime.setString(job->getStartedDate(), NULL, true);
- tTime.getDate(year, month, day, true);
- tTime.getTime(hour, minute, second, nano, true);
- StringBuffer started;
- started.appendf("%4d-%02d-%02d %02d:%02d:%02d",year,month,day,hour,minute,second);
- tTime.setString(job->getFinishedDate(), NULL, true);
- tTime.getDate(year, month, day, true);
- tTime.getTime(hour, minute, second, nano, true);
- StringBuffer finished;
- finished.appendf("%4d-%02d-%02d %02d:%02d:%02d",year,month,day,hour,minute,second);
- xml.append(" <Row>");
- appendXMLTag(xml, "wuid", job->getWuid());
- appendXMLTag(xml, "graph", job->getGraphNum());
- appendXMLTag(xml, "sub-graph", job->getSubGraphNum());
- appendXMLTag(xml, "runs", job->getNumOfRuns());
- appendXMLTag(xml, "started", started.str());
- appendXMLTag(xml, "finished", finished.str());
- xml.appendf("<duration>%d</duration>", job->getDuration());
- appendXMLTag(xml, "cluster", job->getCluster());
- appendXMLTag(xml, "state", job->getState());
- xml.append("</Row>").newline();
- jobList.append(*job.getClear());
- }
- xml.append("</Dataset>").newline();
- return true;
- }
- class CJobUsage : public CInterface
- {
- public:
- StringBuffer m_date;
- float m_usage, m_busage, m_nbusage;
- public:
- IMPLEMENT_IINTERFACE;
- CJobUsage()
- {
- m_usage = 0.0;
- m_busage = 0.0;
- m_nbusage = 0.0;
- };
- };
- typedef CIArrayOf<CJobUsage> JobUsageArray;
- //what???
- int ZCMJD(unsigned y, unsigned m, unsigned d)
- {
- if (m<3)
- {
- m += 12 ;
- y--;
- }
- return -678973 + d + (((153*m-2)/5)|0) + 365*y + ((y/4)|0) - ((y/100)|0) + ((y/400)|0);
- }
- void AddToClusterJobXLS(JobUsageArray& jobsummary, CDateTime &adjStart, CDateTime &adjEnd, int first, float busStart, float busEnd)
- {
- unsigned year0, month0, day0, hour0, minute0, second0, nano0;
- adjStart.getDate(year0, month0, day0, true);
- adjStart.getTime(hour0, minute0, second0, nano0, true);
- unsigned year1, month1, day1, hour1, minute1, second1, nano1;
- adjEnd.getDate(year1, month1, day1, true);
- adjEnd.getTime(hour1, minute1, second1, nano1, true);
- busStart *= 3600.0;
- busEnd *= 3600.0;
- float x1 = 3600.0F*hour0 + 60.0F*minute0 + second0;
- int y1 = ZCMJD(year0, month0, day0)-first;
- float x2 = 3600.0F*hour1 + 60.0F*minute1 + second1;
- int y2 = ZCMJD(year1, month1, day1)-first;
- for(int y=y1; y<=y2; y++)
- {
- if ((y < 0) || (y > (int)jobsummary.length() - 1))
- continue;
- CJobUsage& jobUsage = jobsummary.item(y);
- float xx1= (y==y1 ? x1 : 0.0F);
- float xx2= (y==y2 ? x2 : 86400.0F);
- jobUsage.m_usage += (xx2-xx1)/864.0F;
- float bhours = ((busEnd < xx2)? busEnd : xx2) - ((busStart > xx1) ? busStart : xx1);
- if(bhours < 0.0)
- bhours = 0.0;
- float nbhours = (xx2 - xx1 - bhours);
- if(busStart + (86400.0 - busEnd) > 0.001)
- jobUsage.m_nbusage += 100 * nbhours/(busStart + (86400.0F - busEnd));
- if(busEnd - busStart > 0.001)
- jobUsage.m_busage += 100*bhours/(busEnd - busStart);
- }
- return;
- }
- bool readECLWUCurrentJob(const char* curjob, const char* clusterName, const char* toDate, StringBuffer& dtStr, StringBuffer& actionStr, StringBuffer& wuidStr, StringBuffer& graphStr, StringBuffer& subGraphStr, StringBuffer& clusterStr)
- {
- if(!curjob || !*curjob)
- return false;
- // startdate
- const char* bptr = curjob;
- const char* eptr = strchr(bptr, ',');
- if(!eptr)
- return false;
- StringBuffer dt;
- dt.clear().append(eptr - bptr, bptr);
- dt.setCharAt(10, 'T');
- if (strcmp(dt.str(), toDate) > 0)
- return false;
- CDateTime enddt;
- enddt.setString(dt.str(), NULL, true);
- dt.clear();
- enddt.getString(dt, false);
- dt.append('Z');
- //Progress
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(!eptr)
- return false;
- //Thor
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(!eptr)
- return false;
- // action name
- char action[256];
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(!eptr)
- return false;
- int len = eptr - bptr;
- strncpy(action, bptr, len);
- action[len] = 0;
- // cluster name
- char cluster[256];
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(!eptr)
- return false;
- len = eptr - bptr;
- strncpy(cluster, bptr, len);
- cluster[len] = 0;
- if (cluster && *cluster)
- {
- clusterStr.clear().append(cluster);
- if (clusterName && *clusterName && stricmp(cluster, clusterName))
- return false;
- }
- dtStr = dt;
- actionStr.clear().append(action);
- if (!stricmp(action, "startup") || !stricmp(action, "terminate"))
- return true;
- //WUID
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(!eptr)
- return false;
- wuidStr.clear().append(eptr - bptr, bptr);
- //graph number
- char graph[32];
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(!eptr)
- return false;
- len = eptr - bptr;
- if (bptr[0] == 'g' && len > 5)
- {
- bptr += 5;
- len = eptr - bptr;
- }
- strncpy(graph, bptr, len);
- graph[len] = 0;
- graphStr.clear().append(eptr - bptr, bptr);
- if (!stricmp(action, "start") || !stricmp(action, "stop"))
- return true;
- //subgraph number
- char subgraph[32];
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(!eptr)
- {
- strcpy(subgraph, bptr);
- }
- else
- {
- len = eptr - bptr;
- strncpy(subgraph, bptr, len);
- subgraph[len] = 0;
- }
- subGraphStr.clear().append(subgraph);
- return true;
- }
- void addUnfinishedECLWUs(IArrayOf<IEspECLJob>& eclJobList, const char* wuid, const char* graph, const char* subGraph,
- const char* cluster, const char* dt, const char* dt1, StringArray& unfinishedWUIDs, StringArray& unfinishedGraphs,
- StringArray& unfinishedSubGraphs, StringArray& unfinishedClusters, StringArray& unfinishedWUStarttime, StringArray& unfinishedWUEndtime)
- {
- bool bFound = false;
- ForEachItemIn(idx, eclJobList)
- {
- IConstECLJob& curECLJob = eclJobList.item(idx);
- const char *eclwuid = curECLJob.getWuid();
- const char *eclgraph = curECLJob.getGraphNum();
- const char *eclsubgraph = curECLJob.getSubGraphNum();
- const char *ecldate = curECLJob.getFinishedDate();
- if (!eclwuid || !*eclwuid || stricmp(eclwuid, wuid))
- continue;
- if (!eclgraph || !*eclgraph || stricmp(eclgraph, graph))
- continue;
- if (!eclsubgraph || !*eclsubgraph || stricmp(eclsubgraph, subGraph))
- continue;
- //if (!ecldate || !*ecldate || (stricmp(ecldate, dt) < 0) || (stricmp(ecldate, dt1) > 0))
- // continue;
- if (!ecldate || !*ecldate)
- continue;
- int test = stricmp(ecldate, dt);
- if (test < 0)
- continue;
- test = stricmp(ecldate, dt1);
- if (test > 0)
- continue;
- bFound = true;
- break;
- }
- if (!bFound)
- {
- unfinishedWUIDs.append(wuid);
- StringBuffer graph0("graph");
- graph0.append(graph);
- unfinishedGraphs.append(graph0);
- unfinishedSubGraphs.append(subGraph);
- unfinishedClusters.append(cluster);
- unfinishedWUStarttime.append(dt);
- unfinishedWUEndtime.append(dt1);
- }
- return;
- }
- const unsigned MAXSUBGRAPHDAYS = 10;
- bool getPreviousUnfinishedECLWU(CDateTime fromTime, CDateTime toTime, const char* toDate, const char* cluster,
- StringBuffer& wuidStr, StringBuffer& graphStr, StringBuffer& subGraphStr, StringBuffer& clusterStr, StringBuffer& dtStr)
- {
- bool bFound = false;
- wuidStr.clear();
- graphStr.clear();
- subGraphStr.clear();
- dtStr.clear();
- StringBuffer filter0("Progress,Thor");
- CDateTime fromTime1 = fromTime, toTime1;
- bool bStop = false;
- for (unsigned day = 0; !bStop && day < MAXSUBGRAPHDAYS; day++)
- {
- toTime1 = fromTime1;
- fromTime1.adjustTime(-1440);
- StringAttrArray jobs1;
- queryAuditLogs(fromTime1, toTime1, filter0.str(), jobs1);
- #if 0
- char* str1 = "2010-10-04 07:39:04 ,Progress,Thor,StartSubgraph,thor,W20100929-073902,5,1,thor,thor.thor";
- char* str2 = "2010-10-04 15:53:43 ,Progress,Thor,Startup,thor,thor,thor.thor,//10.173.51.20/c$/thor_logs/09_29_2010_15_52_39/THORMASTER.log";
- char* str3 = "2010-10-04 17:52:31 ,Progress,Thor,Start,thor,W20100929-075230,graph1,r3gression,thor,thor.thor";
- jobs1.append(*new StringAttrItem(str2, strlen(str2)));
- jobs1.append(*new StringAttrItem(str1, strlen(str1)));
- jobs1.append(*new StringAttrItem(str3, strlen(str3)));
- #endif
- ForEachItemInRev(idx1, jobs1)
- {
- const char* curjob = jobs1.item(idx1).text;
- if(!curjob || !*curjob)
- continue;
- StringBuffer actionStr, clusterStr;
- if (!readECLWUCurrentJob(curjob, cluster, toDate, dtStr, actionStr, wuidStr, graphStr, subGraphStr, clusterStr))
- continue;
- if (!stricmp(actionStr.str(), "StartSubgraph") && (wuidStr.length() > 0) && (graphStr.length() > 0))
- {
- bFound = true;
- bStop = true;
- break;
- }
- if (!stricmp(actionStr.str(), "Startup") || !stricmp(actionStr.str(), "Terminate"))
- {
- bStop = true;
- break;
- }
- }
- }
- return bFound;
- }
- //Tony ToBeRefactored
- void findUnfinishedECLWUs(IArrayOf<IEspECLJob>& eclJobList, CDateTime fromTime, CDateTime toTime, const char* toDate, const char* cluster, StringArray& unfinishedWUIDs,
- StringArray& unfinishedGraphs, StringArray& unfinishedSubGraphs, StringArray& unfinishedClusters, StringArray& unfinishedWUStarttime, StringArray& unfinishedWUEndtime)
- {
- StringAttrArray jobs1;
- StringBuffer filter1("Progress,Thor");
- queryAuditLogs(fromTime, toTime, filter1.str(), jobs1);
- bool bAbnormalWU = false;
- int len = jobs1.length();
- StringBuffer dtStr, actionStr, wuidStr, graphStr, subGraphStr, clusterStr;
- ForEachItemIn(idx1, jobs1)
- {
- const char* curjob = jobs1.item(idx1).text;
- if(!curjob || !*curjob)
- continue;
- wuidStr.clear();
- graphStr.clear();
- subGraphStr.clear();
- if (!readECLWUCurrentJob(curjob, cluster, toDate, dtStr, actionStr, wuidStr, graphStr, subGraphStr, clusterStr))
- continue;
- if (stricmp(actionStr.str(), "Start"))
- continue;
- bAbnormalWU = true;
- int nextIndex = idx1 + 1;
- int idx2 = nextIndex;
- while (idx2 < len)
- {
- const char* curjob1 = jobs1.item(idx2).text;
- if(!curjob1 || !*curjob1)
- continue;
- StringBuffer dtStr1, actionStr1, wuidStr1, graphStr1, subGraphStr1, clusterStr1;
- if (readECLWUCurrentJob(curjob1, cluster, toDate, dtStr1, actionStr1, wuidStr1, graphStr1, subGraphStr1, clusterStr1))
- {
- if (!stricmp(wuidStr.str(), wuidStr1.str()) && !stricmp(graphStr.str(), graphStr1.str()))
- {
- if (!stricmp(actionStr1.str(), "Stop") )
- {
- bAbnormalWU = false;
- break;
- }
- else if (!stricmp(actionStr1.str(), "Start"))
- {
- break;
- }
- }
- }
- idx2++;
- }
- //If the WU did not finish by itself, let's check whether the cluster was stopped before the WU finished.
- if (bAbnormalWU)
- {
- int idx2 = nextIndex;
- while (idx2 < len)
- {
- const char* curjob1 = jobs1.item(idx2).text;
- if(!curjob1 || !*curjob1)
- continue;
- StringBuffer dtStr1, actionStr1, wuidStr1, graphStr1, subGraphStr1, clusterStr1;
- if (!readECLWUCurrentJob(curjob1, cluster, toDate, dtStr1, actionStr1, wuidStr1, graphStr1, subGraphStr1, clusterStr1))
- {
- idx2++;
- continue;
- }
- if (!stricmp(actionStr1.str(), "StartSubgraph") && !stricmp(wuidStr.str(), wuidStr1.str()) && !stricmp(graphStr.str(), graphStr1.str()))
- {
- //update subgraph number
- subGraphStr.clear().append(subGraphStr1.str());
- dtStr.clear().append(dtStr1.str());
- clusterStr.clear().append(clusterStr1.str());
- idx2++;
- continue;
- }
- if (stricmp(actionStr1.str(), "Startup") && stricmp(actionStr1.str(), "Terminate"))
- {
- idx2++;
- continue;
- }
- addUnfinishedECLWUs(eclJobList, wuidStr.str(), graphStr.str(), subGraphStr.str(), clusterStr.str(), dtStr.str(), dtStr1.str(),
- unfinishedWUIDs, unfinishedGraphs, unfinishedSubGraphs, unfinishedClusters, unfinishedWUStarttime, unfinishedWUEndtime);
- bAbnormalWU = false;
- break;
- }
- if (bAbnormalWU)
- {
- addUnfinishedECLWUs(eclJobList, wuidStr.str(), graphStr.str(), subGraphStr.str(), clusterStr.str(), dtStr.str(), toDate,
- unfinishedWUIDs, unfinishedGraphs, unfinishedSubGraphs, unfinishedClusters, unfinishedWUStarttime, unfinishedWUEndtime);
- bAbnormalWU = false;
- }
- }
- }
- //What if a WU started before *and* ended after the search time range
- if ((eclJobList.length() < 1) && (unfinishedWUIDs.length() < 1))
- {
- if (getPreviousUnfinishedECLWU(fromTime, toTime, toDate, cluster, wuidStr, graphStr, subGraphStr, clusterStr, dtStr))
- {
- addUnfinishedECLWUs(eclJobList, wuidStr.str(), graphStr.str(), subGraphStr.str(), clusterStr.str(), dtStr.str(), toDate,
- unfinishedWUIDs, unfinishedGraphs, unfinishedSubGraphs, unfinishedClusters, unfinishedWUStarttime, unfinishedWUEndtime);
- }
- }
- return;
- }
- bool getClusterJobSummaryXLS(double version, StringBuffer &xml, const char* cluster, const char* startDate, const char* endDate, bool showall, const char* busStartStr, const char* busEndStr)
- {
- float busStart = 0;
- float busEnd = 24;
- if(showall)
- {
- timeStrToFloat(busStartStr, busStart);
- timeStrToFloat(busEndStr, busEnd);
- if(busStart <= 0 || busStart > 24 || busStart >= busEnd)
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "Invalid business hours");
- }
- CDateTime fromTime;
- if(notEmpty(startDate))
- fromTime.setString(startDate, NULL, false);
- CDateTime toTime;
- int delayTime = -240; //4 hour time difference
- bool extendedToNextDay = false;
- if(notEmpty(endDate))
- {
- toTime.setString(endDate, NULL, false);
- unsigned year, month, day, day1;
- CDateTime tTime = toTime;
- tTime.getDate(year, month, day);
- tTime.adjustTime(delayTime);
- tTime.getDate(year, month, day1);
- if (day1 < day)
- extendedToNextDay = true;
- }
- StringAttrArray jobs;
- StringBuffer filter("Timing,ThorGraph");
- if(notEmpty(cluster))
- filter.append(',').append(cluster);
- queryAuditLogs(fromTime, toTime, filter.str(), jobs);
- unsigned year, month, day;
- fromTime.getDate(year, month, day);
- int first = ZCMJD(year, month, day);
- toTime.getDate(year, month, day);
- int last = ZCMJD(year, month, day);
- if (last < first)
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "Invalid day range");
- CDateTime usageDT(fromTime);
- JobUsageArray jobUsages;
- for (int i = first; i <= last; i++)
- {
- Owned<CJobUsage> jobUsage = new CJobUsage();
- usageDT.getDateString(jobUsage->m_date);
- jobUsages.append(*jobUsage.getClear());
- usageDT.adjustTime(60*24);
- }
- IArrayOf<IEspECLJob> jobList;
- ForEachItemIn(idx, jobs)
- {
- if(jobs.item(idx).text.isEmpty())
- continue;
- Owned<IEspECLJob> job = createEclJobFromAuditLine(version, jobs.item(idx).text.get());
- CDateTime adjStart;
- adjStart.setString(job->getStartedDate(),NULL,true);
- adjStart.adjustTime(delayTime);
- CDateTime adjEnd;
- adjEnd.setString(job->getFinishedDate(),NULL,true);
- adjEnd.adjustTime(delayTime);
- AddToClusterJobXLS(jobUsages, adjStart, adjEnd, first, busStart, busEnd);
- jobList.append(*job.getClear());
- }
- StringBuffer s;
- StringArray unfinishedWUIDs, unfinishedGraphs, unfinishedSubGraphs, unfinishedClusters, unfinishedWUStarttime, unfinishedWUEndtime;
- findUnfinishedECLWUs(jobList, fromTime, toTime, toTime.getString(s).str(), cluster, unfinishedWUIDs, unfinishedGraphs, unfinishedSubGraphs, unfinishedClusters, unfinishedWUStarttime, unfinishedWUEndtime);
- ForEachItemIn(idx3, unfinishedWUIDs)
- {
- CDateTime adjStart;
- adjStart.setString(unfinishedWUStarttime.item(idx3), NULL, true);
- adjStart.adjustTime(delayTime);
- CDateTime adjEnd;
- adjEnd.setString(unfinishedWUEndtime.item(idx3),NULL,true);
- adjEnd.adjustTime(delayTime);
- AddToClusterJobXLS(jobUsages, adjStart, adjEnd, first, busStart, busEnd);
- }
- xml.append("<XmlSchema name=\"MySchema\">");
- xml.append(
- "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n"
- "<xs:element name=\"Dataset\">"
- "<xs:complexType>"
- "<xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n"
- "<xs:element name=\"Row\">"
- "<xs:complexType>"
- "<xs:sequence>\n");
- xml.append("<xs:element name=\"Date\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"Business\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"Non-business\" type=\"xs:string\"/>\n");
- xml.append("<xs:element name=\"Overall\" type=\"xs:string\"/>\n");
- xml.append( "</xs:sequence>"
- "</xs:complexType>"
- "</xs:element>\n"
- "</xs:sequence>"
- "</xs:complexType>"
- "</xs:element>\n");
- xml.append("<xs:simpleType name=\"string20\"><xs:restriction base=\"xs:string\"><xs:maxLength value=\"20\"/></xs:restriction></xs:simpleType>\n");
- xml.append("</xs:schema>");
- xml.append("</XmlSchema>").newline();
- xml.append("<Dataset name=\"data\" xmlSchema=\"MySchema\" >").newline();
- StringBuffer percentageStr;
- percentageStr.append("%");
- int lastUsage = jobUsages.length();
- if (extendedToNextDay)
- lastUsage --;
- for (int i0 = 0; i0 < lastUsage; i0++)
- {
- CJobUsage& jobUsage = jobUsages.item(i0);
- xml.append(" <Row>");
- xml.appendf("<Date>%s</Date>", jobUsage.m_date.str());
- xml.appendf("<Business>%3.0f %s</Business>", jobUsage.m_busage, percentageStr.str());
- xml.appendf("<Non-business>%3.0f %s</Non-business>", jobUsage.m_nbusage, percentageStr.str());
- xml.appendf("<Overall>%3.0f %s</Overall>", jobUsage.m_usage, percentageStr.str());
- xml.append(" </Row>");
- }
- xml.append("</Dataset>").newline();
- return true;
- }
- inline StringBuffer &appendQuoted(StringBuffer &s, const char *val, bool first=false, const char q='\'')
- {
- if (!first)
- s.append(',');
- return s.append(q).append(val).append(q);
- }
- inline StringBuffer &appendQuoted(StringBuffer &s, float val, bool first=false, const char q='\'')
- {
- if (!first)
- s.append(',');
- return s.append(q).append(val).append(q);
- }
- inline StringBuffer &appendQuoted(StringBuffer &s, unsigned val, bool first=false, const char q='\'')
- {
- if (!first)
- s.append(',');
- return s.append(q).append(val).append(q);
- }
- void streamJobListResponse(IEspContext &context, const char *cluster, const char *from , const char *to, CHttpResponse* response, bool showall, float bbtime, float betime, const char *xls)
- {
- CDateTime fromTime;
- StringBuffer fromstr;
- if (notEmpty(from))
- {
- fromTime.setString(from, NULL, false);
- fromTime.getString(fromstr, false);
- }
- CDateTime toTime;
- StringBuffer tostr;
- if(notEmpty(to))
- {
- toTime.setString(to,NULL,false);
- toTime.getString(tostr, false);
- }
- StringBuffer sb;
- sb.append("<script language=\"javascript\">parent.displayLegend(");
- appendQuoted(sb, fromstr.str(), true);
- appendQuoted(sb, tostr.str());
- appendQuoted(sb, showall ? "1" : "0");
- sb.append(")</script>\r\n");
- response->sendChunk(sb.str());
- sb.clear();
- sb.append("<script language=\"javascript\">parent.displayBegin(");
- appendQuoted(sb, fromstr.str(), true);
- appendQuoted(sb, tostr.str());
- appendQuoted(sb, showall ? "1" : "0");
- sb.append(")</script>\r\n");
- response->sendChunk(sb.str());
- sb.clear();
- StringBuffer filter("Timing,ThorGraph");
- if(notEmpty(cluster))
- filter.appendf(",%s", cluster);
- StringAttrArray jobs;
- queryAuditLogs(fromTime, toTime, filter.str(), jobs);
- sb.append("<script language=\"javascript\">\r\n");
- unsigned count=0;
- IArrayOf<IEspECLJob> eclJobList;
- ForEachItemIn(idx, jobs)
- {
- if(!jobs.item(idx).text.length())
- continue;
- Owned<IEspECLJob> job = createEclJobFromAuditLine(context.getClientVersion(), jobs.item(idx).text.get());
- sb.append("parent.displayJob(");
- appendQuoted(sb, job->getWuid(), true);
- appendQuoted(sb, job->getGraph());
- appendQuoted(sb, job->getStartedDate());
- appendQuoted(sb, job->getFinishedDate());
- appendQuoted(sb, job->getCluster());
- appendQuoted(sb, job->getState());
- if (showall)
- sb.append(",\'\',\'1\'");
- else
- sb.append(",\'\',\'0\'");
- sb.append(',').append(bbtime).append(',').append(betime).append(")\r\n");
- if(++count>=50)
- {
- sb.append("</script>\r\n");
- response->sendChunk(sb.str());
- sb.clear().append("<script language=\"javascript\">\r\n");
- count=0;
- }
- eclJobList.append(*job.getClear());
- }
- //Find out which WUs stopped by abnormal thor termination
- StringArray unfinishedWUIDs, unfinishedGraphs, unfinishedSubGraphs, unfinishedClusters, unfinishedWUStarttime, unfinishedWUEndtime;
- findUnfinishedECLWUs(eclJobList, fromTime, toTime, tostr.str(), cluster, unfinishedWUIDs, unfinishedGraphs, unfinishedSubGraphs, unfinishedClusters, unfinishedWUStarttime, unfinishedWUEndtime);
- if (unfinishedWUIDs.ordinality())
- {
- ForEachItemIn(idx3, unfinishedWUIDs)
- {
- CDateTime tTime;
- unsigned year, month, day, hour, minute, second, nano;
- tTime.setString(unfinishedWUStarttime.item(idx3),NULL,true);
- tTime.getDate(year, month, day, true);
- tTime.getTime(hour, minute, second, nano, true);
- StringBuffer started, finished;
- started.appendf("%4d-%02d-%02dT%02d:%02d:%02dZ",year,month,day,hour,minute,second);
- if (notEmpty(unfinishedWUEndtime.item(idx3)))
- {
- tTime.setString(unfinishedWUEndtime.item(idx3),NULL,true);
- tTime.getDate(year, month, day, true);
- tTime.getTime(hour, minute, second, nano, true);
- finished.appendf("%4d-%02d-%02dT%02d:%02d:%02dZ",year,month,day,hour,minute,second);
- }
- sb.append("parent.displayJob(");
- appendQuoted(sb, unfinishedWUIDs.item(idx3), true);
- appendQuoted(sb, unfinishedGraphs.item(idx3));
- appendQuoted(sb, started.str());
- appendQuoted(sb, finished.str());
- appendQuoted(sb, unfinishedClusters.item(idx3));
- appendQuoted(sb, "not finished");
- if (showall)
- sb.append(",\'\',\'1\'");
- else
- sb.append(",\'\',\'0\'");
- sb.append(',').append(bbtime).append(',').append(betime).append(")\r\n");
- if(++count>=50)
- {
- sb.append("</script>\r\n");
- response->sendChunk(sb.str());
- sb.clear().append("<script language=\"javascript\">\r\n");
- count=0;
- }
- }
- }
- sb.append("</script>\r\n");
- response->sendChunk(sb.str());
- sb.clear().append("<script language=\"javascript\">\r\n");
- sb.append("parent.displaySasha();\r\nparent.displayEnd(");
- appendQuoted(sb, xls, true).append(")</script>\r\n");
- response->sendChunk(sb.str());
- }
- bool checkSameStrings(const char* s1, const char* s2)
- {
- if (s1)
- {
- if (s2 && streq(s1, s2))
- return true;
- }
- else if (!s2)
- return true;
- return false;
- }
- bool checkNewThorQueueItem(IEspThorQueue* tq, unsigned showAll, IArrayOf<IEspThorQueue>& items)
- {
- bool bAdd = false;
- if (showAll < 1) //show every lines
- bAdd = true;
- else if (items.length() < 1)
- bAdd = true;
- else if (showAll > 1) //last line now
- {
- IEspThorQueue& tq0 = items.item(items.length()-1);
- if (!checkSameStrings(tq->getDT(), tq0.getDT()))
- bAdd = true;
- }
- else
- {
- IEspThorQueue& tq0 = items.item(items.length()-1);
- if (!checkSameStrings(tq->getRunningWUs(), tq0.getRunningWUs()))
- bAdd = true;
- if (!checkSameStrings(tq->getQueuedWUs(), tq0.getQueuedWUs()))
- bAdd = true;
- if (!checkSameStrings(tq->getConnectedThors(), tq0.getConnectedThors()))
- bAdd = true;
- if (!checkSameStrings(tq->getConnectedThors(), tq0.getConnectedThors()))
- bAdd = true;
- if (!checkSameStrings(tq->getRunningWU1(), tq0.getRunningWU1()))
- bAdd = true;
- if (!checkSameStrings(tq->getRunningWU2(), tq0.getRunningWU2()))
- bAdd = true;
- }
- return bAdd;
- }
- void appendQueueInfoFromAuditLine(IArrayOf<IEspThorQueue>& items, const char* line, unsigned& longestQueue, unsigned& maxConnected, unsigned maxDisplay, unsigned showAll)
- {
- //2009-08-12 02:44:12 ,ThorQueueMonitor,thor400_88_dev,0,0,1,1,114,---,---
- if(!line || !*line)
- return;
- Owned<IEspThorQueue> tq = createThorQueue();
- StringBuffer dt, runningWUs, queuedWUs, waitingThors, connectedThors, idledThors, runningWU1, runningWU2;
- // date/time
- const char* bptr = line;
- const char* eptr = strchr(bptr, ',');
- if(eptr)
- dt.append(eptr - bptr, bptr);
- else
- dt.append(bptr);
- tq->setDT(dt.str());
- if(!eptr)
- {
- if (checkNewThorQueueItem(tq, showAll, items))
- items.append(*tq.getClear());
- return;
- }
- //skip title
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(!eptr)
- {
- if (checkNewThorQueueItem(tq, showAll, items))
- items.append(*tq.getClear());
- return;
- }
- //skip queue name
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(!eptr)
- {
- if (checkNewThorQueueItem(tq, showAll, items))
- items.append(*tq.getClear());
- return;
- }
- //running
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(eptr)
- runningWUs.append(eptr - bptr, bptr);
- else
- runningWUs.append(bptr);
- tq->setRunningWUs(runningWUs.str());
- if(!eptr)
- {
- if (checkNewThorQueueItem(tq, showAll, items))
- items.append(*tq.getClear());
- return;
- }
- //queued
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(eptr)
- queuedWUs.append(eptr - bptr, bptr);
- else
- queuedWUs.append(bptr);
- if (maxDisplay > items.length())
- {
- unsigned queueLen = atoi(queuedWUs.str());
- if (queueLen > longestQueue)
- longestQueue = queueLen;
- }
- tq->setQueuedWUs(queuedWUs.str());
- if(!eptr)
- {
- if (checkNewThorQueueItem(tq, showAll, items))
- items.append(*tq.getClear());
- return;
- }
- //waiting
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(eptr)
- waitingThors.append(eptr - bptr, bptr);
- else
- waitingThors.append(bptr);
- tq->setWaitingThors(waitingThors.str());
- if(!eptr)
- {
- if (checkNewThorQueueItem(tq, showAll, items))
- items.append(*tq.getClear());
- return;
- }
- //connected
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(eptr)
- connectedThors.append(eptr - bptr, bptr);
- else
- connectedThors.append(bptr);
- if (maxDisplay > items.length())
- {
- unsigned connnectedLen = atoi(connectedThors.str());
- if (connnectedLen > maxConnected)
- maxConnected = connnectedLen;
- }
- tq->setConnectedThors(connectedThors.str());
- if(!eptr)
- {
- if (checkNewThorQueueItem(tq, showAll, items))
- items.append(*tq.getClear());
- return;
- }
- //idled
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(eptr)
- idledThors.append(eptr - bptr, bptr);
- else
- idledThors.append(bptr);
- tq->setIdledThors(idledThors.str());
- if(!eptr)
- {
- items.append(*tq.getClear());
- return;
- }
- //runningWU1
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(eptr)
- runningWU1.append(eptr - bptr, bptr);
- else
- {
- runningWU1.append(bptr);
- }
- if (!strcmp(runningWU1.str(), "---"))
- runningWU1.clear();
- if (runningWU1.length() > 0)
- tq->setRunningWU1(runningWU1.str());
- if(!eptr)
- {
- if (checkNewThorQueueItem(tq, showAll, items))
- items.append(*tq.getClear());
- return;
- }
- //runningWU2
- bptr = eptr + 1;
- eptr = strchr(bptr, ',');
- if(eptr)
- runningWU2.append(eptr - bptr, bptr);
- else
- {
- runningWU2.append(bptr);
- }
- if (!strcmp(runningWU2.str(), "---"))
- runningWU2.clear();
- if (runningWU2.length() > 0)
- tq->setRunningWU2(runningWU2.str());
- if (checkNewThorQueueItem(tq, showAll, items))
- items.append(*tq.getClear());
- DBGLOG("Queue log: [%s]", line);
- }
- void streamJobQueueListResponse(IEspContext &context, const char *cluster, const char *from , const char *to, CHttpResponse* response, const char *xls)
- {
- if(!response)
- return;
- unsigned maxDisplay = 125;
- IArrayOf<IEspThorQueue> items;
- CDateTime fromTime;
- StringBuffer fromstr;
- if (notEmpty(from))
- {
- fromTime.setString(from, NULL, false);
- fromTime.getString(fromstr, false);
- }
- CDateTime toTime;
- StringBuffer tostr;
- if(notEmpty(to))
- {
- toTime.setString(to,NULL,false);
- toTime.getString(tostr, false);
- }
- StringBuffer filter("ThorQueueMonitor");
- if (notEmpty(cluster))
- filter.appendf(",%s", cluster);
- StringAttrArray lines;
- queryAuditLogs(fromTime, toTime, filter.str(), lines);
- unsigned countLines = 0;
- unsigned maxConnected = 0;
- unsigned longestQueue = 0;
- ForEachItemIn(idx, lines)
- {
- if(!lines.item(idx).text.length())
- continue;
- if (idx < (lines.length() - 1))
- appendQueueInfoFromAuditLine(items, lines.item(idx).text.get(), longestQueue, maxConnected, maxDisplay, 1);
- else
- appendQueueInfoFromAuditLine(items, lines.item(idx).text.get(), longestQueue, maxConnected, maxDisplay, 2);
- countLines++;
- }
- if (items.length() < 1)
- {
- response->sendChunk("<script language=\"javascript\">\r\nparent.displayQEnd(\'No data found\')</script>\r\n");
- return;
- }
- unsigned itemCount = items.length();
- if (itemCount > maxDisplay)
- itemCount = maxDisplay;
- StringBuffer sb;
- sb.append("<script language=\"javascript\">parent.displayQLegend()</script>\r\n");
- sb.append("<script language=\"javascript\">parent.displayQBegin(");
- sb.append(longestQueue).append(',').append(maxConnected).append(',').append(itemCount).append(")</script>\r\n");
- response->sendChunk(sb.str());
- sb.clear().append("<script language=\"javascript\">\r\n");
- unsigned count = 0;
- unsigned sbcount=0;
- ForEachItemIn(i,items)
- {
- IEspThorQueue& tq = items.item(i);
- count++;
- if (count > maxDisplay)
- break;
- sb.append("parent.displayQueue(");
- appendQuoted(sb, count, true);
- appendQuoted(sb, tq.getDT());
- appendQuoted(sb, tq.getRunningWUs());
- appendQuoted(sb, tq.getQueuedWUs());
- appendQuoted(sb, tq.getWaitingThors());
- appendQuoted(sb, tq.getConnectedThors());
- appendQuoted(sb, tq.getIdledThors());
- appendQuoted(sb, tq.getRunningWU1());
- appendQuoted(sb, tq.getRunningWU2());
- sb.append(")\r\n");
- if(++sbcount>=50)
- {
- sb.append("</script>\r\n");
- response->sendChunk(sb.str());
- sb.clear().append("<script language=\"javascript\">\r\n");
- sbcount=0;
- }
- }
- sb.append("parent.displayQEnd(\'<table><tr><td>");
- sb.append("Total Records in the Time Period: ").append(items.length());
- sb.append(" (<a href=\"/WsWorkunits/WUClusterJobQueueLOG?").append(xls);
- sb.append("\">txt</a>...<a href=\"/WsWorkunits/WUClusterJobQueueXLS?").append(xls).append("\">xls</a>).");
- sb.append("</td></tr><tr><td>");
- if (count > maxDisplay)
- sb.append("Displayed: First ").append(maxDisplay).append(". ");
- sb.append("Max. Queue Length: ").append(longestQueue).append(".");
- sb.append("</td></tr></table>\')</script>\r\n");
- response->sendChunk(sb.str());
- }
- int CWsWorkunitsSoapBindingEx::onGet(CHttpRequest* request, CHttpResponse* response)
- {
- IEspContext *ctx = request->queryContext();
- IProperties *params = request->queryParameters();
- try
- {
- StringBuffer path;
- request->getPath(path);
- if(!strnicmp(path.str(), "/WsWorkunits/JobList", 20))
- {
- const char *cluster = params->queryProp("Cluster");
- const char *startDate = params->queryProp("StartDate");
- const char *endDate = params->queryProp("EndDate");
- const char *showAll = params->queryProp("ShowAll");
- const char *busStart = params->queryProp("BusinessStartTime");
- const char *busEnd = params->queryProp("BusinessEndTime");
- float fBusStart = 0;
- float fBusEnd = 24;
- bool bShowAll = (isEmpty(showAll) ? false : (atoi(showAll)==1));
- if (bShowAll)
- {
- timeStrToFloat(busStart, fBusStart);
- timeStrToFloat(busEnd, fBusEnd);
- if(fBusStart <= 0 || fBusEnd > 24 || fBusStart >= fBusEnd)
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "Invalid business hours");
- }
- response->addHeader("Expires", "0");
- response->setContentType(HTTP_TYPE_TEXT_HTML_UTF8);
- StringBuffer xls("ShowAll=1");
- addToQueryString(xls, "Cluster", cluster);
- addToQueryString(xls, "StartDate", startDate);
- addToQueryString(xls, "EndDate", endDate);
- addToQueryString(xls, "BusinessStartTime", busStart);
- addToQueryString(xls, "BusinessEndTime", busEnd);
- streamJobListResponse(*ctx, cluster, startDate, endDate, response, bShowAll, fBusStart, fBusEnd, xls.str());
- return 0;
- }
- else if(!strnicmp(path.str(), "/WsWorkunits/JobQueue", 21))
- {
- const char *cluster = params->queryProp("Cluster");
- const char *startDate = params->queryProp("StartDate");
- const char *endDate = params->queryProp("EndDate");
- response->addHeader("Expires", "0");
- response->setContentType(HTTP_TYPE_TEXT_HTML_UTF8);
- StringBuffer xls;
- xls.append("ShowType=InGraph");
- addToQueryString(xls, "Cluster", cluster);
- addToQueryString(xls, "StartDate", startDate);
- addToQueryString(xls, "EndDate", endDate);
- streamJobQueueListResponse(*ctx, cluster, startDate, endDate, response, xls.str());
- return 0;
- }
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(*request->queryContext(), e, ECLWATCH_INTERNAL_ERROR);
- }
- return CWsWorkunitsSoapBinding::onGet(request,response);
- }
- bool CWsWorkunitsEx::onWUClusterJobQueueXLS(IEspContext &context, IEspWUClusterJobQueueXLSRequest &req, IEspWUClusterJobQueueXLSResponse &resp)
- {
- try
- {
- DBGLOG("WUClusterJobQueueXLS");
- SecAccessFlags accessOwn;
- SecAccessFlags accessOthers;
- getUserWuAccessFlags(context, accessOwn, accessOthers, true);
- StringBuffer xml("<WUResultExcel><Result>");
- getClusterJobQueueXLS(xml, req.getCluster(), req.getStartDate(), req.getEndDate(), req.getShowType());
- xml.append("</Result></WUResultExcel>");
- Owned<IProperties> params(createProperties());
- params->setProp("showCount",0);
- StringBuffer xls;
- xsltTransform(xml.str(), StringBuffer(getCFD()).append("./smc_xslt/result.xslt").str(), params, xls);
- MemoryBuffer mb;
- mb.setBuffer(xls.length(), (void*)xls.str());
- resp.setResult(mb);
- resp.setResult_mimetype("application/vnd.ms-excel");
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool CWsWorkunitsEx::onWUClusterJobQueueLOG(IEspContext &context,IEspWUClusterJobQueueLOGRequest &req, IEspWUClusterJobQueueLOGResponse &resp)
- {
- try
- {
- DBGLOG("WUClusterJobQueueLOG");
- SecAccessFlags accessOwn;
- SecAccessFlags accessOthers;
- getUserWuAccessFlags(context, accessOwn, accessOthers, true);
- CDateTime fromTime;
- if(notEmpty(req.getStartDate()))
- fromTime.setString(req.getStartDate(), NULL, false);
- CDateTime toTime;
- if(notEmpty(req.getEndDate()))
- toTime.setString(req.getEndDate(), NULL, false);
- const char *cluster = req.getCluster();
- StringBuffer filter("ThorQueueMonitor");
- if (notEmpty(cluster))
- filter.appendf(",%s", cluster);
- StringAttrArray lines;
- queryAuditLogs(fromTime, toTime, filter.str(), lines);
- StringBuffer text;
- ForEachItemIn(idx, lines)
- {
- if (lines.item(idx).text.isEmpty())
- continue;
- text.append(lines.item(idx).text.get()).append("\r\n");
- if (text.length()>LOGFILESIZELIMIT)
- {
- text.appendf("... ...");
- break;
- }
- }
- MemoryBuffer mb;
- mb.setBuffer(text.length(), (void*)text.str());
- resp.setThefile(mb);
- resp.setThefile_mimetype(HTTP_TYPE_TEXT_PLAIN);
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool CWsWorkunitsEx::onWUJobList(IEspContext &context, IEspWUJobListRequest &req, IEspWUJobListResponse &resp)
- {
- return true;
- }
- bool CWsWorkunitsEx::onWUClusterJobXLS(IEspContext &context, IEspWUClusterJobXLSRequest &req, IEspWUClusterJobXLSResponse &resp)
- {
- try
- {
- DBGLOG("WUClusterJobXLS");
- SecAccessFlags accessOwn;
- SecAccessFlags accessOthers;
- getUserWuAccessFlags(context, accessOwn, accessOthers, true);
- StringBuffer xml("<WUResultExcel><Result>");
- getClusterJobXLS(context.getClientVersion(), xml, req.getCluster(), req.getStartDate(), req.getEndDate(), req.getShowAll(), req.getBusinessStartTime(), req.getBusinessEndTime());
- xml.append("</Result></WUResultExcel>");
- Owned<IProperties> params(createProperties());
- params->setProp("showCount",0);
- StringBuffer xls;
- xsltTransform(xml.str(), StringBuffer(getCFD()).append("./smc_xslt/result.xslt").str(), params, xls);
- MemoryBuffer mb;
- mb.setBuffer(xls.length(), (void*)xls.str());
- resp.setResult(mb);
- resp.setResult_mimetype("application/vnd.ms-excel");
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool CWsWorkunitsEx::onWUClusterJobSummaryXLS(IEspContext &context, IEspWUClusterJobSummaryXLSRequest &req, IEspWUClusterJobSummaryXLSResponse &resp)
- {
- try
- {
- DBGLOG("WUClusterJobSummaryXLS");
- SecAccessFlags accessOwn;
- SecAccessFlags accessOthers;
- getUserWuAccessFlags(context, accessOwn, accessOthers, true);
- StringBuffer xml("<WUResultExcel><Result>");
- getClusterJobSummaryXLS(context.getClientVersion(), xml, req.getCluster(), req.getStartDate(), req.getEndDate(), req.getShowAll(), req.getBusinessStartTime(), req.getBusinessEndTime());
- xml.append("</Result></WUResultExcel>");
- StringBuffer xls;
- Owned<IProperties> params(createProperties());
- params->setProp("showCount",0);
- xsltTransform(xml.str(), StringBuffer(getCFD()).append("./smc_xslt/result.xslt").str(), params, xls);
- MemoryBuffer mb;
- mb.setBuffer(xls.length(), (void*)xls.str());
- resp.setResult(mb);
- resp.setResult_mimetype("application/vnd.ms-excel");
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
|