def prepareWeightList(cronList): cronID = 0 origWeights = [] maxShifts = [] minShifts = [] for cron in cronList: leftShift = cron.leftShift rightShift = cron.rightShift cronJobList = cron.cronJobList weight = cron.weight if len(cronJobList) == 0: continue maxShifts.append(rightShift) minShifts.append(leftShift) for cronJob in cronJobList: start = cronJob.startTime end = cronJob.endTime origWeights.append([start, end, weight, cronID]) cronID += 1 CCronLogger.debugToConsole("Total number of cron jobs: " + str(len(origWeights))) origWeights = sorted(origWeights, key=getKey) return [origWeights, minShifts, maxShifts]
def findStartEndTime(self): startTime=datetime.datetime.now().replace(year=9999) endTime=datetime.datetime.now().replace(year=1) for cron in self._cronList: if cron.startTime<startTime: startTime=cron.startTime if cron.endTime>endTime: endTime=cron.endTime self.startTime=startTime self.endTime=endTime self.totalDuration=endTime-startTime CCronLogger.debugToConsole("Start time of first job: "+str(startTime)) CCronLogger.debugToConsole("End time of last job: "+str(endTime)) CCronLogger.debugToConsole("Total duration: "+str(self.totalDuration))
from CronLogger import CCronLogger try: import dominate from dominate.tags import * except ImportError: CCronLogger.errorToConsole("You don't have required Python module.") CCronLogger.debugToConsole("Required modules are: dominate") class CCronReport: def __init__(self,options, newCrontab, statsBefore, statsAfter, shiftVector, cronList): self.setOptions(options) self.newCrontab=newCrontab self.statsBefore=statsBefore self.statsAfter=statsAfter self.shiftVector=shiftVector self.cronList=cronList def setOptions(self,options): try: self._outputDir=options["outputdir"] CCronLogger.debug("Output directory: "+self._outputDir) except KeyError: CCronLogger.info("Output directory directive not found. Setting to default: working directory.") self._outputDir="./" try: self._graphName=options["graphname"] CCronLogger.debug("Graph name: "+self._graphName) except KeyError: CCronLogger.info("Graph name directive not found. Setting to default: graph.pdf.")
def plotCronJobs(self): if len(self._cronList) == 0: CCronLogger.errorToConsole("No viable cron jobs to plot and analyze.") return False,None,None,None height_graph=2+ (len(self._cronList) / 2) #inicializace fig = plt.figure(figsize=(8,height_graph)) ax = fig.add_subplot(111) self._countTotalOverlaps() self._setLineWidth() firstTime=datetime.datetime.now().replace(year=9999) lastTime=datetime.datetime.now().replace(year=1) cronNameList=[] yLabels=[] cronCounter=0 cronID=1 counter=0 shown=False print("Plotting cron jobs.") for cron in self._cronList: if self._ignoreShort and cron.duration < timedelta(seconds=self._cronLenLimit): CCronLogger.debug("Cron job "+str(cron)+" is too short, it will be skipped.") continue #pokud je prikaz moc dlouhy, orizni ho if len(cron.command) > 30: cronNameList.append(cron.command[0:27]+" ...") else: cronNameList.append(cron.command) if cron.overlaps > 0: CCronLogger.info("Cron job "+str(cron)+" starts before previous run isn't finished. It should be manually optimized.") CCronLogger.infoToConsole("Cron job "+str(cron)+" starts before previous run isn't finished. It should be manually optimized.") yLabels.append(cronID + (cron.overlaps / 2) ) jobID=0 for job in cron.cronJobList: self._weights.append([job.startTime,job.endTime,cron.weight]) self._endPoints[job.startTime]=None self._endPoints[job.endTime]=None if job.startTime<firstTime: firstTime=job.startTime if job.endTime>lastTime: lastTime=job.endTime #cron joby se prekryvaji if cron.overlaps>0: #vykresli je nad sebe, cervene self._drawLine(cronID + (jobID % (cron.overlaps + 1) ),job.startTime,job.endTime,"r") #crony se neprekryvaji else: self._drawLine(cronID,job.startTime,job.endTime,"k") #prubeh progress=int(counter*100/self.cronJobsTotal) if not progress%5: if not shown: CCronLogger.debugToConsoleWithLineFeed("Progress: "+str(progress)+"%") shown=True else: shown=False counter+=1 jobID+=1 cronID+=(cron.overlaps+1) cronCounter+=1 #pokud to neni posledni vykreslovany cron, udelej vodorovnou caru if cronCounter!=len(self._cronList): plt.axhline(cronID - 0.5,color="black") CCronLogger.debugToConsole("Progress: 100%") if counter == 0: CCronLogger.error("No crons to plot.") CCronLogger.errorToConsole("No crons to plot.") return False,None,None,None #osaX = cas ax.xaxis_date() #format casu na ose length=lastTime-firstTime self.startTime=firstTime self.endTime=lastTime self.duration=length dateFormat = DateFormatter(self._timeFormat) #nastaveni osyX format casu ax.xaxis.set_major_formatter(dateFormat) #rezerva na oseX delta=(lastTime-firstTime)/100 #rozsah osy y plt.ylim(-0.5,cronID) #rozsah osyX (zacatecni,konecny cas) + nejaka rezerva plt.xlim(firstTime-delta, lastTime+delta) #popis osyX plt.xlabel('Time') #plt.ylabel("Cron jobs") fig.autofmt_xdate() centers, weights, maxWeight, minWeight, summedWeights,weightsForStatistics = self.makeWeightIntervals() std=self.createStatistics(maxWeight, weightsForStatistics) loadPeaks = self.findLoadPeaks(summedWeights) if len(loadPeaks) > 0: yLabels.insert(0, 0) cronNameList.insert(0, "Bottlenecks") plt.axhline(0.5,color="black",lw=2.5) loadPeaksLen=timedelta(seconds=0) totalWeight=0 for peak in loadPeaks: plt.hlines(0, peak[0], peak[1], "r", lw=self.lineWidth) startTime=peak[0].strftime("%d.%m.%Y %H:%M:%S") endTime=peak[1].strftime("%d.%m.%Y %H:%M:%S") totalWeight+= peak[2] loadPeaksLen+=(peak[1]-peak[0]) CCronLogger.info("Found bottleneck: "+startTime+" <---> "+endTime) CCronLogger.info("Total length of load peaks: "+str(loadPeaksLen)+" of total weight: "+str(totalWeight)) CCronLogger.infoToConsole("Total length of load peaks: "+str(loadPeaksLen)+" of total weight: "+str(totalWeight)) #popisky osyY: 1.arg list ID (unikatni cronjoby), 2.arg = list popisku (nazvy cronjobu) plt.yticks(yLabels, cronNameList) #autoupraveni odsazeni kolem grafu, aby se tam veslo vsechno plt.tight_layout() #export do pdf if self.plotBetter: CCronLogger.info("Saving plot with cron jobs to: "+self._outputDir+"improved_"+self._graphName) CCronLogger.infoToConsole("Saving plot with cron jobs to: "+self._outputDir+"improved_"+self._graphName) try: savefig(self._outputDir+"improved_"+self._graphName) except: CCronLogger.errorToConsole("Error while saving image.") CCronLogger.error("Error while saving image.") else: CCronLogger.info("Saving plot with cron jobs to: "+self._outputDir+self._graphName) CCronLogger.infoToConsole("Saving plot with cron jobs to: "+self._outputDir+self._graphName) try: savefig(self._outputDir+self._graphName) except: CCronLogger.errorToConsole("Error while saving image.") CCronLogger.error("Error while saving image.") #ukazani grafu v Tk if self._showImages: plt.show() self.plotWeightGraph(length, centers, weights, maxWeight) return True,std,maxWeight,minWeight
import datetime from datetime import timedelta from collections import OrderedDict from CronLogger import CCronLogger import random import statistics try: import matplotlib.pyplot as plt from matplotlib.dates import DateFormatter from matplotlib.pyplot import savefig import intervaltree from numpy import asarray except ImportError: CCronLogger.errorToConsole("You don't have required Python module.") CCronLogger.debugToConsole("Required modules are: matplotlib, intervaltree, numpy") class CCronPlotter: def __init__(self,cronList,options,plotBetter=False): self.plotBetter=plotBetter self.setOptions(options) self._endPoints=dict() self._weights=[] self._cronList=cronList self.oneMinute=timedelta(minutes=1) self.oneHour=timedelta(hours=1) self.oneDay=timedelta(days=1) self.oneWeek=timedelta(weeks=1) self.oneMonth=timedelta(weeks=4)
import random from datetime import timedelta import datetime from CronJob import CCronJob from CronLogger import CCronLogger import statistics import multiprocessing import os try: from deap import creator, base, tools import intervaltree except ImportError: CCronLogger.errorToConsole("You don't have required Python module.") CCronLogger.debugToConsole("Required modules are: deap, intervaltree") def init(cronList, options): global cnt cnt = 0 global intervalLen intervalLen, duration, numberOfGenerations, sizeOfPopulation, crossoverProb, mutationProb, parallel, mateOp, uniformProb, tournamentSize = setOptions( options) origWeights2, minShifts2, maxShifts2 = prepareWeightList(cronList) global origWeights origWeights = origWeights2