|
|
|
@ -12,7 +12,7 @@ from sets import Set
|
|
|
|
|
import re
|
|
|
|
|
import datetime
|
|
|
|
|
import Queue
|
|
|
|
|
from threading import Thread
|
|
|
|
|
from threading import Thread, RLock
|
|
|
|
|
import time
|
|
|
|
|
class Analysis:
|
|
|
|
|
def __init__(self):
|
|
|
|
@ -23,6 +23,10 @@ class Analysis:
|
|
|
|
|
def init(self):
|
|
|
|
|
d = datetime.datetime.now()
|
|
|
|
|
self.now = {"month":d.month,"year":d.year, "day":d.day,"hour":d.hour,"minute":d.minute}
|
|
|
|
|
def getNow(self):
|
|
|
|
|
d = datetime.datetime.now()
|
|
|
|
|
return {"month":d.month,"year":d.year, "day":d.day,"hour":d.hour,"minute":d.minute}
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
This class is designed to analyze environment variables. Environment variables can either be folders, files or simple values
|
|
|
|
|
The class returns a quantifiable assessment of the environment variables (expected 100%)
|
|
|
|
@ -31,7 +35,7 @@ class Env(Analysis):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
Analysis.__init__(self)
|
|
|
|
|
def init(self,values):
|
|
|
|
|
Analysis.init(self)
|
|
|
|
|
#Analysis.init(self)
|
|
|
|
|
self.values = values
|
|
|
|
|
"""
|
|
|
|
|
This function evaluate the validity of an environment variable by returning a 1 or 0 (computable)
|
|
|
|
@ -57,19 +61,19 @@ class Env(Analysis):
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
def composite (self):
|
|
|
|
|
Analysis.init(self)
|
|
|
|
|
#Analysis.init(self)
|
|
|
|
|
r = [ self.evaluate(id) for id in self.values] ;
|
|
|
|
|
N = len(r)
|
|
|
|
|
n = sum(r)
|
|
|
|
|
value = n/N
|
|
|
|
|
missing = [self.values[i] for i in range(0,N) if r[i] == 0]
|
|
|
|
|
return {"value":value,"missing":missing}
|
|
|
|
|
return dict(self.getNow(),**{"value":value,"missing":missing})
|
|
|
|
|
|
|
|
|
|
class Sandbox(Analysis):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
Analysis.__init__(self)
|
|
|
|
|
def init(self,conf):
|
|
|
|
|
Analysis.init(self)
|
|
|
|
|
#Analysis.init(self)
|
|
|
|
|
self.sandbox_path = conf['sandbox']
|
|
|
|
|
self.requirements_path = conf['requirements']
|
|
|
|
|
def get_requirements (self):
|
|
|
|
@ -99,7 +103,7 @@ class Sandbox(Analysis):
|
|
|
|
|
value = 1 - (n/N)
|
|
|
|
|
missing = list(Set(required_modules) - Set(sandbox_modules))
|
|
|
|
|
|
|
|
|
|
return dict(self.now,**{"value":value,"missing":missing})
|
|
|
|
|
return dict(self.getNow(),**{"value":value,"missing":missing})
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
This class performs the analysis of a list of processes and determines
|
|
|
|
@ -109,7 +113,7 @@ class ProcessCounter(Analysis):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
Analysis.__init__(self)
|
|
|
|
|
def init(self,names):
|
|
|
|
|
Analysis.init(self)
|
|
|
|
|
#Analysis.init(self)
|
|
|
|
|
self.names = names
|
|
|
|
|
def evaluate(self,name):
|
|
|
|
|
cmd = "".join(['ps -eo comm |grep ',name,' |wc -l'])
|
|
|
|
@ -117,7 +121,7 @@ class ProcessCounter(Analysis):
|
|
|
|
|
|
|
|
|
|
return int(handler.communicate()[0].replace("\n","") )
|
|
|
|
|
def composite(self):
|
|
|
|
|
Analysis.init(self)
|
|
|
|
|
#Analysis.init(self)
|
|
|
|
|
r = {}
|
|
|
|
|
for name in self.names :
|
|
|
|
|
r[name] = self.evaluate(name)
|
|
|
|
@ -125,7 +129,7 @@ class ProcessCounter(Analysis):
|
|
|
|
|
#N = len(r)
|
|
|
|
|
#n = sum(r)
|
|
|
|
|
#return n/N
|
|
|
|
|
return dict(self.now,**r)
|
|
|
|
|
return dict(self.getNow(),**r)
|
|
|
|
|
"""
|
|
|
|
|
This class returns an application's both memory and cpu usage
|
|
|
|
|
"""
|
|
|
|
@ -133,8 +137,9 @@ class DetailProcess(Analysis):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
Analysis.__init__(self)
|
|
|
|
|
def init (self,names):
|
|
|
|
|
Analysis.init(self)
|
|
|
|
|
#Analysis.init(self)
|
|
|
|
|
self.names = names;
|
|
|
|
|
|
|
|
|
|
def split(self,name,stream):
|
|
|
|
|
pattern = " (\d+.{0,1}\d*)\x20*(\d+.{0,1}\d*)\x20*(\d+.{0,1}\d*)\x20".replace(":name",name)
|
|
|
|
|
g = re.match(pattern,stream)
|
|
|
|
@ -148,8 +153,7 @@ class DetailProcess(Analysis):
|
|
|
|
|
ostream = handler.communicate()[0].split('\n')
|
|
|
|
|
|
|
|
|
|
ostream = [ self.split(name,row) for row in ostream if row != '']
|
|
|
|
|
|
|
|
|
|
if len(ostream) == 0:
|
|
|
|
|
if len(ostream) == 0 or len(ostream[0]) < 4 :
|
|
|
|
|
ostream = [['0','0','0',name]]
|
|
|
|
|
r = []
|
|
|
|
|
for row in ostream :
|
|
|
|
@ -158,6 +162,7 @@ class DetailProcess(Analysis):
|
|
|
|
|
# On OSX it has been observed that the fully qualified path is sometimes returned (go figure)
|
|
|
|
|
#
|
|
|
|
|
row = [float(value) for value in row if value.strip() != '' and name not in value ] +[re.sub('\$|^','',name)]
|
|
|
|
|
|
|
|
|
|
r.append(row)
|
|
|
|
|
return r
|
|
|
|
|
def status(self,row):
|
|
|
|
@ -171,24 +176,25 @@ class DetailProcess(Analysis):
|
|
|
|
|
else:
|
|
|
|
|
return "crash"
|
|
|
|
|
def format(self,row):
|
|
|
|
|
|
|
|
|
|
r= {"memory_usage":row[0],"cpu_usage":row[1],"memory_available":row[2]/1000,"label":row[3]}
|
|
|
|
|
status = self.status(r)
|
|
|
|
|
r['status'] = status
|
|
|
|
|
return dict(self.now,**r)
|
|
|
|
|
return r
|
|
|
|
|
#return dict(self.getNow(),**r)
|
|
|
|
|
def composite(self):
|
|
|
|
|
Analysis.init(self)
|
|
|
|
|
print ' **** ',self.now
|
|
|
|
|
#Analysis.init(self)
|
|
|
|
|
|
|
|
|
|
#value = self.evaluate(self.name)
|
|
|
|
|
#row= {"memory_usage":value[0],"cpu_usage":value[1]}
|
|
|
|
|
#return row
|
|
|
|
|
#ma = [self.evaluate(name) for name in self.names]
|
|
|
|
|
ma = []
|
|
|
|
|
now = self.getNow()
|
|
|
|
|
for name in self.names:
|
|
|
|
|
|
|
|
|
|
matrix = self.evaluate(name)
|
|
|
|
|
|
|
|
|
|
ma += [self.format(row) for row in matrix]
|
|
|
|
|
ma += [ dict(now, **self.format(row)) for row in matrix]
|
|
|
|
|
|
|
|
|
|
#return [{"memory_usage":row[0],"cpu_usage":row[1],"memory_available":row[2]/1000,"label":row[3]} for row in ma]
|
|
|
|
|
|
|
|
|
@ -203,22 +209,29 @@ class Monitor (Thread):
|
|
|
|
|
self.logs = []
|
|
|
|
|
self.handler = self.config['class']
|
|
|
|
|
self.mconfig = self.config['config']
|
|
|
|
|
self.lock = RLock()
|
|
|
|
|
def run(self):
|
|
|
|
|
r = {}
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
for label in self.mconfig:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.handler.init(self.mconfig[label])
|
|
|
|
|
r[label] = self.handler.composite()
|
|
|
|
|
self.logs.append(r)
|
|
|
|
|
|
|
|
|
|
self.queue.put(r)
|
|
|
|
|
#self.logs.append(r)
|
|
|
|
|
|
|
|
|
|
self.prune()
|
|
|
|
|
|
|
|
|
|
self.queue.task_done()
|
|
|
|
|
HALF_HOUR = 60*15
|
|
|
|
|
self.logs.append(self.queue.get(block=False))
|
|
|
|
|
HALF_HOUR = 60*1
|
|
|
|
|
time.sleep(HALF_HOUR)
|
|
|
|
|
|
|
|
|
|
def prune(self) :
|
|
|
|
|
MAX_ENTRIES = 1000
|
|
|
|
|
MAX_ENTRIES = 100
|
|
|
|
|
if len(self.logs) > MAX_ENTRIES :
|
|
|
|
|
BEG = len(self.logs) - MAX_SIZE -1
|
|
|
|
|
self.logs = self.logs[BEG:]
|
|
|
|
@ -236,11 +249,7 @@ class mapreducer:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if reducer is not None:
|
|
|
|
|
r = {}
|
|
|
|
|
for key in self.store:
|
|
|
|
|
beg = len(self.store[key]) - 101 if len(self.store[key]) > 100 else 0
|
|
|
|
|
end = beg + 100
|
|
|
|
|
r[key] = self.store[key][beg:end]
|
|
|
|
|
r = self.store
|
|
|
|
|
# r = [reducer(self.store[key]) for key in self.store]
|
|
|
|
|
else:
|
|
|
|
|
r = self.store
|
|
|
|
|