Merge branch 'Thinginitself-checkbox'

This commit is contained in:
zhongyehong 2016-07-02 17:16:30 +08:00
commit cf358de156
7 changed files with 125 additions and 10 deletions

View File

@ -1,6 +1,6 @@
#!/usr/bin/python3
import subprocess,re,os,etcdlib,psutil
import subprocess,re,os,etcdlib,psutil,math
import time,threading,json,traceback,platform
from log import logger
@ -11,12 +11,16 @@ monitor_vnodes = {}
workerinfo = {}
workercinfo = {}
lastbillingtime = {}
increment = {}
class Container_Collector(threading.Thread):
def __init__(self,test=False):
threading.Thread.__init__(self)
self.thread_stop = False
self.interval = 2
self.billingtime = 3600
self.test = test
self.cpu_last = {}
self.cpu_quota = {}
@ -46,6 +50,8 @@ class Container_Collector(threading.Thread):
def collect_containerinfo(self,container_name):
global workercinfo
global increment
global lastbillingtime
output = subprocess.check_output("sudo lxc-info -n %s" % (container_name),shell=True)
output = output.decode('utf-8')
parts = re.split('\n',output)
@ -54,6 +60,10 @@ class Container_Collector(threading.Thread):
basic_exist = 'basic_info' in workercinfo[container_name].keys()
if basic_exist:
basic_info = workercinfo[container_name]['basic_info']
else:
basic_info['RunningTime'] = 0
basic_info['LastTime'] = 0
basic_info['billing'] = 0
for part in parts:
if not part == '':
key_val = re.split(':',part)
@ -65,11 +75,8 @@ class Container_Collector(threading.Thread):
#if basic_exist:
# logger.info(workercinfo[container_name]['basic_info'])
if(info['State'] == 'STOPPED'):
if not 'RunningTime' in basic_info.keys():
basic_info['RunningTime'] = 0
basic_info['LastTime'] = 0
workercinfo[container_name]['basic_info'] = basic_info
logger.info(basic_info)
#logger.info(basic_info)
return False
running_time = self.get_proc_etime(int(info['PID']))
if basic_exist and 'PID' in workercinfo[container_name]['basic_info'].keys():
@ -83,7 +90,6 @@ class Container_Collector(threading.Thread):
basic_info['PID'] = info['PID']
basic_info['IP'] = info['IP']
basic_info['RunningTime'] = running_time
workercinfo[container_name]['basic_info'] = basic_info
cpu_parts = re.split(' +',info['CPU use'])
cpu_val = cpu_parts[0].strip()
@ -121,6 +127,11 @@ class Container_Collector(threading.Thread):
cpu_use['usedp'] = cpu_usedp
self.cpu_last[container_name] = cpu_val;
workercinfo[container_name]['cpu_use'] = cpu_use
if container_name not in increment.keys():
increment[container_name] = {}
increment[container_name]['lastcputime'] = 0
increment[container_name]['memincrement'] = 0
mem_parts = re.split(' +',info['Memory use'])
mem_val = mem_parts[0].strip()
@ -130,11 +141,40 @@ class Container_Collector(threading.Thread):
mem_use['unit'] = mem_unit
if(mem_unit == "MiB"):
mem_val = float(mem_val) * 1024
increment[container_name]['memincrement'] += float(mem_val)
elif (mem_unit == "GiB"):
mem_val = float(mem_val) * 1024 * 1024
increment[container_name]['memincrement'] += float(mem_val)*1024
mem_usedp = float(mem_val) / self.mem_quota[container_name]
mem_use['usedp'] = mem_usedp
workercinfo[container_name]['mem_use'] = mem_use
lasttime = 0
if container_name in lastbillingtime.keys():
lasttime = lastbillingtime[container_name]
else:
lasttime = 0
lastbillingtime[container_name] = 0
#logger.info(running_time)
if not int(running_time/self.billingtime) == lasttime:
#logger.info("billing:"+str(float(cpu_val)))
lastbillingtime[container_name] = int(running_time/self.billingtime)
cpu_increment = float(cpu_val) - float(increment[container_name]['lastcputime'])
#logger.info("billing:"+str(cpu_increment)+" "+str(increment[container_name]['lastcputime']))
if cpu_increment == 0.0:
avemem = 0
else:
avemem = cpu_increment*float(increment[container_name]['memincrement'])/1800.0
increment[container_name]['lastcputime'] = cpu_val
increment[container_name]['memincrement'] = 0
if 'disk_use' in workercinfo[container_name].keys():
disk_quota = workercinfo[container_name]['disk_use']['total']
else:
disk_quota = 0
#logger.info("cpu_increment:"+str(cpu_increment)+" avemem:"+str(avemem)+" disk:"+str(disk_quota)+"\n")
billing = cpu_increment/1000.0 + avemem/500000.0 + float(disk_quota)/1024.0/1024.0/2000
basic_info['billing'] += math.ceil(billing)
workercinfo[container_name]['basic_info'] = basic_info
#print(output)
#print(parts)
return True

View File

@ -1,9 +1,14 @@
import json
from log import logger
from model import db, Notification, NotificationGroups
from model import db, Notification, NotificationGroups, User
from userManager import administration_required, token_required
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from datetime import datetime
import env
class NotificationMgr:
def __init__(self):
@ -26,6 +31,54 @@ class NotificationMgr:
notify_ids = sorted(list(set(notify_ids)), reverse=True)
return [Notification.query.filter_by(id=notify_id).first() for notify_id in notify_ids]
def mail_notification(self, notify_id):
email_from_address = env.getenv('EMAIL_FROM_ADDRESS')
if (email_from_address in ['\'\'', '\"\"', '']):
return {'success' : 'true'}
notify = Notification.query.filter_by(id=notify_id).first()
notify_groups = NotificationGroups.query.filter_by(notification_id=notify_id).all()
to_addr = []
groups = []
for group in notify_groups:
groups.append(group.group_name)
if 'all' in groups:
users = User.query.all()
for user in users:
to_addr.append(user.e_mail)
else:
for group in notify_groups:
users = User.query.filter_by(user_group=group.group_name).all()
for user in users:
to_addr.append(user.e_mail)
content = notify.content
text = '<html><h4>Dear '+ 'user' + ':</h4>' #user.username + ':</h4>'
text += '''<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Your account in <a href='%s'>%s</a> has been recieved a notification:</p>
<p>%s</p>
<br>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Note: DO NOT reply to this email!</p>
<br><br>
<p> <a href='http://docklet.unias.org'>Docklet Team</a>, SEI, PKU</p>
''' % (env.getenv("PORTAL_URL"), env.getenv("PORTAL_URL"), content)
text += '<p>'+ str(datetime.utcnow()) + '</p>'
text += '</html>'
subject = 'Docklet Notification: ' + notify.title
msg = MIMEMultipart()
textmsg = MIMEText(text,'html','utf-8')
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = email_from_address
msg.attach(textmsg)
s = smtplib.SMTP()
s.connect()
for address in to_addr:
try:
msg['To'] = address
s.sendmail(email_from_address, address, msg.as_string())
except Exception as e:
logger.error(e)
s.close()
return {"success": 'true'}
@administration_required
def create_notification(self, *args, **kwargs):
'''
@ -47,6 +100,8 @@ class NotificationMgr:
notify_groups = NotificationGroups(notify.id, group_name)
db.session.add(notify_groups)
db.session.commit()
if 'sendMail' in form:
self.mail_notification(notify.id)
return {"success": 'true'}
@administration_required
@ -88,6 +143,8 @@ class NotificationMgr:
notify_groups = NotificationGroups(notify.id, group_name)
db.session.add(notify_groups)
db.session.commit()
if 'sendMail' in form:
self.mail_notification(notify_id)
return {"success": 'true'}
@administration_required

View File

@ -206,6 +206,7 @@ function processBasicInfo()
$("#con_ip").html(basic_info.IP);
}
$("#con_time").html(basic_info.RunningTime+"s");
$("#con_billing").html(basic_info.billing+" beans");
},"json");
}
setInterval(processBasicInfo,1000);

View File

@ -59,6 +59,12 @@
{% endfor %}
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Also send email</label>
<div class="col-sm-10">
<input type="checkbox" name="sendMail" value="true">
</div>
</div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-primary" type="submit">Create</button>
@ -73,4 +79,4 @@
{% block script_src %}
{% endblock %}
{% endblock %}

View File

@ -86,6 +86,7 @@
<th>Cpu Usage</th>
<th>Mem Usage</th>
<th>Disk Usage</th>
<th>Billing</th>
<th>Summary</th>
</tr>
</thead>
@ -105,6 +106,7 @@
<td id='{{cluster}}_{{ loop.index }}_cpu'>--</td>
<td id='{{cluster}}_{{ loop.index }}_mem'>--</td>
<td id='{{cluster}}_{{ loop.index }}_disk'>--</td>
<td id='{{cluster}}_{{ loop.index }}_billing'>--</td>
<td><a class="btn btn-info btn-xs" href='/vclusters/{{ cluster }}/{{ container['containername'] }}/'>Realtime</a></td>
</tr>
{% endfor %}
@ -135,6 +137,7 @@
$("#"+index+"_disk").html(usedp+"%<br/>"+detail);
},"json");
$("#"+index+"_time").html(data.monitor.basic_info.RunningTime+"s")
$("#"+index+"_billing").html(data.monitor.basic_info.billing+" beans")
var state = data.monitor.basic_info.State;
if(state == 'RUNNING')

View File

@ -45,6 +45,7 @@
<th>CPU Usage</th>
<th>Mem Usage</th>
<th>Disk Usage</th>
<th>Billing</th>
</tr>
</thead>
<tbody>
@ -60,6 +61,7 @@
<td id='con_cpu'>--</td>
<td id='con_mem'>--</td>
<td id='con_disk'>--</td>
<td id='con_billing'>{{ container['billing'] }} beans</td>
</tr>
</tbody>
</table>

View File

@ -155,6 +155,12 @@
{% endif %}
</div>
</div>
<div class="form-group">
<h5>
<b>Also send email</b>
</h5>
<input type="checkbox" name="sendMail" value="true">
</div>
</form>
</div>
<div class="modal-footer">
@ -209,4 +215,4 @@
$('#deleteNotificationForm_'+notifyId).submit();
}
</script>
{% endblock %}
{% endblock %}