It works
parent
f8d5ed14e2
commit
119f049b48
@ -0,0 +1,3 @@
|
||||
flask==1.1.2
|
||||
psutil==5.7.0
|
||||
sh==1.13.1
|
@ -0,0 +1,11 @@
|
||||
from flask.blueprints import Blueprint
|
||||
|
||||
from .stats import get_stats
|
||||
|
||||
api_bp = Blueprint('api', __name__)
|
||||
|
||||
|
||||
@api_bp.route("/stats")
|
||||
def stats():
|
||||
"""Returns resource utilization statistics similar to `top`"""
|
||||
return get_stats()
|
@ -0,0 +1,51 @@
|
||||
"""
|
||||
Module contains all logic for retrieving CPU, Memory, and Disk stats.
|
||||
"""
|
||||
import psutil
|
||||
import datetime as dt
|
||||
|
||||
from typing import Dict, Any
|
||||
|
||||
STATIC_STATS = {"cpu_count": psutil.cpu_count(logical=True),
|
||||
"boot_time": dt.datetime.fromtimestamp(psutil.boot_time())}
|
||||
|
||||
|
||||
def get_stats() -> Dict[str, Any]:
|
||||
"""Main entrypoint for retrieving system stats."""
|
||||
load_avg = [round(x / psutil.cpu_count(logical=True) * 100, 2) for x in psutil.getloadavg()]
|
||||
mem = psutil.virtual_memory()
|
||||
disk = psutil.disk_usage('/')
|
||||
stats = {'load_avg': load_avg,
|
||||
'mem': {
|
||||
'total': mem.total,
|
||||
'used': mem.used,
|
||||
'free': mem.free,
|
||||
'shared': mem.shared if hasattr(mem, 'shared') else None,
|
||||
'buffers': mem.buffers if hasattr(mem, 'buffers') else None,
|
||||
'cached': mem.cached if hasattr(mem, 'cached') else None,
|
||||
'available': mem.available,
|
||||
'percent': mem.percent,
|
||||
},
|
||||
'tasks': _get_tasks(),
|
||||
}
|
||||
stats.update(STATIC_STATS)
|
||||
return stats
|
||||
|
||||
|
||||
def _get_tasks() -> Dict[str, int]:
|
||||
"""Retrieves a dictionary of task information."""
|
||||
tasks = {
|
||||
'total': 0,
|
||||
'running': 0,
|
||||
'sleeping': 0,
|
||||
}
|
||||
|
||||
for p in psutil.process_iter():
|
||||
with p.oneshot():
|
||||
if p.status() == psutil.STATUS_RUNNING:
|
||||
tasks['running'] += 1
|
||||
if p.status() == psutil.STATUS_SLEEPING:
|
||||
tasks['sleeping'] += 1
|
||||
tasks['total'] += 1
|
||||
|
||||
return tasks
|
@ -0,0 +1,8 @@
|
||||
from flask.app import Flask
|
||||
from api.api import api_bp
|
||||
from client.client import client_bp
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True
|
||||
app.register_blueprint(api_bp, url_prefix='/api_v1')
|
||||
app.register_blueprint(client_bp)
|
@ -0,0 +1,13 @@
|
||||
from flask.blueprints import Blueprint
|
||||
from flask.templating import render_template
|
||||
|
||||
client_bp = Blueprint('client', __name__,
|
||||
template_folder='templates',
|
||||
static_folder='static',
|
||||
static_url_path='/client/static'
|
||||
)
|
||||
|
||||
|
||||
@client_bp.route('/')
|
||||
def index():
|
||||
return render_template('base.html')
|
@ -0,0 +1,15 @@
|
||||
const apiEndpoint = '/api_v1/';
|
||||
|
||||
const vm = new Vue({
|
||||
el: '#vm',
|
||||
delimiters: ['[[', ']]'],
|
||||
data: {
|
||||
greeting: 'Hello Vue!',
|
||||
flaskStats: {}
|
||||
},
|
||||
created: async function(){
|
||||
const gResponse = await fetch(apiEndpoint + 'stats');
|
||||
const glObject = await gResponse.json()
|
||||
this.flaskStats = glObject
|
||||
}
|
||||
})
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>Pupper ctl</title>
|
||||
<link rel="stylesheet" href="{{ url_for('client.static', filename='vendor/tailwind.min.css') }}">
|
||||
<script src="{{ url_for('client.static', filename='vendor/vue.min.js') }}"></script>
|
||||
</head>
|
||||
<body class="font-sans">
|
||||
<noscript>
|
||||
<strong>We're sorry but real-world-vue doesn't work properly without JavaScript enabled. Please enable it to
|
||||
continue.</strong>
|
||||
</noscript>
|
||||
<h1 class="text-6xl">Pupperctl</h1>
|
||||
<div id="vm">
|
||||
<p>[[ greeting ]]</p>
|
||||
<p>[[ flaskStats.load_avg ]]</p>
|
||||
</div>
|
||||
<script src="{{ url_for('client.static', filename='app.js') }}" ></script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue