Skip to content
Snippets Groups Projects
Commit f2c3c78a authored by Kelvin Jones's avatar Kelvin Jones
Browse files

General Fixes

Organized: organized the dashboard a little
Changes: small type fixes
Changes: fixed bootstrap 3 alert message style
Fixes: Log page fixes and layout fixes
Added: worker_blender_mem and cpu ussage statistics
Added: blender_stats function to worker
parent 21dcee4a
No related branches found
No related tags found
No related merge requests found
......@@ -8,4 +8,4 @@
/temp/*
venv/
*.log
.ropeproject/*
......@@ -97,44 +97,57 @@ def workers_render_chunk():
@app.route('/worker/<worker_id>')
def worker(worker_id):
#print(workers)
worker = None
try:
workers = http_request(BRENDER_SERVER, '/workers')
workers = json.loads(workers)
if worker_id in workers:
for key, val in workers.iteritems():
if worker_id in key:
try:
worker = http_request(val['ip_address'], '/run_info')
worker = json.loads(worker)
entry = ({"ip_address": val['ip_address'], "worker_id": worker_id, "status": val['status']})
worker.update(entry)
except IOError:
worker = {
'worker_id': worker_id,
'status': 'N/A',
'update_frequent': {
'load_average': {
'5min': 'N/A',
'1min': 'N/A',
'15min': 'N/A'
},
'worker_num_cpus': 'N/A',
'worker_cpu_percent': 'N/A',
'worker_architecture': 'N/A',
'worker_mem_percent': 'N/A',
'worker_disk_percent': 'N/A'
},
'hostname': 'N/A',
'system': 'N/A',
'mac_address': 'N/A',
'worker_blender_cpu_usage': 'coming soon',
'worker_blender_mem_usage': 'coming soon'
}
except KeyError:
'''
there are multiple exceptions that we can use here
1. KeyError
2. UnboundLocalError
3. NameError
'''
print 'worker doesnt exist'
if worker_id in workers:
for key, val in workers.iteritems():
if worker_id in key:
try:
worker = http_request(val['ip_address'], '/run_info')
worker = json.loads(worker)
entry = ({"ip_address": val['ip_address'], "worker_id": worker_id, "status": val['status']})
worker.update(entry)
except IOError:
worker = {
'worker_id': worker_id,
'status': val['status'],
'update_frequent': {
'load_average': {
'5min': 'N/A',
'1min': 'N/A',
'15min': 'N/A'
},
'worker_num_cpus': 'N/A',
'worker_cpu_percent': 'N/A',
'worker_architecture': 'N/A',
'worker_mem_percent': 'N/A',
'worker_disk_percent': 'N/A'
},
'hostname': 'N/A',
'system': 'N/A',
'mac_address': 'N/A',
'worker_blender_cpu_usage': 'N/A',
'worker_blender_mem_usage': 'N/A'
}
if worker:
return render_template('worker.html', worker=worker, title='worker')
except:
else:
return make_response('worker ' + worker_id + ' doesnt exist')
@app.route('/shots/')
def shots_index():
shots = http_request(BRENDER_SERVER, '/shots')
......@@ -267,8 +280,8 @@ def status():
@app.route('/log/', methods=['GET', 'POST'])
def log():
if request.method == 'POST':
result = request.form['result']
if result:
try:
......@@ -283,7 +296,7 @@ def log():
'Please make sure the log file exists at ' + result)
else:
flash('No log to read Please input a filepath ex: ' +
'/User/koder/log.log')
'log.log')
return render_template('log.html', title='status')
......
......@@ -161,15 +161,13 @@
</div>
<div class="col-md-10">
{% for message in get_flashed_messages() %}
<div class="alert">
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ message }}
{% for message in get_flashed_messages() %}
<div class="alert alert-warning">
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ message }}
</div>
{% endfor %}
{% endfor %}
{% block body %}{% endblock %}
</div>
</div>
<hr>
......
{% extends "layout.html" %}
{% block footer_scripts %}
<script type="text/javascript">
$(function(){
$("#log > p:gt("+($("#log > p").length-35)+")").addClass("show special");
$('.' + "show").show();
});
$(function(){
$("#log > p:gt("+($("#log > p").length-5)+")").addClass("show special");
$('.' + "show").show();
});
$(".morelink").click(function(){
if($("#log > p").hasClass("hide")) {
$("#log > p").addClass("show");
$('.' + "show").show();
$("#log > p").removeClass("hide");
$('.' + "morelink").text('Show Less Log');
} else {
$("#log > p").addClass("hide");
$('.' + "hide").hide();
$("#log > p").removeClass("show");
$('.' + "special").show();
$('.' + "morelink").text('Show More Log');
}
});
$(".morelink").click(function(){
if($("#log > p").hasClass("hide")) {
$("#log > p").addClass("show");
$('.' + "show").show();
$("#log > p").removeClass("hide");
$('.' + "morelink").text('Show Less Log');
} else {
$("#log > p").addClass("hide");
$('.' + "hide").hide();
$("#log > p").removeClass("show");
$('.' + "special").show();
$('.' + "morelink").text('Show More Log');
}
});
</script>
{% endblock %}
{% block body %}
<div class="page-header">
<h1>Log</h1>
<h3>{% if result %} {{ result }} {% endif %}</h3>
<br/>
<form action="/log/" method="POST">
<div class="input-append">
<input class="span2" id="appendedInputButton" type="text" placeholder="ex: /User/koder/log.log" name="result">
<button class="btn" type="submit">Go!</button>
</div>
</form>
</div>
<div id="log">
<hr>
<div class="row">
<form action="/log/" method="POST">
<div class="input-group span2">
<input class="form-control" id="appendedInputButton" type="text" placeholder="ex: log.log" value="{% if result %} {{ result }} {% endif %}" name="result">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Go!</button>
</span>
</div>
</form>
</div>
<div id="log">
<hr>
{% for line in lines %}
<p class="hide">{{ line }}</p>
<p class="hide">{{ line }}</p>
{% endfor %}
{% if lines %}
<a class="morelink">Show More Log</a>
<hr>
<a class="morelink">Show More Log</a>
{% endif %}
</div>
</div>
{% endblock %}
......@@ -19,14 +19,14 @@
</div>
<div class="panel-body">
<p>hostname: {{worker['hostname'] | default('N/A')}}</p>
<p>status: <b class="{{ worker['status']}}">{{ worker['status'] | default('N/A')}}</b></p>
<p>cores: {{ worker['update_frequent']['worker_num_cpus'] | default('N/A')}}</p>
<p>architecture: {{worker['update_frequent']['worker_architecture'] | default('N/A')}}</p>
<p>cpu percent: {{worker['update_frequent']['worker_cpu_percent'] | default('N/A')}} %</p>
<p>mem percent: {{worker['update_frequent']['worker_mem_percent'] | default('N/A')}} %</p>
<p>disk percent: {{worker['update_frequent']['worker_disk_percent'] | default('N/A')}} %</p>
<p>blender mem usage: {{worker['update_frequent']['worker_blender_mem_usage'] | default('N/A')}}</p>
<p>blender cpu usage: {{worker['update_frequent']['worker_blender_cpu_usage'] | default('N/A')}} %</p>
<p>blender mem usage: {{worker['update_frequent']['worker_blender_mem_usage'] | default('N/A')}} %</p>
</div>
<div class="panel-footer">
<p class="pull-right">
......
from peewee import *
from datetime import date
import random
DATABASE = 'brender.sqlite'
db = SqliteDatabase(DATABASE)
......
......@@ -7,11 +7,14 @@ import platform
import flask
import os
import select
import gocept.cache.method
from threading import Thread
from flask import Flask, jsonify, redirect, url_for, request
from uuid import getnode as get_mac_address
BRENDER_SERVER = 'http://brender-server:9999'
MAC_ADDRESS = get_mac_address() # the MAC address of the worker
HOSTNAME = socket.gethostname() # the hostname of the worker
......@@ -27,7 +30,7 @@ app = Flask(__name__)
app.config.update(
DEBUG=True
#SERVER_NAME = 'brender-worker:' + str(PORT)
)
)
def http_request(command, values):
......@@ -53,9 +56,9 @@ def register_worker():
time.sleep(0.1)
http_request('connect', {'mac_address': MAC_ADDRESS,
'port': PORT,
'hostname': HOSTNAME,
'system': SYSTEM})
'port': PORT,
'hostname': HOSTNAME,
'system': SYSTEM})
# we use muliprocessing to register the client the worker to the server
......@@ -119,12 +122,12 @@ def run_blender_in_thread(options):
options['blender_path'],
'-b',
options['file_path'],
'-s' ,
'-s',
options['start_frame'],
'-e',
options['end_frame'],
'-a'
]
]
print("[Info] Running %s" % render_command)
......@@ -139,7 +142,7 @@ def run_blender_in_thread(options):
f.write(full_output)
http_request('jobs/update', {'id': options['job_id'],
'status': 'finished'})
'status': 'finished'})
@app.route('/execute_job', methods=['POST'])
......@@ -164,28 +167,50 @@ def update():
blender_process = flask.g.get("blender_process")
if blender_process:
blender_process.kill()
return('done')
return('done')
@gocept.cache.method.Memoize(10)
def blender_stats(blender_stat):
import psutil
if 'cpu' in [blender_stat]:
try:
a = [x for x in psutil.get_process_list() if x.name == 'blender']
cpu = []
for ab in a:
cpu.append(ab.get_cpu_percent())
print sum(cpu)
return round(sum(cpu), 2)
except psutil._error.NoSuchProcess:
return 'N/A'
elif 'mem' in [blender_stat]:
try:
a = [x for x in psutil.get_process_list() if x.name == 'blender']
mem = []
for ab in a:
mem.append(ab.get_memory_percent())
return round(sum(mem), 2)
except psutil._error.NoSuchProcess:
return 'N/A'
@gocept.cache.method.Memoize(5)
def get_system_load():
import psutil
import platform
return ({
"load_average": ({
"1min": round(os.getloadavg()[0], 2),
"5min": round(os.getloadavg()[1], 2),
"15min": round(os.getloadavg()[2], 2)
}),
}),
"worker_cpu_percent": psutil.cpu_percent(),
"worker_mem_percent": psutil.phymem_usage().percent,
"worker_disk_percent": psutil.disk_usage('/').percent,
"worker_num_cpus": psutil.NUM_CPUS,
"worker_architecture": platform.machine(),
'worker_blender_cpu_usage': 'coming soon',
"worker_blender_mem_usage": 'coming soon'
})
'worker_blender_cpu_usage': blender_stats('cpu'),
"worker_blender_mem_usage": blender_stats('mem')
})
@app.route('/run_info')
......@@ -195,8 +220,8 @@ def run_info():
return jsonify(mac_address=MAC_ADDRESS,
hostname=HOSTNAME,
system=SYSTEM,
update_frequent=get_system_load()
)
update_frequent=get_system_load(),
)
if __name__ == "__main__":
start_worker()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment