def __init__(self, name=None, parent=None, obj=None): pmModule.__init__(self, name, parent, obj) self.jobstates = ('Pilots', '%fail', 'Latest') + utils.jobStates + ('unassigned', ) self._ALL = ' ALL' self.lstates = len(self.jobstates) self.cloudList = pmt.getCloudList() self.clouds = [self._ALL] self.clouds += self.cloudList.keys() + ['CMS', 'AMS'] self._region4sites, self._sites4region = setutils.region4Sites(pmt) self._iFailed = utils.name2Index(self.jobstates, 'failed') self._iFinished = utils.name2Index(self.jobstates, 'finished') self._iRation = utils.name2Index(self.jobstates, '%fail') self._iPilots = utils.name2Index(self.jobstates, 'Pilots') self._iLatest = utils.name2Index(self.jobstates, 'Latest') self._jobSum = [ ['States', 'status'], ['Users', 'username'], ['Releases', 'transUses'], ['Processing Types', 'processingType'] # ,['Analysis Tasks' , 'destinationDBlock'] # tasktype = 'analysis' # ,['Output Dataset', 'destinationDBlock'] # tasktype = 'analysis' , ['Task Labels', 'prodSourceLabel'] # , ['Task ID' , 'JEDITASKID'] # ,['Batch system ID','batchID' ] , ['Transformations', 'transPath'] # ,['Input dataset' , 'prodDBlock'] , ['Working groups', 'workingGroup'] # ,['Creation Hosts' , 'creationHost'] # ,['Packages' , 'homepackage'] # need constrain # ,['Sites' , 'computingSite'] # , ['Regions' , 'Region'] , ['Clouds', 'cloud'], ['Task Types', 'taskType'], ['Jobs', 'JediTaskID'] # ,['Analysis Tasks', 'destinationDBlock'] # ,['Task Priorities' , 'currentPriority' ]# need constrain ] # self.clouds = 'ALL CA CERN DE ES FR IT ND NL RU TW UK US OSG CMS AMS'.split() self._description, params = utils.normalizeDbSchema( pmt, 'jobsarchived4') self.publishUI(self.doQuery, params=params)
def __init__(self,name=None,parent=None,obj=None): pmModule.__init__(self,name,parent,obj) self._jobstates = utils.jobStates self._lstates = len(self._jobstates) actIndex = utils.name2Index(self._jobstates,'activated')+1 canIndex = utils.name2Index(self._jobstates,'cancelled')+1 self._jobsFactoryStates = utils.parseArray(self._jobstates[:actIndex]) self._jobsWNStates = utils.parseArray(self._jobstates[actIndex:canIndex-1]) self._jobsCaneledStates = utils.parseArray(self._jobstates[canIndex:]) shift = 1 self._shift = shift self._ifailed = utils.name2Index(self._jobstates,'failed')+shift self._itotal = self._lstates+shift self._ifail = 0 self._description,params = utils.normalizeDbSchema(pmt,'jobsarchived4') self.publishUI(self.doQuery,params = params)
def __init__(self,name=None,parent=None,obj=None): pmModule.__init__(self,name,parent,obj) self.jobstates = ('Pilots','%fail','Latest')+utils.jobStates + ('unassigned',) self._ALL = ' ALL' self.lstates = len(self.jobstates) self.cloudList= pmt.getCloudList() self.clouds = [self._ALL] self.clouds += self.cloudList.keys() + ['CMS','AMS'] self._region4sites,self._sites4region = setutils.region4Sites(pmt) self._iFailed = utils.name2Index(self.jobstates,'failed') self._iFinished = utils.name2Index(self.jobstates,'finished') self._iRation = utils.name2Index(self.jobstates,'%fail') self._iPilots = utils.name2Index(self.jobstates,'Pilots'); self._iLatest = utils.name2Index(self.jobstates,'Latest'); self._jobSum = [ ['States' , 'status'] ,['Users' , 'username'] ,['Releases' ,'transUses'] ,['Processing Types' , 'processingType'] # ,['Analysis Tasks' , 'destinationDBlock'] # tasktype = 'analysis' # ,['Output Dataset', 'destinationDBlock'] # tasktype = 'analysis' ,['Task Labels' , 'prodSourceLabel'] # , ['Task ID' , 'JEDITASKID'] # ,['Batch system ID','batchID' ] ,['Transformations', 'transPath'] # ,['Input dataset' , 'prodDBlock'] ,['Working groups', 'workingGroup'] # ,['Creation Hosts' , 'creationHost'] # ,['Packages' , 'homepackage'] # need constrain # ,['Sites' , 'computingSite'] # , ['Regions' , 'Region'] , ['Clouds' , 'cloud'] , ['Task Types' , 'taskType'] , ['Jobs','JediTaskID'] # ,['Analysis Tasks', 'destinationDBlock'] # ,['Task Priorities' , 'currentPriority' ]# need constrain ] # self.clouds = 'ALL CA CERN DE ES FR IT ND NL RU TW UK US OSG CMS AMS'.split() self._description,params = utils.normalizeDbSchema(pmt,'jobsarchived4') self.publishUI(self.doQuery,params=params)
def __init__(self, name=None, parent=None, obj=None): pmModule.__init__(self, name, parent, obj) self._description = pmt.describe('^PANDALOG$') # add the optional parameters: params = {} ci = utils.name2Index(self._description['header'], 'column_name') collist = 'name message asctime Type PandaID loglevel levelname filename lineno module'.split( ) exclude = "pid line type name levelname BINTIME LOGUSER".upper().split( ) nmap = {} for c in collist: nmap[c.upper()] = c for c in self._description['rows']: p = not c[ci] in exclude nm = nmap.get(c[ci], c[ci]) c[ci] = nm if p: params[nm] = ' ' self._allparams = ','.join(params.keys()) self._levelmap = {'INFO': 20, 'WARNING': 30, 'DEBUG': 10, 'ERROR': 40} ## 'publishUI' must be the last init statement ! self.publishUI(self.doJson, params=params) self.publishUI(self.doScript, role=pmRoles.script())
def doQuery(self,tstart=None,tend=None,hours=6,days=None, type='FAXrecovery',limit=None,count=None,message=None): """ Shows Panda logger messages coming from FAX failovers. Messages are summarized per site. <ul> <li> tstart - the start time of the period the messages belongs to <li> tend - the start time of the period the messages belongs to <li> hours - select the messages for the last '24*days+hours' hours <li> days - select the messages for the last 'days+hours/24' days <li> limit - the max number of records to be fetched from the Db table <li> <b><a title='Click to see the full list of the jobinfo parameters available' href='http://pandamon.cern.ch/describe?table=^JOBSARCHIVED4&doc=*'>PARAM</a>=value</b> - comma-separated list of the value <a href ='https://twiki.cern.ch/twiki/bin/view/PanDA/PandaPlatform#API_parameter_value_format'> patterns</a> to filter the job records. </ul> """ site="panda.mon.fax" vals = self.extraValuesFilled() if vals == None: vals = {} if not vals.has_key("jobStatus"): vals["jobStatus"] = 'finished,cancelled,failed' levelcode= '' hrs = 0 try: hrs = int(hours) except: pass try: hrs += int(days)*24 days = None except: pass logwatch = Stopwatch() jobparam="computingSite,jobStatus,prodUserName" conditions=None q = pmt.getFaxInfo(site,type,levelcode, message=message, limit=limit, hours=hrs,select=["PID as PandaID ",'MESSAGE','Time'],selectjobs=jobparam,conditions=conditions,days=days,tstart=tstart,tend=tend,table='ATLAS_PANDA.PANDALOG_FAX tab') logwatch.stop() header = utils.normalizeSchema(q['header']) rows = q['rows'] main = {} main['header'] = [] main['info'] = rows try: count = int(count) main['count'] = count except: pass jobwatch = None if len(rows) > 0: jobwatch = Stopwatch() main['header'] = header # extract the "pandaid" iPandaId = utils.name2Index(header,'pandaid') if iPandaId ==None: iPandaId = utils.name2Index(header,'pid') iProdUserName = utils.name2Index(header,'prodUserName') iComputingSite = utils.name2Index(header,'computingSite') rows = sorted(rows, key=lambda fax: fax[iPandaId]) selRows = [] for r in rows: if r[iProdUserName] == 'gangarbt': continue r[iComputingSite] = self.cloud(r[iComputingSite]) selRows += [r] rows = selRows main['info'] = rows # split the message by variables header += self._faxVariables iMessage = utils.name2Index(header,'message') vIndx = utils.name2Index(header) for r in rows: r += [0]*len(self._faxVariables) try: faxcolumns = self.toObj(r[iMessage]) except: print " FAX message {%s} from the job record [%s] is corrupted" % (r[iMessage], r) continue for f in faxcolumns: try: r[vIndx[f]] = faxcolumns[f] except: raise ValueError(" len=%s r=%s f=%s vIndx=%s %s" % (len(r),r,f,vIndx,faxcolumns)) r.pop(iMessage) # removing message column header.pop(iMessage) # removing message from header jobwatch.stop() main['time'] = {'logquery': '%s' % logwatch,'jobquery': '%s' % jobwatch} main['params'] = {'hours':hrs} self.publish(main) self.publish( "%s/%s" % ( self.server().fileScriptURL(),"fax/%s.js" % "failoverfast" ),role=pmRoles.script() ) self.publishTitle("Panda report on jobs failovers to FAX over last %s hours " % hrs )
def do(self,header,rows,site,hostonly,details,f,w): states = self.states(f,w) iHost = utils.name2Index(header,'modificationhost') iSite = utils.name2Index(header,'computingSite') iStatus = utils.name2Index(header,'jobStatus') iJobs= utils.name2Index(header,'jobs') itotal = self.total(f,w) lrow = itotal+2 allSitesTotal = self.status(f,w) sites = [] wnlist = { 'st' :allSitesTotal, 'sites' : sites } wnlistStatus = wnlist['st'] nxSite = {'nm': None } nxHost = {'nm': None } hostStatus = None hosts = {} hostonly = isinstance(hostonly ,str) and hostonly.lower() == 'yes' sitesStat = {} for r in rows: if details != 'summary': siteName = r[iSite] if siteName == None: siteName = 'UNDEFINED' if sitesStat.has_key(siteName): siteStatus = sitesStat[siteName] else: nxSite = self.site(siteName,f,w) siteStatus = nxSite['st'] sites.append(nxSite) nxHost = {'nm' : None} hosts = {} sitesStat[siteName] = siteStatus host = r[iHost] if hostonly: host = utils.hostName(host) if not hosts.has_key(host): nxHost = self.host(host,f,w) hostStatus = nxHost['st'] if details and details != 'summary': nxSite['hosts'].append(nxHost) hosts[host] = hostStatus else: hostStatus = hosts[host] status = r[iStatus] jbs = r[iJobs] istatus = utils.name2Index(states,status)+1 if details and details != 'summary': hostStatus[istatus] += jbs hostStatus[itotal] += jbs if details != 'summary': siteStatus[istatus] += jbs siteStatus[itotal] += jbs wnlistStatus[istatus] += jbs wnlistStatus[itotal]+= jbs # --- if f == None: if len(rows) > 0: self.countFail(wnlistStatus,w) wsites = wnlist['sites'] for c in wsites: self.countFail(c['st'],w) for h in c['hosts']: self.countFail(h['st'],w) c['hosts'] = sorted(c['hosts'], key=lambda site: site['nm']) header = ['fail'] + list(states) + ['Total'] res = {"header" : header , 'status' : wnlist} # print utils.lineInfo(), details ,len(hosts) if details == 'summary': res['hosts']=len(hosts) return res
def doJobs( self, pandaid=None, params=None, jobparam=None, table=None, hours=None, tstart=None, tend=None, field="modificationTime", days=None, format=None, jobtype=None, testsite=None, limit=1500, summary=None, minjob=1, dump=None, region=None, lfn=None, showcpu=None, ): ## Perform the query main = {} errorcolcheck = False selection = "*" vals = self.extraValuesFilled(self._alias) title = "PanDA Job(s)" if utils.isFilled(pandaid): hours = None days = None title += " %s " % pandaid if days != None: title += " for %.2f Day" % float(days) if days > 1: title += "s" if hours != None: if days == None: title += " for " title += " %d Hour" % int(hours) if hours > 1: title += "s" if vals != None: for k in vals.keys(): if vals[k] == "undefined": vals[k] = None elif ( vals[k] != None and k.lower() == "jobstatus" and ( vals[k].lower().find("prerun") >= 0 or vals[k].lower().find("finishing") >= 0 or vals[k].lower().find("unassigned") >= 0 or vals[k].lower().find("retried") >= 0 ) ): stvals = utils.parseArray(vals[k]) statvals = [] for v in stvals: if v.lower() == "prerun": statvals += ["defined", "assigned", "waiting", "activated", "pending", "sent", "starting"] elif v.lower() == "finishing": statvals += ["holding", "transferring"] elif v.lower() == "unassigned": vals["computingSite"] = "NULL" statvals += ["cancelled"] elif v.lower() == "retried": # See the slide 3 from Tadashi: https://indico.cern.ch/getFile.py/access?contribId=13&sessionId=11&resId=0&materialId=slides&confId=119171 vals["taskBufferErrorCode"] = [106, 107] statvals += ["failed"] else: statvals += [v] vals[k] = ",".join(statvals) cleanVal = dict((k, v) for k, v in vals.iteritems() if v is not None) vals = cleanVal if vals == None: vals = {} nav = "" certificate = None certusr = None try: cert = self.server().certificate() if cert != None: certusr = pmt.cleanUserID(cert) main["ceruser"] = certusr except: pass if vals.get("prodUserName") == "auto" and certusr != None: if cert != None: vals["prodUserName"] = certusr for v in vals: nav += "<b>%s</b>=%s " % (v, vals[v]) # nav += "<span id=linkjobid stule='display:inline'></span>" # nav +="<script>$(document).ready(function(){$('#linkjobid').html(utils().linkJobs(s.cloud,jobtype" # nav += jobtype if jobtype!=None else "undefined" # nav += ", s.jobStatus, " # nav += "%d" % hours if hours!=None else "undefined" # nav += ", s.computingSite,'Classic Page' ))});</script>"; if not utils.isFilled(summary): nav += "<b>%s</b>=%s " % ("limit", limit) self.publishNav(nav) if len(vals) == 0: vals = None if vals == None and jobparam == None: main["Description"] = self.description() else: if lfn != None and lfn != "undefined": lfnselect = "pandaid,lfn" lfnjobs = pmt.getJobLFN(select=lfnselect, table="new", lfn=lfn, pandaid=pandaid, type="*", limit=limit) if lfnjobs["rows"] > 0: pandaid = [ljobs[0] for ljobs in lfnjobs["rows"]] selection = {} if vals != None: selection.update(vals) if pandaid != None: selection.update({nmap.get("pandaid"): pandaid}) if region != None: selection.update({"region": region}) main["Selection"] = selection conditions = vals if conditions == None: conditions = {} cs = conditions.get("computingSite") if cs == None: site4region = self.getSite4Region(region) if site4region != None and len(site4region) > 0: conditions["computingSite"] = site4region else: pass # ignore the region parameter if utils.isValid(summary): jobtype = ( "production" if jobtype == None and jobparam.lower().find("taskid") >= 0 and jobparam.lower().find("jeditaskid") < 0 else jobtype ) jobs = pmt.getJobsAtt( pandaid, jobparam, conditions, None, hours, tstart, tend, field, days, format, jobtype, testsite, None, True, ) rows = jobs["rows"] indx = [] if len(rows) > 30: for i, r in enumerate(rows): try: if r[1] > minjob: indx.append(i) continue except: pass cleanrows = [rows[i] for i in indx] jobs["rows"] = cleanrows istatus = utils.name2Index(jobs["header"], "jobstatus") if istatus != None: statOrder = utils.name2Index(utils.jobStates) def byStatus(a, b): return statOrder[a[istatus]] - statOrder[b[istatus]] jobs["rows"] = sorted(jobs["rows"], cmp=byStatus) else: if jobparam == self._allparams and conditions.get(self._jobParametersName) == None: conditions[self._jobParametersName] = "any" jobs = pmt.getJobsAtt( pandaid, "PandaID," + jobparam, conditions, None, hours, tstart, tend, field, days, format, jobtype, testsite, limit, ) errorcolcheck = True if len(jobs) > 0: header = [nmap.get(h) for h in jobs["header"]] info = jobs["rows"] main["header"] = header # + self._extraFields timecols = [] errdict = None errorcol = not errorcolcheck for i, h in enumerate(header): if "time" in h.lower() and "cpuconsumptiontime" != h.lower(): timecols.append(i) if not errorcol and "error" in h.lower(): errorcol = True ## # add an artificial retryID ## header += ['retryID'] headindx = utils.name2Index(header) creationtDict = {} histograms = {} prodSourceLabel = headindx.get("prodSourceLabel") jobStatus = headindx.get("jobStatus") status4title = conditions.get("jobStatus") if not utils.isFilled(status4title): if len(info) == 1 and jobStatus != None: status4title = info[0][jobStatus] if utils.isFilled(status4title): title = status4title[0].upper() + status4title[1:] + " " + title prodtype = "production" in jobtype.lower() if jobtype != None else True taskidsum = prodtype if not utils.isValid(summary) and dump != "yes": jsets = setutils.factory(header, info, self._errorCodes, self._siteId, self._siteNicks) main["jobset"] = jsets.jobsets() for r in info: if not taskidsum and ((prodSourceLabel and r[prodSourceLabel] == "managed") and prodtype): taskidsum = True if errorcol and errorcolcheck: errdict = self.getErrors(r, headindx, errdict) for t in timecols: r[t] = utils.epochTime(r[t]) ## r += [None] # retryID # row = self.jobsetTime(utils.zip(header(info[r])),creationtDict,histograms) # info[r] = self.addFields(utils.zip(header(info[r])),creationtDict,histograms) # Action cleanUserID SSL_CLIENT_S_DN main["info"] = info if errorcolcheck: main["errorCodes"] = errdict main["colNames"] = sorted(header) main["jobsummary"] = copy.copy(self._jobSum) if taskidsum: main["jobsummary"] += [["Task ID", "taskID"]] # print utils.lineInfo(), "===============", self._description.get("JEDITASKID"), self._description.get("JediTaskID") # if self._description.get("JEDITASKID") or self._description.get("JediTaskID"): # main['jobsummary'] += [['Jedi ID','JediTaskID']] elif jobtype != "jedi": main["jobsummary"] += [["Jobsets", "jobsetID"]] # need constrain elif jobtype == "analysis": main["jobsummary"] += [["Analysis Tasks", "destinationDBlock"]] if showcpu == "yes": main["jobsummary"] += [["CPU Type", "cpuConsumptionUnit"]] self.publishTitle(title) return main
def doQuery(self, jobtype='production,test', hours=12, cores=2, vo=None, computingSite=None, processingType=None, workingGroup=None, prodUserName=None, specialHandling=None, region=False): if int(hours) > 24 * 3: hours = 24 * 3 title = 'Job summary from the MultiCore sites for the last %s hours only.' % hours # Use <a href="%s/?%s">"stats"</a> page to see all %s hours' % ( 24 * 3, utils.monURL, 'mode=sitestats', hours ) else: title = 'Job summary from the MultiCore sites for the last %s hours' % hours self.publishTitle(title) modes = ('Defined', 'Waiting', 'Active', 'Archived') rows = [] cores = cores if cores != None else 0 for mode in modes: q = pmt.getCloudSummary( jobtype, vo, hours, selectionFields= 'computingSite,processingType,workingGroup, prodUserName,specialHandling,coreCount', tablename='ATLAS_PANDA.jobs%s4' % mode) if len(rows) == 0: header = q['header'] rows += q['rows'] ### Build the jobsumd dictionary jobsumd = {} proctyped = {} workgroupd = {} userd = {} spechandled = {} for c in self.clouds: jobsumd[c] = {} jobsumd[c]['ALL'] = [0] * (self.lstates + 1) if c != 'ALL': jobsumd[c]['status'] = self.cloudList[c]['status'] iCloud = utils.name2Index(header, 'cloud') print utils.lineInfo(), header iComputingSite = utils.name2Index(header, 'computingSite') iStatus = utils.name2Index(header, 'jobStatus') iProctype = utils.name2Index(header, 'processingType') iSpechandle = utils.name2Index(header, 'specialHandling') iWorkgroup = utils.name2Index(header, 'workingGroup') iUser = utils.name2Index(header, 'prodUserName') iCore = utils.name2Index(header, 'coreCount') iCount = utils.name2Index(header, 'COUNT') for r in rows: ncores = r[iCore] if r[iCore] != None else 0 if cores != 0 and ncores < cores: continue site = r[iComputingSite] if site == None: # print "Db record doesn't define any site: %s " % r if region: continue site = "Unknown" # continue cloud = r[iCloud] # utils.getCloud4Site(r) status = r[iStatus] istatus = utils.name2Index(self.jobstates, status) proctype = r[iProctype] spechandle = r[iSpechandle] workgroup = r[iWorkgroup] user = r[iUser] count = r[iCount] if not cloud in jobsumd: print 'Unknown cloud: %s for site %s ' % (cloud, site) continue cloud = 'ALL' if not status in self.jobstates: print 'Unknown jobstate:', status continue if not site in jobsumd[cloud]: jobsumd[cloud][site] = {} jobsumd[cloud][site] = [0] * (self.lstates + 1) jobsumd[cloud][site][ self.lstates] = ncores if ncores != None else 0 jobsumd[cloud][site][istatus] += count if cloud != 'ALL': jobsumd[cloud]['ALL'][istatus] += count jobsumd['ALL']['ALL'][istatus] += count proctyped[proctype] = proctyped.get(proctype, 0) + count workgroupd[workgroup] = workgroupd.get(workgroup, 0) + count userd[user] = userd.get(user, 0) + count if spechandle != None: spechandled[spechandle] = spechandled.get(spechandle, 0) + count ## Get cloud/site status main = {} main['states'] = self.jobstates main['jobsumd'] = jobsumd main['params'] = { 'jobtype': jobtype, 'hours': hours, 'vo': vo, 'computingSite': computingSite, 'processingType': processingType, 'workingGroup': workingGroup, 'prodUserName': prodUserName, 'specialHandling': specialHandling, 'cores': cores, 'region': region } self.publish(main) self.publishNav(' type=%s hours=%s' % (jobtype, hours)) self.publish( "%s/%s" % (self.server().fileScriptURL(), "monitor/%s.js" % "mcore"), role="script")
def failed(self,f,w): ifl = utils.name2Index(self.states(f,w),'failed') if ifl !=None: ifl += self._shift return ifl
def doQuery(self, jobtype='production', hours=24, vcloud='IAAS', testJobs=None): if int(hours) > 24 * 3: hours = 24 * 3 title = "ATLAS '%s' Virtualized Sites for the Last %s Hours Only." % ( vcloud, hours ) # Use <a href="%s/?%s">"stats"</a> page to see all %s hours' % ( 24 * 3, utils.monURL, 'mode=sitestats', hours ) else: title = "ATLAS '%s' Virtualized Sites for the last %s hours" % ( vcloud, hours) self.publishTitle(title) modes = ('Defined', 'Waiting', 'Active', 'Archived') rows = [] t = [] for mode in modes: t += ['ATLAS_PANDA.jobs%s4' % mode] q = pmt.getVCloudSummary(jobtype, hours, table=','.join(t), vcloud=vcloud, testsite=(testJobs != None)) header = q['header'] rows = q['rows'] ### Build the jobsumd dictionary jobsumd = {} for c in [ 'ALL', ]: jobsumd[c] = {} jobsumd[c]['ALL'] = [0] * (self.lstates + 2) jobsumd[c] = {} jobsumd[c]['ALL'] = [0] * (self.lstates + 2) iCloud = utils.name2Index(header, 'cloud') iComputingSite = utils.name2Index(header, 'computingSite') iStatus = utils.name2Index(header, 'jobStatus') iCount = utils.name2Index(header, 'COUNT') iCpu = utils.name2Index(header, 'cpuConsumptionTime') icpu = self.lstates for r in rows: site = r[iComputingSite] if site == None: # print "Db record doesn't define any site: %s " % r if region: continue site = "Unknown" # continue cloud = r[iCloud] # utils.getCloud4Site(r) status = r[iStatus] istatus = utils.name2Index(self.jobstates, status) count = r[iCount] cpu = r[iCpu] if not jobsumd.has_key(cloud): jobsumd[cloud] = {} jobsumd[cloud]['ALL'] = [0] * (self.lstates + 1) if cloud != 'ALL': jobsumd[cloud]['status'] = self.cloudList[cloud]['status'] if cloud == 'CERN' and vcloud == 'IAAS': # fake site for the time being jobsumd[cloud]['HELIX_ATOS'] = {} jobsumd[cloud]['HELIX_ATOS'] = [0] * (self.lstates + 1) if not status in self.jobstates: print 'Unknown jobstate:', status continue if not site in jobsumd[cloud]: jobsumd[cloud][site] = {} jobsumd[cloud][site] = [0] * (self.lstates + 1) jobsumd[cloud][site][istatus] += count jobsumd[cloud]['ALL'][istatus] += count jobsumd['ALL']['ALL'][istatus] += count jobsumd[cloud][site][icpu] += cpu jobsumd[cloud]['ALL'][icpu] += cpu jobsumd['ALL']['ALL'][icpu] += cpu ## Get cloud/site status main = {} main['states'] = list(self.jobstates) + ["CPU (hours)"] main['jobsumd'] = jobsumd main['params'] = { 'jobtype': jobtype, 'hours': hours, 'computingSite': vcloud } if testJobs == None: main['params']['srcLabel'] = 'managed' self.publish(main) self.publishNav( ' <b>type</b>=%s <b>hours</b>=%s <b>date:</b> %s' % (jobtype, hours, datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S'))) self.publish( "%s/%s" % (self.server().fileScriptURL(), "monitor/%s.js" % "vcloud"), role=pmRoles.script()) self.publish({'s-maxage': 340, 'max-age': 200}, role=pmRoles.cache())
def doQuery(self, jobtype='production', hours=12, region=None): """ <ul> <li>jobtype - production,analysis, test <li>hours - production,analysis, test <li>VO - virtual organization atlas,cms <li>computingSite <li>processingType <li>workingGroup <li>prodUserName <li>specialHandling </ul> """ if int(hours) > 24 * 3: hours = 24 * 3 title = 'Job summary for the last %s hours only.' % hours # Use <a href="%s/?%s">"stats"</a> page to see all %s hours' % ( 24 * 3, utils.monURL, 'mode=sitestats', hours ) else: title = 'Job summary for the past %s hours' % hours pars = self.extraValuesFilled() self.publishTitle(title) nav = ' <b>type</b>=%s <b>hours</b>=%s' % (jobtype, hours) if pars != None: for tp in [ 'computingSite', 'processingType', 'workingGroup', 'prodUserName', 'specialHandling' ]: if pars.get(tp) != None: nav += ' <b>%s</b>=%s' % (tp, pars[tp]) modes = ('Defined', 'Waiting', 'Active', 'Archived') rows = [] for mode in modes: q = pmt.getCloudSummary( jobtype, pars.get('VO') if pars != None else None, hours, extraConditions=pars, selectionFields= 'computingSite,processingType,workingGroup, prodUserName,specialHandling,modificationTime', tablename='ATLAS_PANDA.jobs%s4' % mode) if len(rows) == 0: header = q['header'] rows += q['rows'] # get getCurrentSiteData pilotd = pmt.getCurrentSiteData() ### Build the jobsumd dictionary jobsumd = {} proctyped = {} workgroupd = {} userd = {} spechandled = {} item = self.clouds if region != None: item = [self._ALL] + self._sites4region.keys() for c in item: jobsumd[c] = {} jobsumd[c][self._ALL] = [0] * self.lstates if c != self._ALL: jobsumd[c]['status'] = self.cloudList.get( c, {'status': 'unknown'})['status'] iCloud = utils.name2Index(header, 'cloud') iComputingSite = utils.name2Index(header, 'computingSite') iStatus = utils.name2Index(header, 'jobStatus') iProctype = utils.name2Index(header, 'processingType') iSpechandle = utils.name2Index(header, 'specialHandling') iWorkgroup = utils.name2Index(header, 'workingGroup') iUser = utils.name2Index(header, 'prodUserName') iCount = utils.name2Index(header, 'COUNT') iTime = utils.name2Index(header, 'modificationTime') iLatest = self._iLatest def updateTime(oldt, newt): ol = oldt[iLatest] if (ol != 0 and ol < newt) or ol == 0: oldt[iLatest] = newt for r in rows: site = r[iComputingSite] if site == None: # print "Db record doesn't define any site: %s " % r regn = "unassigned" site = "unassigned" if region != None: continue # continue else: regn = self._region4sites.get(site, 'unknown') if region != None and regn == 'unknown': continue cloud = r[iCloud] # utils.getCloud4Site(r) status = r[iStatus] if status == 'cancelled' and site == 'Unknown': status = 'unassigned' istatus = utils.name2Index(self.jobstates, status) proctype = r[iProctype] spechandle = r[iSpechandle] workgroup = r[iWorkgroup] user = r[iUser] count = r[iCount] time = r[iTime] if region != None: cloud = regn if not cloud in jobsumd: print 'Unknown cloud: %s for site %s ' % (cloud, site) continue if not status in self.jobstates: print 'Unknown jobstate:', status continue if not site in jobsumd[cloud]: jobsumd[cloud][site] = {} jobsumd[cloud][site] = [0] * self.lstates jobsumd[cloud][site][istatus] += count jobsumd[cloud][self._ALL][istatus] += count jobsumd[self._ALL][self._ALL][istatus] += count updateTime(jobsumd[cloud][site], time) updateTime(jobsumd[cloud][self._ALL], time) updateTime(jobsumd[self._ALL][self._ALL], time) proctyped[proctype] = proctyped.get(proctype, 0) + count workgroupd[workgroup] = workgroupd.get(workgroup, 0) + count userd[user] = userd.get(user, 0) + count if spechandle != None: spechandled[spechandle] = spechandled.get(spechandle, 0) + count iFailed = self._iFailed iFinished = self._iFinished iRation = self._iRation iPilots = self._iPilots for cloud in jobsumd: for site in jobsumd[cloud]: if site == 'status': continue allcloud = jobsumd[cloud][site] ntot = allcloud[iFailed] + allcloud[iFinished] psite = pilotd.get(site) if psite: nplt = pilotd[site]['updateJob'] + pilotd[site]['getJob'] jobsumd[cloud][site][iPilots] = nplt jobsumd[cloud][self._ALL][iPilots] += nplt jobsumd[self._ALL][self._ALL][iPilots] += nplt if ntot > 0: jobsumd[cloud][site][ iRation] = 100.0 * allcloud[iFailed] / ntot ## Get cloud/site status main = {} main['states'] = self.jobstates main['jobsumd'] = jobsumd if pars == None: pars = {} if (hours != None): pars['hours'] = hours if (jobtype != None): pars['jobtype'] = jobtype if (region != None): pars['region'] = region nav += ' <b>region view</a>' main['params'] = pars self.publish(main) self.publishNav(nav) self.publish( "%s/%s" % (self.server().fileScriptURL(), "monitor/%s.js" % "cloudsummary"), role=pmRoles.script())
def doJson(self,hours=None,days=180,tstart=None,tend=None,PRODUSERNAME=None,top='nJobsA', topsize=0): """ Get the list of the users <ul> <li> hours = use the last hours <li> days = use the last days <li> topsize - the size of the top list <br> = 0 - all users are shown <li> top - select top list using 'top' column <ul> <li> 'nJobsA' - the number of the jobs <li> 'CPUA1' - Personal the CPU used for the last 24 hours <li> 'CPUA7' - Personal Cpu used for the last 7 days <li> 'CPUP1' - Group Cpu for the last 24 hours <li> 'CPUP7' - Group Cpu for the last 7 days </ul> </ul> """ if days == None: days = 0 if hours == None: hours = 0 main = {"buffer":{ "params" : {'hours' : days*24+hours } , "method" : 'getUsers' , "type" : False } } columns="name,njobsa,latestjob,cpua1,cpua7,cpup1,cpup7" if topsize==0 or topsize==None: columns+=",scriptcache" q = pmt.getUsers(PRODUSERNAME,days*24+hours,columns=columns) header = q['header'] users = q['rows'] if PRODUSERNAME == None: if topsize > 0: title = "Recent %(topsize)d Top Panda Analysis Users" % { 'topsize' : topsize } else: title = "Recent Panda Analysis Users" else: title = "PanDA jobs for %s" % PRODUSERNAME main["buffer"]["params"]['user'] = PRODUSERNAME, iNJobs = utils.name2Index(header,"njobsa") iLatest = utils.name2Index(header,"latestjob") jobpertime = {"anajobs" : 0, "n1000" : 0, "n10k" : 0 } recent = { "d3" :0, "d7" :0 , "d30" : 0, "d90" : 0, "d180" :0 } for u in users: nxtp = u[iNJobs] if nxtp == None: continue nxtp = int(nxtp) if nxtp > 0 : jobpertime["anajobs"] += nxtp if nxtp > 1000: jobpertime["n1000"] += 1; if nxtp > 10000: jobpertime["n10k"] += 1 nxtp = u[iLatest] if nxtp != None: diffdays = (datetime.utcnow() - nxtp).days; if diffdays < 4: recent["d3"] += 1 if diffdays < 8: recent["d7"] += 1 if diffdays < 31: recent["d30"] += 1 if diffdays < 91: recent["d90"] += 1 if diffdays < 181: recent["d180"] += 1 if topsize > 0 and top != None: iTop = utils.name2Index(header,top) users = self.makeTop(users,iTop)[:topsize] main["buffer"]["top"] = { 'top' : top, 'size' : topsize } # remove thr group main["buffer"]["data"] = {'header' : header,'rows' : users } main["buffer"]["totaljobs"] = jobpertime main["buffer"]["recent"] = recent self.publishTitle(title) self.publish(main) self.publish( "%s/%s" % (utils.fileScriptURL(),"taskBuffer/%s.js" % "getUsers"),role="script") return
def doQuery(self,jobtype='production',hours=24,vcloud='IAAS',testJobs=None): if int(hours) > 24 * 3: hours = 24 * 3 title = "ATLAS '%s' Virtualized Sites for the Last %s Hours Only." % (vcloud,hours) # Use <a href="%s/?%s">"stats"</a> page to see all %s hours' % ( 24 * 3, utils.monURL, 'mode=sitestats', hours ) else: title = "ATLAS '%s' Virtualized Sites for the last %s hours" % (vcloud,hours) self.publishTitle(title) modes = ( 'Defined', 'Waiting', 'Active', 'Archived' ) rows = [] t = [] for mode in modes: t += ['ATLAS_PANDA.jobs%s4' % mode] q = pmt.getVCloudSummary(jobtype,hours,table=','.join(t),vcloud=vcloud,testsite=(testJobs!=None)) header = q['header'] rows = q['rows'] ### Build the jobsumd dictionary jobsumd = {} for c in ['ALL',]: jobsumd[c] = {} jobsumd[c]['ALL'] = [0]*(self.lstates+2) jobsumd[c] = {} jobsumd[c]['ALL'] = [0]*(self.lstates+2) iCloud = utils.name2Index(header,'cloud') iComputingSite = utils.name2Index(header,'computingSite') iStatus = utils.name2Index(header,'jobStatus') iCount = utils.name2Index(header,'COUNT') iCpu = utils.name2Index(header,'cpuConsumptionTime') icpu = self.lstates for r in rows: site = r[iComputingSite] if site == None: # print "Db record doesn't define any site: %s " % r if region: continue site="Unknown" # continue cloud = r[iCloud] # utils.getCloud4Site(r) status = r[iStatus] istatus = utils.name2Index(self.jobstates,status) count = r[iCount] cpu = r[iCpu] if not jobsumd.has_key(cloud): jobsumd[cloud] = {} jobsumd[cloud]['ALL'] = [0]*(self.lstates+1) if cloud != 'ALL': jobsumd[cloud]['status'] = self.cloudList[cloud]['status'] if cloud == 'CERN' and vcloud == 'IAAS': # fake site for the time being jobsumd[cloud]['HELIX_ATOS'] = {} jobsumd[cloud]['HELIX_ATOS'] = [0]*(self.lstates+1) if not status in self.jobstates: print 'Unknown jobstate:', status continue if not site in jobsumd[cloud]: jobsumd[cloud][site] = {} jobsumd[cloud][site] = [0]*(self.lstates+1) jobsumd[cloud][site][istatus] += count jobsumd[cloud]['ALL'][istatus] += count jobsumd['ALL']['ALL'][istatus] += count jobsumd[cloud][site][icpu] += cpu jobsumd[cloud]['ALL'][icpu] += cpu jobsumd['ALL']['ALL'][icpu] += cpu ## Get cloud/site status main = {} main['states'] = list(self.jobstates) + ["CPU (hours)"] main['jobsumd'] = jobsumd main['params'] = { 'jobtype': jobtype,'hours': hours ,'computingSite': vcloud } if testJobs == None: main['params']['srcLabel'] = 'managed' self.publish(main) self.publishNav(' <b>type</b>=%s <b>hours</b>=%s <b>date:</b> %s' % (jobtype, hours, datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') ) ) self.publish( "%s/%s" % ( self.server().fileScriptURL(),"monitor/%s.js" % "vcloud" ),role=pmRoles.script() ) self.publish( {'s-maxage':340,'max-age': 200}, role=pmRoles.cache())
def doJson(self,hours=None,days=180,tstart=None,tend=None,PRODUSERNAME=None,top='CPUA7', topsize=0,name=None): """ Get the list of the users <ul> <li> hours = use the last hours <li> days = use the last days <li> PRODUSERNAME or name - the comma separated pattern to select the list of the users. <li> topsize - the size of the top list <br> = 0 - all users are shown <li> top - the comma separated list to select top users using 'top' columns. <ul> <li> 'nJobsA' - the number of the jobs <li> 'CPUA1' - Personal the CPU used for the last 24 hours <li> 'CPUA7' - Personal Cpu used for the last 7 days <li> 'CPUP1'- Group the CPU used for the last 24 hours <li> 'CPUP7'- Group Cpu used for the last 7 days </ul> The order of the column names defines the default sorting. <br>For example: top='cpua7,nJobsA' creates the table sorted by "7 days " cpu and by "number of the jobs" <br> the parameter is essential for CLI (aka 'curl'/'ajax') clients. The Web Browser user can override the default by clicking onto the column header </ul> """ if days == None: days = 0 if hours == None: hours = 0 main = {"buffer":{ "params" : {'hours' : days*24+hours } , "method" : 'getUsers' , "type" : False } } columns="name,njobsa,cpua1,cpua7,latestjob" if topsize==0 or topsize==None: columns="name,njobsa,latestjob,cpua1,cpua7,cpup1,cpup7,scriptcache" elif 'pup' in top.lower(): columns="name,njobsa,cpup1,cpup7,latestjob,scriptcache" if PRODUSERNAME == None: PRODUSERNAME = name q = pmt.getUsers(PRODUSERNAME,days*24+hours,columns=columns) header = q['header'] users = q['rows'] if PRODUSERNAME == None: if topsize > 0: title = "Recent %(topsize)d Top Panda Analysis Users" % { 'topsize' : topsize } else: title = "Recent Panda Analysis Users" else: title = "PanDA jobs for %s" % PRODUSERNAME main["buffer"]["params"]['user'] = PRODUSERNAME, iNJobs = utils.name2Index(header,"njobsa") iLatest = utils.name2Index(header,"latestjob") iCpua1 = utils.name2Index(header,"cpua1") iCpua7 = utils.name2Index(header,"cpua7") iCpup1 = utils.name2Index(header,"cpup1") iCpup7 = utils.name2Index(header,"cpup7") jobpertime = {"anajobs" : 0, "n1000" : 0, "n10k" : 0 } recent = { "d3" :0, "d7" :0 , "d30" : 0, "d90" : 0, "d180" :0 } for u in users: nxtp = u[iNJobs] if nxtp == None: continue nxtp = int(nxtp) if nxtp > 0 : jobpertime["anajobs"] += nxtp if nxtp > 1000: jobpertime["n1000"] += 1; if nxtp > 10000: jobpertime["n10k"] += 1 nxtp = u[iLatest] if nxtp != None: diffdays = (datetime.utcnow() - nxtp).days; if diffdays < 4: recent["d3"] += 1 if diffdays < 8: recent["d7"] += 1 if diffdays < 31: recent["d30"] += 1 if diffdays < 91: recent["d90"] += 1 if diffdays < 181: recent["d180"] += 1 if topsize > 0 and diffdays > 7 : # exclude the old users from the count if iCpua1 >=0: u[iCpua1] = 0; if iCpua7 >=0: u[iCpua7] = 0; if iCpup1 >=0: u[iCpup1] = 0; if iCpup1 >=0: u[iCpup7] = 0; if topsize > 0 and top != None: vtop = top.split(",") iTop = tuple( utils.name2Index(header,t) for t in vtop) users = self.makeTop(users,iTop)[:topsize] main["buffer"]["top"] = { 'top' : top, 'size' : topsize } njobsa = 0 cpua1 = 0 cpua7 = 0 cpup1 = 0 cpup7 = 0 finalusers = [] for u in users: nxtp = u[iNJobs] if nxtp == None: continue njobsa+= nxtp cpu = 0 if iCpua1 >=0: cpua1 += u[iCpua1] cpu += u[iCpua1] if iCpua7 >=0: cpua7 += u[iCpua7] cpu += u[iCpua7] if iCpup1 >=0: cpup1 += u[iCpup1] cpu += u[iCpup1] if iCpup7 >=0: cpup7 += u[iCpup7] cpu += u[iCpup7] if cpu >0: njobsa+= nxtp finalusers.append(u) users = finalusers main["buffer"]["data"] = {'header' : header,'rows' : users } main["buffer"]["totaljobs"] = jobpertime if topsize > 0: if iCpua1>=0 or iCpua7 >=0: main["buffer"]["totaltop"] = {'njobsa' :njobsa,'cpua1':cpua1, 'cpua7': cpua7 } else: main["buffer"]["totaltop"] = {'njobsa' :njobsa,'cpup1':cpup1, 'cpup7': cpup7 } main["buffer"]["recent"] = recent self.publishTitle(title) self.publish(main) self.publish( "%s/%s" % (self.server().fileScriptURL(),"taskBuffer/%s.js" % "getUsers"),role="script") return
def doQuery(self,jobtype='production,test',hours=12,cores=2,vo=None,computingSite=None,processingType=None,workingGroup=None,prodUserName=None,specialHandling=None,region=False): if int(hours) > 24 * 3: hours = 24 * 3 title = 'Job summary from the MultiCore sites for the last %s hours only.' % hours # Use <a href="%s/?%s">"stats"</a> page to see all %s hours' % ( 24 * 3, utils.monURL, 'mode=sitestats', hours ) else: title = 'Job summary from the MultiCore sites for the last %s hours' % hours self.publishTitle(title) modes = ( 'Defined', 'Waiting', 'Active', 'Archived' ) rows = [] cores = cores if cores != None else 0 for mode in modes: q = pmt.getCloudSummary(jobtype,vo,hours,selectionFields='computingSite,processingType,workingGroup, prodUserName,specialHandling,coreCount', tablename='ATLAS_PANDA.jobs%s4' % mode) if len(rows) == 0: header = q['header'] rows += q['rows'] ### Build the jobsumd dictionary jobsumd = {} proctyped = {} workgroupd = {} userd = {} spechandled = {} for c in self.clouds: jobsumd[c] = {} jobsumd[c]['ALL'] = [0]*(self.lstates+1) if c != 'ALL': jobsumd[c]['status'] = self.cloudList[c]['status'] iCloud = utils.name2Index(header,'cloud') print utils.lineInfo(), header iComputingSite = utils.name2Index(header,'computingSite') iStatus = utils.name2Index(header,'jobStatus') iProctype = utils.name2Index(header,'processingType') iSpechandle = utils.name2Index(header,'specialHandling') iWorkgroup = utils.name2Index(header,'workingGroup') iUser = utils.name2Index(header,'prodUserName') iCore = utils.name2Index(header,'coreCount') iCount = utils.name2Index(header,'COUNT') for r in rows: ncores = r[iCore] if r[iCore] != None else 0 if cores != 0 and ncores < cores: continue site = r[iComputingSite] if site == None: # print "Db record doesn't define any site: %s " % r if region: continue site="Unknown" # continue cloud = r[iCloud] # utils.getCloud4Site(r) status = r[iStatus] istatus = utils.name2Index(self.jobstates,status) proctype = r[iProctype] spechandle = r[iSpechandle] workgroup = r[iWorkgroup] user = r[iUser] count = r[iCount] if not cloud in jobsumd: print 'Unknown cloud: %s for site %s ' % ( cloud, site) continue cloud = 'ALL' if not status in self.jobstates: print 'Unknown jobstate:', status continue if not site in jobsumd[cloud]: jobsumd[cloud][site] = {} jobsumd[cloud][site] = [0]*(self.lstates+1) jobsumd[cloud][site][self.lstates] = ncores if ncores != None else 0 jobsumd[cloud][site][istatus] += count if cloud != 'ALL': jobsumd[cloud]['ALL'][istatus] += count jobsumd['ALL']['ALL'][istatus] += count proctyped[proctype] = proctyped.get(proctype,0) + count workgroupd[workgroup] = workgroupd.get(workgroup,0) + count userd[user] = userd.get(user,0) + count if spechandle != None: spechandled[spechandle] = spechandled.get(spechandle,0) + count ## Get cloud/site status main = {} main['states'] = self.jobstates main['jobsumd'] = jobsumd main['params'] = { 'jobtype': jobtype,'hours': hours,'vo':vo ,'computingSite': computingSite ,'processingType': processingType ,'workingGroup':workingGroup ,'prodUserName':prodUserName ,'specialHandling':specialHandling ,'cores' : cores ,'region' : region} self.publish(main) self.publishNav(' type=%s hours=%s' % (jobtype, hours ) ) self.publish( "%s/%s" % ( self.server().fileScriptURL(),"monitor/%s.js" % "mcore" ),role="script")
def doJson(self, hours=None, days=180, tstart=None, tend=None, PRODUSERNAME=None, top='nJobsA', topsize=0): """ Get the list of the users <ul> <li> hours = use the last hours <li> days = use the last days <li> topsize - the size of the top list <br> = 0 - all users are shown <li> top - select top list using 'top' column <ul> <li> 'nJobsA' - the number of the jobs <li> 'CPUA1' - Personal the CPU used for the last 24 hours <li> 'CPUA7' - Personal Cpu used for the last 7 days <li> 'CPUP1' - Group Cpu for the last 24 hours <li> 'CPUP7' - Group Cpu for the last 7 days </ul> </ul> """ if days == None: days = 0 if hours == None: hours = 0 main = { "buffer": { "params": { 'hours': days * 24 + hours }, "method": 'getUsers', "type": False } } columns = "name,njobsa,latestjob,cpua1,cpua7,cpup1,cpup7" if topsize == 0 or topsize == None: columns += ",scriptcache" q = pmt.getUsers(PRODUSERNAME, days * 24 + hours, columns=columns) header = q['header'] users = q['rows'] if PRODUSERNAME == None: if topsize > 0: title = "Recent %(topsize)d Top Panda Analysis Users" % { 'topsize': topsize } else: title = "Recent Panda Analysis Users" else: title = "PanDA jobs for %s" % PRODUSERNAME main["buffer"]["params"]['user'] = PRODUSERNAME, iNJobs = utils.name2Index(header, "njobsa") iLatest = utils.name2Index(header, "latestjob") jobpertime = {"anajobs": 0, "n1000": 0, "n10k": 0} recent = {"d3": 0, "d7": 0, "d30": 0, "d90": 0, "d180": 0} for u in users: nxtp = u[iNJobs] if nxtp == None: continue nxtp = int(nxtp) if nxtp > 0: jobpertime["anajobs"] += nxtp if nxtp > 1000: jobpertime["n1000"] += 1 if nxtp > 10000: jobpertime["n10k"] += 1 nxtp = u[iLatest] if nxtp != None: diffdays = (datetime.utcnow() - nxtp).days if diffdays < 4: recent["d3"] += 1 if diffdays < 8: recent["d7"] += 1 if diffdays < 31: recent["d30"] += 1 if diffdays < 91: recent["d90"] += 1 if diffdays < 181: recent["d180"] += 1 if topsize > 0 and top != None: iTop = utils.name2Index(header, top) users = self.makeTop(users, iTop)[:topsize] main["buffer"]["top"] = {'top': top, 'size': topsize} # remove thr group main["buffer"]["data"] = {'header': header, 'rows': users} main["buffer"]["totaljobs"] = jobpertime main["buffer"]["recent"] = recent self.publishTitle(title) self.publish(main) self.publish("%s/%s" % (utils.fileScriptURL(), "taskBuffer/%s.js" % "getUsers"), role="script") return
def doQuery(self,jobtype='production',hours=12,region=None): """ <ul> <li>jobtype - production,analysis, test <li>hours - production,analysis, test <li>VO - virtual organization atlas,cms <li>computingSite <li>processingType <li>workingGroup <li>prodUserName <li>specialHandling </ul> """ if int(hours) > 24 * 3: hours = 24*3 title = 'Job summary for the last %s hours only.' % hours # Use <a href="%s/?%s">"stats"</a> page to see all %s hours' % ( 24 * 3, utils.monURL, 'mode=sitestats', hours ) else: title = 'Job summary for the past %s hours' % hours pars = self.extraValuesFilled() self.publishTitle(title) nav = ' <b>type</b>=%s <b>hours</b>=%s' % (jobtype, hours ) if pars != None: for tp in ['computingSite','processingType','workingGroup', 'prodUserName', 'specialHandling']: if pars.get(tp) !=None: nav += ' <b>%s</b>=%s' % (tp,pars[tp]) modes = ( 'Defined', 'Waiting', 'Active', 'Archived' ) rows = [] for mode in modes: q = pmt.getCloudSummary(jobtype,pars.get('VO') if pars!=None else None,hours,extraConditions=pars,selectionFields='computingSite,processingType,workingGroup, prodUserName,specialHandling,modificationTime', tablename='ATLAS_PANDA.jobs%s4' % mode) if len(rows) ==0: header = q['header'] rows += q['rows'] # get getCurrentSiteData pilotd = pmt.getCurrentSiteData() ### Build the jobsumd dictionary jobsumd = {} proctyped = {} workgroupd = {} userd = {} spechandled = {} item = self.clouds if region != None: item = [self._ALL] + self._sites4region.keys() for c in item: jobsumd[c] = {} jobsumd[c][self._ALL] = [0]*self.lstates if c != self._ALL : jobsumd[c]['status'] = self.cloudList.get(c,{'status':'unknown'})['status'] iCloud = utils.name2Index(header,'cloud') iComputingSite = utils.name2Index(header,'computingSite') iStatus = utils.name2Index(header,'jobStatus') iProctype = utils.name2Index(header,'processingType') iSpechandle = utils.name2Index(header,'specialHandling') iWorkgroup = utils.name2Index(header,'workingGroup') iUser = utils.name2Index(header,'prodUserName') iCount = utils.name2Index(header,'COUNT') iTime = utils.name2Index(header,'modificationTime') iLatest = self._iLatest def updateTime(oldt,newt): ol = oldt[iLatest] if (ol != 0 and ol<newt) or ol==0: oldt[iLatest] = newt for r in rows: site = r[iComputingSite] if site == None: # print "Db record doesn't define any site: %s " % r regn = "unassigned" site="unassigned" if region!= None: continue # continue else: regn = self._region4sites.get(site,'unknown') if region!= None and regn == 'unknown': continue cloud = r[iCloud] # utils.getCloud4Site(r) status = r[iStatus] if status == 'cancelled' and site == 'Unknown': status = 'unassigned' istatus = utils.name2Index(self.jobstates,status) proctype = r[iProctype] spechandle = r[iSpechandle] workgroup = r[iWorkgroup] user = r[iUser] count = r[iCount] time = r[iTime] if region!=None: cloud = regn if not cloud in jobsumd: print 'Unknown cloud: %s for site %s ' % ( cloud, site) continue if not status in self.jobstates: print 'Unknown jobstate:', status continue if not site in jobsumd[cloud]: jobsumd[cloud][site] = {} jobsumd[cloud][site] = [0]*self.lstates jobsumd[cloud][site][istatus] += count jobsumd[cloud][self._ALL][istatus] += count jobsumd[self._ALL][self._ALL][istatus] += count updateTime(jobsumd[cloud][site], time) updateTime(jobsumd[cloud][self._ALL], time) updateTime(jobsumd[self._ALL][self._ALL], time) proctyped[proctype] = proctyped.get(proctype,0) + count workgroupd[workgroup] = workgroupd.get(workgroup,0) + count userd[user] = userd.get(user,0) + count if spechandle != None: spechandled[spechandle] = spechandled.get(spechandle,0) + count iFailed = self._iFailed iFinished = self._iFinished iRation = self._iRation iPilots = self._iPilots for cloud in jobsumd: for site in jobsumd[cloud]: if site == 'status': continue allcloud = jobsumd[cloud][site] ntot = allcloud[iFailed] + allcloud[iFinished] psite = pilotd.get(site) if psite: nplt = pilotd[site]['updateJob']+ pilotd[site]['getJob'] jobsumd[cloud][site][iPilots] = nplt jobsumd[cloud][self._ALL][iPilots] += nplt jobsumd[self._ALL][self._ALL][iPilots] += nplt if ntot >0: jobsumd[cloud][site][iRation] = 100.0*allcloud[iFailed]/ntot ## Get cloud/site status main = {} main['states'] = self.jobstates main['jobsumd'] = jobsumd if pars == None: pars = {} if (hours!=None): pars['hours'] = hours if (jobtype!=None): pars['jobtype'] = jobtype if (region!=None): pars['region'] = region nav += ' <b>region view</a>' main['params'] = pars self.publish(main) self.publishNav(nav) self.publish( "%s/%s" % ( self.server().fileScriptURL(),"monitor/%s.js" % "cloudsummary" ),role=pmRoles.script() )
def doJson(self, table=None, column=None, db='pmt', doc=None): """ Describe the selected Panda table / column <br> <code>table = the Db table name regexp comma-separated patterns to check</code><br> <code>column = the Db table column name regexp comma-separated patterns to find</code><br> <code>doc = '*|all' - document all columns selected if available<br> = 'comma-separated list of the regexp' is to display the columns with the comments matched the regexp provided </code><br> """ title = 'Describe the Panda Db ' inp = False if table != None and table != 'None': title += "'%s*'" % table inp = True title += " table" else: title += " tables" if column != None and column != 'None': title += " with '%s*' column " % column inp = True main = {} if inp: self.publishTitle(title) timer = Stopwatch.Stopwatch() main["buffer"] = {} main["buffer"]["db"] = db dbAccess = self._db.get(db) if dbAccess != None: main["buffer"]["method"] = "describe" main["buffer"]["params"] = (table, column, doc) main["buffer"]["type"] = False if not utils.isFilled(doc): tdes = dbAccess.describe(table, column) iclmn = utils.name2Index(tdes['header'], 'COLUMN_NAME') rows = tdes['rows'] for h in rows: h[iclmn] = nmap.get(h[iclmn]) main["buffer"]["data"] = tdes else: docrows = [] if utils.isFilled(table): tdoc = dbAccess.pandatabs( table, comments=doc, select= "table_name,'Table Description' as COLUMN_NAME,comments" ) iclmn = utils.name2Index(tdoc['header'], 'COLUMN_NAME') docrows = tdoc['rows'] for h in docrows: h[iclmn] = nmap.get(h[iclmn]) tcol = dbAccess.pandacols( column, table, select='TABLE_NAME,COLUMN_NAME,COMMENTS', comments=doc) iclmn = utils.name2Index(tcol['header'], 'COLUMN_NAME') for h in tcol['rows']: h[iclmn] = nmap.get(h[iclmn]) tcol['rows'] += docrows main["buffer"]["data"] = tcol self.publish({ 's-maxage': 60000, 'max-age': 6000 }, role=pmRoles.cache()) else: self.publishTitle( "Error: 'describe' - unknown Db name '%s' has been provided" % db) self.publish({ 's-maxage': 0, 'max-age': 0 }, role=pmRoles.cache()) else: self.publishTitle( "Error: 'describe' - no parameter has been provided. Define one at least. It should be either 'column' or 'table'" ) self.publish({'s-maxage': 0, 'max-age': 0}, role=pmRoles.cache()) self.publish(main) self.publish( "%s/%s" % (self.server().fileScriptURL(), "taskBuffer/%s.js" % "describe"), role=pmRoles.script())
def doJson(self,table=None,column=None,db='pmt',doc=None): """ Describe the selected Panda table / column <br> <code>table = the Db table name regexp comma-separated patterns to check</code><br> <code>column = the Db table column name regexp comma-separated patterns to find</code><br> <code>doc = '*|all' - document all columns selected if available<br> = 'comma-separated list of the regexp' is to display the columns with the comments matched the regexp provided </code><br> """ title = 'Describe the Panda Db ' inp = False if table != None and table != 'None': title += "'%s*'" % table inp = True title +=" table" else: title +=" tables" if column != None and column !='None': title += " with '%s*' column " % column inp = True main = {} if inp: self.publishTitle(title) timer = Stopwatch.Stopwatch() main["buffer"] = {} main["buffer"]["db"] = db dbAccess = self._db.get(db) if dbAccess != None: main["buffer"]["method"] = "describe" main["buffer"]["params"] = (table,column,doc) main["buffer"]["type"] = False if not utils.isFilled(doc): tdes = dbAccess.describe(table,column) iclmn = utils.name2Index(tdes['header'],'COLUMN_NAME') rows = tdes['rows'] for h in rows: h[iclmn] = nmap.get(h[iclmn]) main["buffer"]["data"] = tdes else: docrows = [] if utils.isFilled(table): tdoc = dbAccess.pandatabs(table,comments=doc,select="table_name,'Table Description' as COLUMN_NAME,comments") iclmn = utils.name2Index(tdoc['header'],'COLUMN_NAME') docrows = tdoc['rows'] for h in docrows: h[iclmn] = nmap.get(h[iclmn]) tcol = dbAccess.pandacols(column,table,select='TABLE_NAME,COLUMN_NAME,COMMENTS', comments=doc) iclmn = utils.name2Index(tcol['header'],'COLUMN_NAME') for h in tcol['rows']: h[iclmn] = nmap.get(h[iclmn]) tcol['rows'] += docrows main["buffer"]["data"] = tcol self.publish( {'s-maxage':60000,'max-age': 6000}, role=pmRoles.cache()) else: self.publishTitle("Error: 'describe' - unknown Db name '%s' has been provided" % db) self.publish( {'s-maxage':0,'max-age': 0}, role=pmRoles.cache()) else: self.publishTitle("Error: 'describe' - no parameter has been provided. Define one at least. It should be either 'column' or 'table'") self.publish( {'s-maxage':0,'max-age': 0}, role=pmRoles.cache()) self.publish(main) self.publish( "%s/%s" % (self.server().fileScriptURL(),"taskBuffer/%s.js" % "describe"),role=pmRoles.script() )
def doJson( self, hours=None, days=180, tstart=None, tend=None, PRODUSERNAME=None, top="CPUA7", topsize=0, name=None ): """ Get the list of the users <ul> <li> hours = use the last hours <li> days = use the last days <li> PRODUSERNAME or name - the comma separated pattern to select the list of the users. <li> topsize - the size of the top list <br> = 0 - all users are shown <li> top - the comma separated list to select top users using 'top' columns. <ul> <li> 'nJobsA' - the number of the jobs <li> 'CPUA1' - Personal the CPU used for the last 24 hours <li> 'CPUA7' - Personal Cpu used for the last 7 days <li> 'CPUP1'- Group the CPU used for the last 24 hours <li> 'CPUP7'- Group Cpu used for the last 7 days </ul> The order of the column names defines the default sorting. <br>For example: top='cpua7,nJobsA' creates the table sorted by "7 days " cpu and by "number of the jobs" <br> the parameter is essential for CLI (aka 'curl'/'ajax') clients. The Web Browser user can override the default by clicking onto the column header </ul> """ if days == None: days = 0 if hours == None: hours = 0 main = {"buffer": {"params": {"hours": days * 24 + hours}, "method": "getUsers", "type": False}} columns = "name,njobsa,cpua1,cpua7,latestjob" if topsize == 0 or topsize == None: columns = "name,njobsa,latestjob,cpua1,cpua7,cpup1,cpup7,scriptcache" elif "pup" in top.lower(): columns = "name,njobsa,cpup1,cpup7,latestjob,scriptcache" if PRODUSERNAME == None: PRODUSERNAME = name q = pmt.getUsers(PRODUSERNAME, days * 24 + hours, columns=columns) header = q["header"] users = q["rows"] if PRODUSERNAME == None: if topsize > 0: title = "Recent %(topsize)d Top Panda Analysis Users" % {"topsize": topsize} else: title = "Recent Panda Analysis Users" else: title = "PanDA jobs for %s" % PRODUSERNAME main["buffer"]["params"]["user"] = (PRODUSERNAME,) iNJobs = utils.name2Index(header, "njobsa") iLatest = utils.name2Index(header, "latestjob") iCpua1 = utils.name2Index(header, "cpua1") iCpua7 = utils.name2Index(header, "cpua7") iCpup1 = utils.name2Index(header, "cpup1") iCpup7 = utils.name2Index(header, "cpup7") jobpertime = {"anajobs": 0, "n1000": 0, "n10k": 0} recent = {"d3": 0, "d7": 0, "d30": 0, "d90": 0, "d180": 0} for u in users: nxtp = u[iNJobs] if nxtp == None: continue nxtp = int(nxtp) if nxtp > 0: jobpertime["anajobs"] += nxtp if nxtp > 1000: jobpertime["n1000"] += 1 if nxtp > 10000: jobpertime["n10k"] += 1 nxtp = u[iLatest] if nxtp != None: diffdays = (datetime.utcnow() - nxtp).days if diffdays < 4: recent["d3"] += 1 if diffdays < 8: recent["d7"] += 1 if diffdays < 31: recent["d30"] += 1 if diffdays < 91: recent["d90"] += 1 if diffdays < 181: recent["d180"] += 1 if topsize > 0 and diffdays > 7: # exclude the old users from the count if iCpua1 >= 0: u[iCpua1] = 0 if iCpua7 >= 0: u[iCpua7] = 0 if iCpup1 >= 0: u[iCpup1] = 0 if iCpup1 >= 0: u[iCpup7] = 0 if topsize > 0 and top != None: vtop = top.split(",") iTop = tuple(utils.name2Index(header, t) for t in vtop) users = self.makeTop(users, iTop)[:topsize] main["buffer"]["top"] = {"top": top, "size": topsize} njobsa = 0 cpua1 = 0 cpua7 = 0 cpup1 = 0 cpup7 = 0 finalusers = [] for u in users: nxtp = u[iNJobs] if nxtp == None: continue njobsa += nxtp cpu = 0 if iCpua1 >= 0: cpua1 += u[iCpua1] cpu += u[iCpua1] if iCpua7 >= 0: cpua7 += u[iCpua7] cpu += u[iCpua7] if iCpup1 >= 0: cpup1 += u[iCpup1] cpu += u[iCpup1] if iCpup7 >= 0: cpup7 += u[iCpup7] cpu += u[iCpup7] if cpu > 0: njobsa += nxtp finalusers.append(u) users = finalusers main["buffer"]["data"] = {"header": header, "rows": users} main["buffer"]["totaljobs"] = jobpertime if topsize > 0: if iCpua1 >= 0 or iCpua7 >= 0: main["buffer"]["totaltop"] = {"njobsa": njobsa, "cpua1": cpua1, "cpua7": cpua7} else: main["buffer"]["totaltop"] = {"njobsa": njobsa, "cpup1": cpup1, "cpup7": cpup7} main["buffer"]["recent"] = recent self.publishTitle(title) self.publish(main) self.publish("%s/%s" % (self.server().fileScriptURL(), "taskBuffer/%s.js" % "getUsers"), role="script") return
def doJobs(self, pandaid=None, params=None, jobparam=None, table=None, hours=None, tstart=None, tend=None, field='modificationTime', days=None, format=None, jobtype=None, testsite=None, limit=1500, summary=None, minjob=1, dump=None, region=None, lfn=None, showcpu=None): ## Perform the query main = {} errorcolcheck = False selection = '*' vals = self.extraValuesFilled(self._alias) title = 'PanDA Job(s)' if utils.isFilled(pandaid): hours = None days = None title += " %s " % pandaid if days != None: title += ' for %.2f Day' % float(days) if days > 1: title += "s" if hours != None: if days == None: title += " for " title += ' %d Hour' % int(hours) if hours > 1: title += "s" if vals != None: for k in vals.keys(): if vals[k] == 'undefined': vals[k] = None elif vals[k] != None and k.lower() == 'jobstatus' and ( vals[k].lower().find('prerun') >= 0 or vals[k].lower().find('finishing') >= 0 or vals[k].lower().find('unassigned') >= 0 or vals[k].lower().find('retried') >= 0): stvals = utils.parseArray(vals[k]) statvals = [] for v in stvals: if v.lower() == 'prerun': statvals += [ 'defined', 'assigned', 'waiting', 'activated', 'pending', 'sent', 'starting' ] elif v.lower() == 'finishing': statvals += ['holding', 'transferring'] elif v.lower() == 'unassigned': vals['computingSite'] = 'NULL' statvals += ['cancelled'] elif v.lower() == 'retried': # See the slide 3 from Tadashi: https://indico.cern.ch/getFile.py/access?contribId=13&sessionId=11&resId=0&materialId=slides&confId=119171 vals['taskBufferErrorCode'] = [106, 107] statvals += ['failed'] else: statvals += [v] vals[k] = ','.join(statvals) cleanVal = dict( (k, v) for k, v in vals.iteritems() if v is not None) vals = cleanVal if vals == None: vals = {} nav = '' certificate = None certusr = None try: cert = self.server().certificate() if cert != None: certusr = pmt.cleanUserID(cert) main['ceruser'] = certusr except: pass if vals.get('prodUserName') == 'auto' and certusr != None: if cert != None: vals['prodUserName'] = certusr for v in vals: nav += "<b>%s</b>=%s " % (v, vals[v]) # nav += "<span id=linkjobid stule='display:inline'></span>" # nav +="<script>$(document).ready(function(){$('#linkjobid').html(utils().linkJobs(s.cloud,jobtype" # nav += jobtype if jobtype!=None else "undefined" # nav += ", s.jobStatus, " # nav += "%d" % hours if hours!=None else "undefined" # nav += ", s.computingSite,'Classic Page' ))});</script>"; if not utils.isFilled(summary): nav += "<b>%s</b>=%s " % ('limit', limit) self.publishNav(nav) if len(vals) == 0: vals = None if vals == None and jobparam == None: main['Description'] = self.description() else: if lfn != None and lfn != "undefined": lfnselect = 'pandaid,lfn' lfnjobs = pmt.getJobLFN(select=lfnselect, table='new', lfn=lfn, pandaid=pandaid, type='*', limit=limit) if lfnjobs['rows'] > 0: pandaid = [ljobs[0] for ljobs in lfnjobs['rows']] selection = {} if vals != None: selection.update(vals) if pandaid != None: selection.update({nmap.get('pandaid'): pandaid}) if region != None: selection.update({'region': region}) main['Selection'] = selection conditions = vals if conditions == None: conditions = {} cs = conditions.get('computingSite') if cs == None: site4region = self.getSite4Region(region) if site4region != None and len(site4region) > 0: conditions['computingSite'] = site4region else: pass # ignore the region parameter if utils.isValid(summary): jobtype = 'production' if jobtype == None and jobparam.lower( ).find('taskid') >= 0 and jobparam.lower().find( 'jeditaskid') < 0 else jobtype jobs = pmt.getJobsAtt(pandaid, jobparam, conditions, None, hours, tstart, tend, field, days, format, jobtype, testsite, None, True) rows = jobs['rows'] indx = [] if len(rows) > 30: for i, r in enumerate(rows): try: if r[1] > minjob: indx.append(i) continue except: pass cleanrows = [rows[i] for i in indx] jobs['rows'] = cleanrows istatus = utils.name2Index(jobs['header'], 'jobstatus') if istatus != None: statOrder = utils.name2Index(utils.jobStates) def byStatus(a, b): return statOrder[a[istatus]] - statOrder[b[istatus]] jobs['rows'] = sorted(jobs['rows'], cmp=byStatus) else: if jobparam == self._allparams and conditions.get( self._jobParametersName) == None: conditions[self._jobParametersName] = 'any' jobs = pmt.getJobsAtt(pandaid, 'PandaID,' + jobparam, conditions, None, hours, tstart, tend, field, days, format, jobtype, testsite, limit) errorcolcheck = True if len(jobs) > 0: header = [nmap.get(h) for h in jobs['header']] info = jobs['rows'] main['header'] = header # + self._extraFields timecols = [] errdict = None errorcol = not errorcolcheck for i, h in enumerate(header): if 'time' in h.lower( ) and 'cpuconsumptiontime' != h.lower(): timecols.append(i) if not errorcol and 'error' in h.lower(): errorcol = True ## # add an artificial retryID ## header += ['retryID'] headindx = utils.name2Index(header) creationtDict = {} histograms = {} prodSourceLabel = headindx.get('prodSourceLabel') jobStatus = headindx.get('jobStatus') status4title = conditions.get('jobStatus') if not utils.isFilled(status4title): if len(info) == 1 and jobStatus != None: status4title = info[0][jobStatus] if utils.isFilled(status4title): title = status4title[0].upper( ) + status4title[1:] + " " + title prodtype = 'production' in jobtype.lower( ) if jobtype != None else True taskidsum = prodtype if not utils.isValid(summary) and dump != 'yes': jsets = setutils.factory(header, info, self._errorCodes, self._siteId, self._siteNicks) main['jobset'] = jsets.jobsets() for r in info: if not taskidsum and ( (prodSourceLabel and r[prodSourceLabel] == 'managed') and prodtype): taskidsum = True if errorcol and errorcolcheck: errdict = self.getErrors(r, headindx, errdict) for t in timecols: r[t] = utils.epochTime(r[t]) ## r += [None] # retryID # row = self.jobsetTime(utils.zip(header(info[r])),creationtDict,histograms) # info[r] = self.addFields(utils.zip(header(info[r])),creationtDict,histograms) # Action cleanUserID SSL_CLIENT_S_DN main['info'] = info if errorcolcheck: main['errorCodes'] = errdict main['colNames'] = sorted(header) main['jobsummary'] = copy.copy(self._jobSum) if taskidsum: main['jobsummary'] += [['Task ID', 'taskID']] # print utils.lineInfo(), "===============", self._description.get("JEDITASKID"), self._description.get("JediTaskID") # if self._description.get("JEDITASKID") or self._description.get("JediTaskID"): # main['jobsummary'] += [['Jedi ID','JediTaskID']] elif jobtype != 'jedi': main['jobsummary'] += [['Jobsets', 'jobsetID']] # need constrain elif jobtype == 'analysis': main['jobsummary'] += [[ 'Analysis Tasks', 'destinationDBlock' ]] if showcpu == 'yes': main['jobsummary'] += [['CPU Type', 'cpuConsumptionUnit']] self.publishTitle(title) return main