basic changes

community
Steve L. Nyemba 6 years ago
parent f48d4decfd
commit 31f5317430

@ -13,28 +13,33 @@
- Add socketio, so that each section of the dashboard updates independently - Add socketio, so that each section of the dashboard updates independently
""" """
from flask import Flask, session, request, redirect, Response from flask import Flask, session, request, redirect, Response, stream_with_context
from flask.templating import render_template from flask.templating import render_template
import requests import requests
from flask_session import Session from flask_session import Session
from datetime import datetime
import time import time
import sys import sys
import os import os
import json import json
import re import re
import monitor # import monitor
import uuid import uuid
from utils.register import Register # from utils.register import Register
from utils.transport import *
from utils.agents import actor
from utils.charting import *
from utils.transport import *
from utils.ml.analytics import *
# from utils.agents import actor
from threading import Thread
#from utils.ml import ML,AnomalyDetection,AnalyzeAnomaly #from utils.ml import ML,AnomalyDetection,AnalyzeAnomaly
import utils.params as SYS_ARGS import utils.params as SYS_ARGS
# from utils.agents.actor import * # from utils.agents.actor import *
import utils.agents.actor as actor # import utils.agents.actor as actor
import pickle import pickle
from utils.agents.manager import Manager # from utils.agents.manager import Manager
app = Flask(__name__) app = Flask(__name__)
app.config['SECRET_KEY'] = '!h8-[0v8]247-4-360' app.config['SECRET_KEY'] = '!h8-[0v8]247-4-360'
@ -49,6 +54,8 @@ f.close()
# #
#from threading import Thread, RLock #from threading import Thread, RLock
p = CONFIG['store']['args'] p = CONFIG['store']['args']
global SYS_STORE
SYS_STORE = CONFIG['store']
class_read = CONFIG['store']['class']['read'] class_read = CONFIG['store']['class']['read']
class_write= CONFIG['store']['class']['write'] class_write= CONFIG['store']['class']['write']
factory = DataSourceFactory() factory = DataSourceFactory()
@ -80,43 +87,324 @@ def home():
print (e) print (e)
return render_template('dashboard.html',context=context,title=title,app_names=apps) return render_template('dashboard.html',context=context,title=title,app_names=apps)
@app.route('/register',methods=['POST']) def update_plan(uid,plan,auid=None):
url = ":protocol://:host/subscribe/smart-top"
url = url.replace(":protocol",CONFIG['protocol']).replace(":host",CONFIG['api'])
try:
args = {"type":SYS_STORE['class']['read'],"args":SYS_STORE['args']}
# reader = factory.instance(**args)
headers = {"uid":uid}
if plan :
headers['pid'] = plan
if auid is not None:
headers["auid"]=json.dumps([auid])
r = requests.post(url,headers=headers)
return json.loads( r.text)
except Exception,e:
print e
return None
def set_userdata(key):
"""
This function will pull an authenticated user data into the session
@param key user key
"""
args = {"type":SYS_STORE['class']['read'],"args":SYS_STORE['args']}
reader = factory.instance(**args)
views = []
for id in views :
r = reader.view(id,key=key)
session[id] = r
pass
@app.route('/1/register',methods=['POST'])
def register() : def register() :
""" """
This function registers a user and provides This function registers a user and provides, if we already have a
if the customer/user already exists a new key will be generated for her with an unchanged subscription
""" """
global p
body = request.get_json(silent=True) body = request.get_json(silent=True)
uid = body['uid']
default_plan = CONFIG['plan'] # session['info'] = body
if 'plan' not in body : uid = body['user']['uid']
plan = CONFIG['plan'] args = {"type":SYS_STORE['class']['read'],"args":SYS_STORE['args']}
reader = factory.instance(**args)
key = None
if 'key' not in session :
key = reader.view('users/uid_map',key=uid)
# if key :
# session['key'] = key
if key :
plans = reader.view('users/active_plan',key=str(key))
else: else:
plan = body['plan'] plans = None
handler = Register(write=class_write,read=class_read,store=p,default=default_plan,uid=uid) plan = body['plan'] if 'plan' in body else CONFIG['default_plan']#-- default plan
r = handler.register(plan)
session['key'] = r['key']
plans = update_plan(uid,plan)
key = reader.view('users/uid_map',key=uid)
if 'key' not in session :
args = {"type":SYS_STORE['class']['write'],"args":SYS_STORE['args']}
args['args']['uid'] = key
writer = factory.instance(**args)
auid = str(uuid.uuid5(uuid.NAMESPACE_DNS,str(key)))
writer.write(label='hash',data=auid)
session['key'] = key
if plans :
session['user-plan'] = plans
return ('',204)
return "",403
@app.route('/1/store/<id>',methods=['POST'])
def store_data(id) :
"""
This function stores data into the session coming from a client/dashboard
"""
body = request.get_json(silent=True)
session[id] = body
return ('',204)
@app.route('/1/apps',methods=['GET'])
def apps() :
if 'key' in session :
args = {"type":SYS_STORE['class']['read'],"args":SYS_STORE['args']}
args['args']['uid'] = session['key']
factory = DataSourceFactory()
reader = factory.instance(**args)
logs = reader.read()['apps']
logs = logs[len(logs)-1]
WEB_ARGS = {}
WEB_ARGS['grid'] = {"fields":[{"name":"name","title":"Name","headercss":"small bold"},{"name":"mem","title":"Memory","headercss":"small bold","type":"number"},{"name":"cpu","title":"CPU","headercss":"small bold","type":"number"},{"name":"started","title":"Started", "headercss":"small bold","width":"65px"},{"name":"status","title":"Status","headercss":"small bold"}]}
WEB_ARGS['grid']['data'] = logs
WEB_ARGS['context'] = SYS_ARGS.PARAMS['context']
return render_template('dashboard/apps/data-grid.html',**WEB_ARGS)
else:
return render_template('error.html')
@app.route("/1/plan",methods=['GET'])
def active_plan():
args = {"type":SYS_STORE['class']['read'],"args":SYS_STORE['args']}
factory = DataSourceFactory()
reader = factory.instance(**args)
if 'key' in session :
return (json.dumps(plans),200)
else:
return ('',403)
@app.route("/1/board",methods=["GET"])
def get_board():
session['key'] = 'cus_D2x3ItYNfWjSY3'
if 'key' in session :
args = {"type":SYS_STORE['class']['read'],"args":SYS_STORE['args']}
args['args']['uid'] = session['key']
args['context'] = SYS_ARGS.PARAMS['context']
# if 'nodes' not in session :
handler = didact(config=args,key=session['key'])
args['nodes'] = handler.get('nodes')
for id in handler.cache :
session[id] = handler.cache[id]
args['app_logs'] = session['apps.logs']
args['app_summary'] = session['apps.summary']
args['app_grid'] = session['apps.grid']
args['folders_summary'] = session['folders.summary']
args['folder_size'] = session['folders.max_size']
return render_template("dashboard/apps/summary.html",**args)
else:
return ('',403)
@app.route("/1/clients",methods=['GET'])
def get_clients():
if 'key' in session :
if request.method == 'GET' :
args = {"type":SYS_STORE['class']['read'],"args":SYS_STORE['args']}
args['args']['uid'] = session['key']
reader = factory.instance(**args)
document = reader.read()
lclients = document['clients'] if 'clients' in document else []
args = {"clients":lclients}
args['context'] = SYS_ARGS.PARAMS['context'] if 'context' in SYS_ARGS.PARAMS else ''
args['grid'] = {"fields":[{"name":"key","width":"45%","css":"small","headercss":"small bold"},{"name":"node","title":"Alias","headercss":"small bold","css":"small","type":"text"},{"name":"apps.length","title":"Apps","css":"small","headercss":"small bold","type":"number","width":"65px"},{"name":"folders.length","title":"Folders","css":"small","headercss":"small bold","type":"number","width":"65px"}]}
args['grid']['data'] = lclients
args['hash'] = document['hash']
args['features'] = {"clients":1}
args['context'] = SYS_ARGS.PARAMS['context']
if 'user-info' in session :
args['uid'] = session['user-info']['uid']
if 'user-plan' in session :
features = json.loads(session['user-plan'][0]['metadata']['features'])
# features = json.loads(session['user-plan']['metadata']['features'])
args['client_count'] = features['clients']
return render_template('dashboard/client-keys.html',**args)
# elif request.method == 'POST' :
# clients = request.get_json(silent=True)
# #
# # We can NOT have uncontrolled writes
# #
# # N = session['user-plan'][0]['metadata']['features']
# # clients = client[:N] if len(clients) > N else clients
# args = {"type":SYS_STORE['class']['write'],"args":SYS_STORE['args']}
# args['args']['uid'] = session['key']
# writer = factory.instance(**args)
# # writer.set({"clients":clients})
# writer.set(clients=clients)
# return ('',200)
# pass
else:
return ('',403)
@app.route('/1/clients',methods=['POST'])
def set_clients() :
if 'key' in session :
clients = request.get_json(silent=True)
# #
# We should try to run a thread that loads the data for the user so when she requests it it is ready # We can NOT have uncontrolled writes
# @TODO:
# #
try: # N = session['user-plan'][0]['metadata']['features']
session['plan'] = r # clients = client[:N] if len(clients) > N else clients
key = r['key']
args = json.loads(json.dumps(p)) args = {"type":SYS_STORE['class']['write'],"args":SYS_STORE['args']}
args['dbname'] = r['name'] args['args']['uid'] = session['key']
gReader = factory.instance(type=class_read,args=args) writer = factory.instance(**args)
session['logs'] = {} # writer.set({"clients":clients})
for id in ['app_status','log_size','emails'] : writer.set(clients=clients)
session['logs'][id] = gReader.view('summary/'+id.strip(),key=key) return ('',200)
except Exception as e:
print (e) @app.route("/1/emails",methods=['GET'])
def get_emails():
"""
This function retrieves a list of emails for a given user
@session.has('key')
"""
if 'key' in session:
user_key = session['key']
if request.method == 'GET' :
args = {"type":SYS_STORE['class']['read'],"args":SYS_STORE['args']}
args['args']['uid'] = session['key']
reader = factory.instance(**args)
document = reader.read()
emails = document['emails'] if 'emails' in document else []
args = {"emails":[{"email":value} for value in emails]}
args['context'] = SYS_ARGS.PARAMS['context'] if 'context' in SYS_ARGS.PARAMS else ''
args['uid'] = str(emails[0])
return render_template('dashboard/user-emails.html',**args)
else:
return ('',403)
@app.route("/1/emails",methods=['POST'])
def set_emails():
"""
This function is designed to add an email to the list of contacts
@header content-type application/json
@body [email_o,email_i,...]
@session.has('key')
"""
if 'key' in session:
user_key = session['key']
emails = request.get_json(silent=True)
args = {"type":SYS_STORE['class']['write'],"args":SYS_STORE['args']}
args['args']['uid'] = session['key']
writer = factory.instance(**args)
writer.set(emails=list(set(emails)))
return ('',200)
else:
return ('',403)
@app.route("/1/client/login",methods=['POST'])
def client_login():
"""
This function establishes a connection and session with the calling code
and will return the the features provided the keys supplied are found
:request application/json {id:<value>,key:<value>}
"""
return json.dumps(r) key = request.headers['id']+'@'+request.headers['key']
if 'client' not in session :
args = {"type":SYS_STORE['class']['read'],"args":SYS_STORE['args']}
# args['args']['uid'] = session['key']
reader = factory.instance(**args)
features = reader.view('clients/config',key=key)
if features :
session['client'] = {key:features}
uid = reader.view('clients/uid_map',key=key)
session['key'] = uid
else:
return "",403
else:
features = session['client'][key]
return json.dumps(features),200
@app.route("/1/client/log",methods=['POST'])
def client_log():
if 'client' in session and 'key' in session:
key = request.headers['id']+'@'+request.headers['key']
context = request.headers['context']
body = request.get_json(silent=True)
now = datetime.now()
date = {"month":now.month,"day":now.day,"year":now.year,"hour":now.hour,"minute":now.minute,"second":now.second,"long":time.mktime(now.timetuple())}
args = dict({"type":SYS_STORE['class']['write'],"args":SYS_STORE['args']})
args['args']['uid'] = session['key']
row = {"node":request.headers['id'],"date":date,"log":body}
#
# We should make sure that we don't have to archive the data
writer = factory.instance(**args)
writer.write (label=context,row=row)
return "",200
else :
return "",403
@app.route("/1/log",methods=['POST'])
def log():
key = request.headers['key']
id = request.headers['id']
label = request.headers['label'] if 'label' in request.headers else None
row = request.get_json(silent=True)
if row and label :
args = {"type":SYS_STORE['class']['read'],"args":SYS_STORE['args']}
reader = factory.instance(**args)
r = reader.view('users/clients',key=key)
if r:
args = {"type":SYS_STORE['class']['write'],"args":SYS_STORE['args']}
writer = factory.instance(**args)
writer.write(label=label, row=row)
return ('1',200)
else:
return ('0',403) #-- not authorized (sorry)
else :
return ('',400) #-- malformed request i.e missing stuff
@app.route("/1/notify/<key>",methods=["POST"])
def notify(key):
"""
This function is designed to notify parties via email, the notification is a report of sorts
@TODO: Create HTML/PDF and email it to a variety of parties.
"""
#
# TODO: Does the user have permission and is her plan still active.
#
pass
@app.route('/1/get/nodes') @app.route('/1/get/nodes')
def get_nodes(): def get_nodes():
""" """
@deprecate
This function returns the labels of applications for every node registered This function returns the labels of applications for every node registered
@param None @param None
""" """
@ -133,6 +421,7 @@ def get_nodes():
@app.route('/1/get/apps') @app.route('/1/get/apps')
def get_apps(): def get_apps():
""" """
@deprecate
This function returns the applications for a given node This function returns the applications for a given node
@param node identifier e.g: apps@zulu.org @param node identifier e.g: apps@zulu.org
""" """
@ -147,8 +436,77 @@ def get_apps():
print (e) print (e)
return json.dumps(r) return json.dumps(r)
def get_logs(key,view_name):
"""
This function will execute a view provided a key and a name for the view
The calling code will insure the preconditions are met i.e session ...
@param key user's key
@param view_name name of the view to execute
"""
store = CONFIG['store']['args']
args = str(json.dumps(store))
args = json.loads(args)
args['dbname'] = plan['name']
args['uid'] = key
session['store'] = args
session['key'] = key
gReader = factory.instance(type=class_read,args=args)
return gReader.view(view_name)
@app.route('/1/get/logs/apps/<id>')
def app_logs(id):
"""
This function returns application log information for a given user
@param id <usage|usage-details|status|status-details|emails|log-size|nodes>
"""
x = {'usage':'app_resources','status-details':'app_status_details','usage-details':'app_resource_usage_details','status':'app_status',"nodes":"nodes"}
r = "{}"
#
# let's make sure we have an active session otherwise, nothing is to be done
#
key = session['key'] if 'key' in session else None
if key is None and 'key' in request.headers:
key = request.headers['key']
status=403
plan = session['plan'] if 'plan' in session else None
if id in x and key and plan:
status = 200
try:
view_name='summary/'+x[id].strip()
r = get_logs(key,view_name)
except Exception,e:
print e;
return r,status
@app.route('/1/get/logs/folders/<id>')
def folder_logs(id):
x = {"info":"folder_info","nodes":"nodes"}
r = "{}"
#
# let's make sure we have an active session otherwise, nothing is to be done
#
key = session['key'] if 'key' in session else None
if key is None and 'key' in request.headers:
key = request.headers['key']
status=403
plan = session['plan'] if 'plan' in session else None
if id in x and key and plan:
status = 200
try:
# store = CONFIG['store']['args']
view_name='summary/'+x[id].strip()
r = get_logs(key,view_name)
except Exception,e:
print e;
return r,status
@app.route('/1/get/logs') @app.route('/1/get/logs')
def get_logs() : def get_logs() :
"""
@deprecate
"""
r = {} r = {}
#session['key'] = 'c259e8b1-e2fb-40df-bf03-f521f8ee352d' #session['key'] = 'c259e8b1-e2fb-40df-bf03-f521f8ee352d'
key = session['key'] if 'key' in session else None key = session['key'] if 'key' in session else None
@ -204,17 +562,21 @@ def update_profile():
def send_to_app () : def send_to_app () :
""" """
This function will send a message to an agent, that will execute the appropriate command This function will send a message to an agent, that will execute the appropriate command
@TODO: Provide some kind of feedback @TODO: Provide some kind of feedback, insure the user's plan is verified so they do NOT do something unauthorized
""" """
msg = {}
try:
body = request.get_json(silent=True) body = request.get_json(silent=True)
key = session['key'] key = session['key']
args = {"host":CONFIG['api'],"qid":body["node"],"uid":key} args = {"host":CONFIG['api'],"qid":body["node"],"uid":key}
print key body = dict(body,**info)
qhandler= factory.instance(type='QueueWriter',args=args) qhandler= factory.instance(type='QueueWriter',args=args)
label=body["node"] label=body["node"]
qhandler.write(label=label,row=body) qhandler.write(label=label,row=body)
except Exception as e:
print e
msg = {'error':e.message}
return '',204 return '',204
@app.route("/1/message/folder",methods=["POST"]) @app.route("/1/message/folder",methods=["POST"])
def send_to_folder(): def send_to_folder():
@ -222,7 +584,7 @@ def send_to_folder():
@app.route("/1/sys/usage/trend") @app.route("/1/sys/usage/trend")
def get_usage_trend(): def get_usage_trend():
""" """
@deprecate
This function returns cpu/memory usage for the entire system being monitored. It will return the 24 most recent observations in the logs This function returns cpu/memory usage for the entire system being monitored. It will return the 24 most recent observations in the logs
@param None @param None
@return {memory_usage:[],cpu_usage:[],app_count:value,memory_available:[]} @return {memory_usage:[],cpu_usage:[],app_count:value,memory_available:[]}
@ -239,6 +601,7 @@ def get_usage_trend():
@app.route("/1/app/usage/trend") @app.route("/1/app/usage/trend")
def get_usage_detail(): def get_usage_detail():
""" """
@deprecate
This function returns detailed information about usage per application monitored. It will return the 24 most recent observations in the logs This function returns detailed information about usage per application monitored. It will return the 24 most recent observations in the logs
@param node node identifier e.g: apps@zulu.io @param node node identifier e.g: apps@zulu.io
@ -277,6 +640,7 @@ def get_usage_detail():
@app.route('/1/app/status') @app.route('/1/app/status')
def app_status() : def app_status() :
""" """
@deprecate
This function aggregates the number of crashes/running/idle instances found in the past 24 log entries This function aggregates the number of crashes/running/idle instances found in the past 24 log entries
for a particular application for a particular application
@param nid node identifier e.g: app@zulu.io @param nid node identifier e.g: app@zulu.io
@ -378,6 +742,7 @@ def init_collector():
Invalid parameters were sent Invalid parameters were sent
""" """
pass pass
return json.dumps(r) return json.dumps(r)
def InitCollector(): def InitCollector():
""" """
@ -464,7 +829,7 @@ def sandbox():
try: try:
handler.init(conf[id]) handler.init(conf[id])
r.append (dict(handler.composite(),**{"label":id})) r.append (dict(handler.composite(),**{"label":id}))
except Exception,e: except Exception as e:
pass pass
else: else:
@ -579,7 +944,7 @@ def user():
#_info = params[name] #_info = params[name]
#try: #try:
#xo = ML.Filter('label',name,d) #xo = ML.Filter('label',name,d)
#except Exception,e: #except Exception as e:
#xo = [] #xo = []
##print name,e ##print name,e
#if len(xo) == 0: #if len(xo) == 0:
@ -663,12 +1028,55 @@ def user():
#d = [] #d = []
#return json.dumps(d) #return json.dumps(d)
@app.route("/1/plot/<format>/<id>/<key>",methods=['GET'])
def get_charts(format,id,key):
remove = request.args['no'].split(',') if 'no' in request.args else []
series = ['series_1']
# args = dict(session[key],**{"remove":remove})
# print session['cloud-info']
# if id == 'pie' :
# X = list(np.arange(3) * np.random.randn() + 10)
# X[2] = 23.5
# else :
# X = []
# series = []
# for i in range(0,3):
# X.append([ np.random.randn()+10 for i in range(0,3)])
# series.append('series '+str(i))
# labels = session['cloud-info']['labels'] #['Foo','Boo','Joo']
# title = 'Do More'
# series = [ 'Series '+str(i+1) for i in range(len(labels))]
# args = {"x":X,"labels":labels,"title":title,"series":series,"remove":remove}
args = session[key]
if isinstance(args,list) :
index = int(request.args['index'])
args = args[index]
# if remove is not None :
args['remove'] = remove
info = Graph.instance(format,id,**args)
if format in ['image','png','jpeg','jpg'] :
# g = ImageGraphs()
# stream = g.pie(X,labels,title)
return Response(info,mimetype='image/png')
else:
args = {'chart_id': ('g_'+id)}
args['config'] = info
args['context'] = SYS_ARGS.PARAMS['context'] if 'context' in SYS_ARGS.PARAMS else ''
return render_template('dashboard/graphs/chart.html',**args)
if __name__== '__main__': if __name__== '__main__':
app.config.from_object(__name__)
# ThreadManager.start(CONFIG) SESSION_PERMANENT=True
app.config['SESSION_TYPE'] = 'filesystem'
app.config['MAX_CONTENT_LENGTH'] = 1600 * 1024 * 1024
app.secret_key = '360-8y-[0v@t10n]+kr81v17y'
if 'port' not in SYS_ARGS.PARAMS : if 'port' not in SYS_ARGS.PARAMS :
SYS_ARGS.PARAMS['port'] = 8484 SYS_ARGS.PARAMS['port'] = 8484
PORT = int(SYS_ARGS.PARAMS['port']) PORT = int(SYS_ARGS.PARAMS['port'])
app.run(host='0.0.0.0' ,port=PORT,debug=True,threaded=True) app.run(host='0.0.0.0' ,port=PORT,debug=True,threaded=True)

@ -1,12 +1,5 @@
type = ['','info','success','warning','danger']; type = ['','info','success','warning','danger'];
function getNode(name){
var nodeName = {}
nodeName.name = name
console.log('nodename...', nodeName.name)
dashboard.initChartist(nodeName)
}
dashboard = { dashboard = {
initPickColor: function(){ initPickColor: function(){
$('.pick-class-label').click(function(){ $('.pick-class-label').click(function(){
@ -22,38 +15,39 @@ dashboard = {
}); });
}, },
initChartist: function(nodeName){ initChartist: function(){
function make_array() {
triple_array = [];
for (i=0;i<3;i++){
myarray = Array.from({length: 24}, () => Math.floor(Math.random() * 100))
triple_array.push(myarray)
}
return triple_array
}
// monitoring apps chart
var getData = $.get('/1/app/usage/trend'); var getData = $.get('/1/app/usage/trend');
getData.done(function(results) { getData.done(function(results) {
var data = JSON.parse(results) var app_usage_trend = JSON.parse(results);
if (typeof nodeName === 'undefined'){ if ($.isEmptyObject(app_usage_trend)){
var node = data['apps@michaels-MBP']; console.log('app_usage_trend is empty, setting testing values.');
console.log("undefined nodename.........") app_usage_trend = [];
} else { random_array = make_array();
console.log('this is nodeName...', nodeName) app_usage_trend = random_array
console.log('this is nodeName.name...', nodeName.name)
var node = data[nodeName.name]
console.log('data.name..', data[name])
} }
var app = node['chrome'];
var cpu = app['cpu'];
var memory_used = app['memory_used'];
console.log('data...',data)
console.log('node...',node)
console.log('app...',app)
console.log('cpu...',cpu)
console.log('memory_used...', memory_used)
// monitoring apps chart
var dataChart = { var dataChart = {
labels: ['24','23','22','21','20','19','18','17','16','15','14','13','12','11','10','9','8','7','6','5','4','3','2','1' ], labels: ['24','23','22','21','20','19','18','17','16','15','14','13','12','11','10','9','8','7','6','5','4','3','2','1' ],
series: [cpu, memory_used, [0,0.1,0.3,0.2,0.4,0.6,0.2], ] // TODO: Check the order, the graph is by index not name. series: app_usage_trend //TODO: Check the order, the graph is by index not name.
}; };
dataChartArray = dataChart.series dataChartArray = dataChart.series;
var maxlist = dataChartArray.map(dataChartArray => Math.max.apply(null, dataChartArray)); var maxlist = dataChartArray.map(function (dataChartArray) {
maxNum = Math.max.apply(null, maxlist) return Math.max.apply(null, dataChartArray);
});
maxNum = Math.max.apply(null, maxlist);
var optionsChart = { var optionsChart = {
lineSmooth: false, lineSmooth: false,
@ -62,13 +56,13 @@ dashboard = {
showArea: true, showArea: true,
height: "245px", height: "245px",
axisX: { axisX: {
showGrid: false, showGrid: false
}, },
lineSmooth: Chartist.Interpolation.simple({ lineSmooth: Chartist.Interpolation.simple({
divisor: 1 divisor: 1
}), }),
showLine: true, showLine: true,
showPoint: false, showPoint: false
}; };
var responsiveChart = [ var responsiveChart = [
@ -83,10 +77,10 @@ dashboard = {
Chartist.Line('#chartHours', dataChart, optionsChart, responsiveChart); Chartist.Line('#chartHours', dataChart, optionsChart, responsiveChart);
// cpu and memory -------------------------- // cpu and memory usage--------------------------
var data = { var data = {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], labels: ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
series: [cpu, memory_used] series: make_array()
}; };
@ -111,16 +105,21 @@ dashboard = {
Chartist.Line('#chartActivity', data, options, responsiveOptions); Chartist.Line('#chartActivity', data, options, responsiveOptions);
var getStatus = $.get('1/get/summary/app_status'); //app status pie chart, idle, running, crash
var getStatus = $.get('1/app/status');
getStatus.done(function(results) { getStatus.done(function(results) {
var data = JSON.parse(results) var pie_chart = JSON.parse(results);
let getStatusList = [] if ($.isEmptyObject(pie_chart)){
getStatusList.push(data.idle) console.log('pie_chart is empty, setting testing values.');
getStatusList.push(data.crash) app_status = [1,2,3]
getStatusList.push(data.running) }
// var app_status = [];
// app_status.push(pie_chart.idle);
// app_status.push(pie_chart.crash);
// app_status.push(pie_chart.running);
Chartist.Pie('#chartPreferences', { Chartist.Pie('#chartPreferences', {
labels: getStatusList, labels: app_status,
series: getStatusList series: app_status
},{donut:true}); },{donut:true});
}) /// end getStatus }) /// end getStatus
}) })
@ -135,7 +134,7 @@ dashboard = {
scrollwheel: false, //we disable de scroll over the map, it is a really annoing when you scroll through page scrollwheel: false, //we disable de scroll over the map, it is a really annoing when you scroll through page
styles: [{"featureType":"water","stylers":[{"saturation":43},{"lightness":-11},{"hue":"#0088ff"}]},{"featureType":"road","elementType":"geometry.fill","stylers":[{"hue":"#ff0000"},{"saturation":-100},{"lightness":99}]},{"featureType":"road","elementType":"geometry.stroke","stylers":[{"color":"#808080"},{"lightness":54}]},{"featureType":"landscape.man_made","elementType":"geometry.fill","stylers":[{"color":"#ece2d9"}]},{"featureType":"poi.park","elementType":"geometry.fill","stylers":[{"color":"#ccdca1"}]},{"featureType":"road","elementType":"labels.text.fill","stylers":[{"color":"#767676"}]},{"featureType":"road","elementType":"labels.text.stroke","stylers":[{"color":"#ffffff"}]},{"featureType":"poi","stylers":[{"visibility":"off"}]},{"featureType":"landscape.natural","elementType":"geometry.fill","stylers":[{"visibility":"on"},{"color":"#b8cb93"}]},{"featureType":"poi.park","stylers":[{"visibility":"on"}]},{"featureType":"poi.sports_complex","stylers":[{"visibility":"on"}]},{"featureType":"poi.medical","stylers":[{"visibility":"on"}]},{"featureType":"poi.business","stylers":[{"visibility":"simplified"}]}] styles: [{"featureType":"water","stylers":[{"saturation":43},{"lightness":-11},{"hue":"#0088ff"}]},{"featureType":"road","elementType":"geometry.fill","stylers":[{"hue":"#ff0000"},{"saturation":-100},{"lightness":99}]},{"featureType":"road","elementType":"geometry.stroke","stylers":[{"color":"#808080"},{"lightness":54}]},{"featureType":"landscape.man_made","elementType":"geometry.fill","stylers":[{"color":"#ece2d9"}]},{"featureType":"poi.park","elementType":"geometry.fill","stylers":[{"color":"#ccdca1"}]},{"featureType":"road","elementType":"labels.text.fill","stylers":[{"color":"#767676"}]},{"featureType":"road","elementType":"labels.text.stroke","stylers":[{"color":"#ffffff"}]},{"featureType":"poi","stylers":[{"visibility":"off"}]},{"featureType":"landscape.natural","elementType":"geometry.fill","stylers":[{"visibility":"on"},{"color":"#b8cb93"}]},{"featureType":"poi.park","stylers":[{"visibility":"on"}]},{"featureType":"poi.sports_complex","stylers":[{"visibility":"on"}]},{"featureType":"poi.medical","stylers":[{"visibility":"on"}]},{"featureType":"poi.business","stylers":[{"visibility":"simplified"}]}]
} };
var map = new google.maps.Map(document.getElementById("map"), mapOptions); var map = new google.maps.Map(document.getElementById("map"), mapOptions);
var marker = new google.maps.Marker({ var marker = new google.maps.Marker({
@ -162,10 +161,10 @@ dashboard = {
align: align align: align
} }
}); });
},
} }
};
/** /**
* Global information about the dashboard * Global information about the dashboard
@ -178,29 +177,29 @@ g.summary = {}
* Initializing the top section of the dashboard (apps and folders) * Initializing the top section of the dashboard (apps and folders)
*/ */
g.summary.factory = function (url,pointer) { g.summary.factory = function (url,pointer) {
var object = {} var object = {};
object.url = url object.url = url;
var observer = null var observer = null;
var TIME_ELLAPSED = 2000 ; var TIME_ELLAPSED = 2000 ;
object.callback = function (r) { object.callback = function (r) {
r = JSON.parse(r.responseText) r = JSON.parse(r.responseText);
pointer(r) pointer(r)
//observer.notify() //observer.notify()
} };
object.init = function (observer) { object.init = function (observer) {
observer = observer observer = observer
var httpclient = HttpClient.instance() var httpclient = HttpClient.instance();
//httpclient.setAsync(false) //httpclient.setAsync(false)
httpclient.get(this.url, this.callback) httpclient.get(this.url, this.callback);
setTimeout(function(){ setTimeout(function(){
observer.notify() observer.notify()
},TIME_ELLAPSED) ; },TIME_ELLAPSED) ;
//observer.notify() //observer.notify()
} };
return object return object
} };

@ -46,39 +46,40 @@
<!-- Dashboard DEMO methods, don't include it in your project! --> <!-- Dashboard DEMO methods, don't include it in your project! -->
<script src="{{context}}/static/js/dashboard.js"></script> <script src="{{context}}/static/js/dashboard.js"></script>
<script src="{{context}}/static/js/jx/dom.js"></script> {# <script src="{{context}}/static/js/jx/dom.js"></script>#}
<script src="{{context}}/static/js/jx/rpc.js"></script> {# <script src="{{context}}/static/js/jx/rpc.js"></script>#}
<script src="{{context}}/static/js/jx/utils.js"></script> {# <script src="{{context}}/static/js/jx/utils.js"></script>#}
<script type="text/javascript"> <script type="text/javascript">
var URI_CONTEXT="{{context}}" var URI_CONTEXT="{{context}}";
$(document).ready(function(){ $(document).ready(function(){
var lobservers = [ {#var lobservers = [#}
g.summary.factory('/1/get/summary/app_resources',function(r){ {# g.summary.factory('/1/get/summary/app_resources',function(r){#}
{##}
//r = JSON.parse(r.responseText) {# //r = JSON.parse(r.responseText)#}
jx.dom.set.value('total_cpu',r.cpu_usage) {# jx.dom.set.value('total_cpu',r.cpu_usage)#}
jx.dom.set.value('total_mem',r.memory_usage) {# jx.dom.set.value('total_mem',r.memory_usage)#}
jx.dom.set.value('mem_units',r.units) {# jx.dom.set.value('mem_units',r.units)#}
{##}
}), {# }),#}
g.summary.factory('/1/get/summary/folder_size',function(r){ {# g.summary.factory('/1/get/summary/folder_size',function(r){#}
//console.log(r.responseText) {# //console.log(r.responseText)#}
//r = JSON.parse(r.responseText) {# //r = JSON.parse(r.responseText)#}
if (r.length == 0){ {# if (r.length == 0){#}
r.size = "0.0" {# r.size = "0.0"#}
r.units = 'MB' {# r.units = 'MB'#}
} {# }#}
jx.dom.set.value('total_folder_size',r.size) {# jx.dom.set.value('total_folder_size',r.size)#}
jx.dom.set.value('folder_units',r.units) {# jx.dom.set.value('folder_units',r.units)#}
}), {# }),#}
g.summary.factory('/1/get/summary/app_status',function(r){ {# g.summary.factory('/1/get/summary/app_status',function(r){#}
{##}
jx.dom.set.value('total_app_crashes',r.crash) {# jx.dom.set.value('total_app_crashes',r.crash)#}
}) {# })#}
] {#]#}
{##}
jx.utils.patterns.observer(lobservers,"init") {#jx.utils.patterns.observer(lobservers,"init")#}
//TODO Do we need the above JX stuff ?
dashboard.initChartist(); dashboard.initChartist();
}); });
@ -190,7 +191,7 @@
</div> </div>
<div class="col-xs-7"> <div class="col-xs-7">
<div class="numbers"> <div class="numbers">
<div id="total_cpu" align="center">00</div> <div id="total_cpu" align="center"></div>
<div class="small" align="right">Percent</div> <div class="small" align="right">Percent</div>
</div> </div>

@ -43,7 +43,7 @@ class Register :
auid = str(uuid.uuid4()) auid = str(uuid.uuid4())
headers = {"uid":self.uid,"pid":pid,"auid":json.dumps([auid])} headers = {"uid":self.uid,"pid":pid,"auid":json.dumps([auid])}
url="https://the-phi.com/store/init/monitor" url="https://the-phi.com/store/init/smart-top"
r = requests.post(url,headers=headers) r = requests.post(url,headers=headers)
return json.loads(r.text) return json.loads(r.text)

@ -471,7 +471,8 @@ class Couchdb:
dbname = args['dbname'] dbname = args['dbname']
self.server = Server(uri=uri) self.server = Server(uri=uri)
self.dbase = self.server.get_db(dbname) self.dbase = self.server.get_db(dbname)
if self.dbase.doc_exist(self.uid) == False: create = args['create'] if 'create' in args else False
if self.dbase.doc_exist(self.uid) == False and create == True:
self.dbase.save_doc({"_id":self.uid}) self.dbase.save_doc({"_id":self.uid})
""" """
Insuring the preconditions are met for processing Insuring the preconditions are met for processing
@ -576,13 +577,25 @@ class CouchdbWriter(Couchdb,Writer):
# #
# If the document doesn't exist then we should create it # If the document doesn't exist then we should create it
# #
def set(self,**args):
_document = self.dbase.get(self.uid)
# document = dict(_document,**document)
for key in args :
_document[key] = args[key]
# if _document :
# document['_id'] = _document['_id']
# document['_rev']= _document['_rev']
self.dbase.save_doc(_document)
def write(self,**params):
""" """
write a given attribute to a document database write a given attribute to a document database
@param label scope of the row repair|broken|fixed|stats @param label scope of the row repair|broken|fixed|stats
@param row row to be written @param row row to be written
""" """
def write(self,**params):
document = self.dbase.get(self.uid) document = self.dbase.get(self.uid)
label = params['label'] label = params['label']
@ -592,18 +605,23 @@ class CouchdbWriter(Couchdb,Writer):
row = params['row'] row = params['row']
row_is_list = isinstance(row,list) row_is_list = isinstance(row,list)
if label not in document : if label not in document :
document[label] = row if row_is_list else [row] document[label] = []
elif isinstance(document[label][0],list) :
document[label].append(row) document[label].append(row)
else: # if label not in document :
document[label] += row # document[label] = row if row_is_list else [row]
# elif isinstance(document[label][0],list) :
# document[label].append(row)
# else:
# document[label] += row
else : else :
if label not in document : if label not in document :
document[label] = {} document[label] = params['data']
if isinstance(params['data'],list) == False : elif isinstance(document[label],dict) == False and isinstance(params['data'],dict):
document[label] = dict(document[label],**params['data']) document[label] = dict(document[label],**params['data'])
elif isinstance(document[label],list) == False and isinstance(params['data'],list):
document[label] = document[label] + params['data']
else: else:
document[label] = params['data'] document[label] = params['data']

Loading…
Cancel
Save