Changeset - a745bee5c419
[Not reviewed]
default
0 8 1
Drew Perttula - 6 years ago 2019-06-06 09:31:36
drewp@bigasterisk.com
new process stats visualizers
Ignore-this: 8e47516baad0bfb9cd02a712571c5a5f
9 files changed with 123 insertions and 8 deletions:
0 comments (0 inline, 0 general)
bin/ascoltami2
Show inline comments
 
@@ -8,15 +8,17 @@ gi.require_version('Gst', '1.0')
 
gi.require_version('Gtk', '3.0')
 

	
 
from light9.ascoltami.player import Player
 
from light9.ascoltami.playlist import Playlist, NoSuchSong
 
from light9.ascoltami.webapp import makeWebApp, songUri, songLocation
 
from light9 import networking, showconfig
 
from standardservice.scalessetup import gatherProcessStats
 

	
 
from gi.repository import GObject, Gst
 

	
 
gatherProcessStats()
 

	
 
class App(object):
 

	
 
    def __init__(self, graph, show):
 
        self.graph = graph
 
        self.player = Player(onEOS=self.onEOS)
bin/collector
Show inline comments
 
@@ -22,12 +22,13 @@ from light9 import networking
 
from light9.collector.collector import Collector
 
from light9.collector.weblisteners import WebListeners
 
from greplin.scales.cyclonehandler import StatsHandler
 
from light9.namespaces import L9
 
from light9.zmqtransport import parseJsonMessage, startZmq
 
from rdfdb.syncedgraph import SyncedGraph
 
from standardservice.scalessetup import gatherProcessStats
 

	
 
from light9.collector.output import Udmx, DummyOutput  # noqa
 

	
 

	
 
class Updates(cyclone.websocket.WebSocketHandler):
 

	
 
@@ -39,12 +40,13 @@ class Updates(cyclone.websocket.WebSocke
 
        self.settings.listeners.delClient(self)
 

	
 
    def messageReceived(self, message):
 
        json.loads(message)
 

	
 

	
 
gatherProcessStats()
 
stats = scales.collection(
 
    '/webServer',
 
    scales.PmfStat('setAttr', recalcPeriod=1),
 
    scales.RecentFpsStat('setAttrFps'),
 
)
 

	
bin/effecteval
Show inline comments
 
@@ -13,16 +13,18 @@ from light9.effect.edit import getMusicS
 
from light9.effecteval.effectloop import makeEffectLoop
 
from greplin.scales.cyclonehandler import StatsHandler
 
from light9.namespaces import L9
 
from rdfdb.patch import Patch
 
from rdfdb.syncedgraph import SyncedGraph
 
from greplin import scales
 
from standardservice.scalessetup import gatherProcessStats
 

	
 
from cycloneerr import PrettyErrorHandler
 
from light9.coffee import StaticCoffee
 

	
 
gatherProcessStats()
 

	
 
class EffectEdit(PrettyErrorHandler, cyclone.web.RequestHandler):
 

	
 
    def get(self):
 
        self.set_header('Content-Type', 'text/html')
 
        self.write(open("light9/effecteval/effect.html").read())
bin/vidref
Show inline comments
 
@@ -27,19 +27,21 @@ import cyclone.web, cyclone.httpclient, 
 

	
 
from cycloneerr import PrettyErrorHandler
 
from light9 import networking, showconfig
 
from light9.newtypes import Song
 
from light9.vidref import videorecorder
 
from rdfdb.syncedgraph import SyncedGraph
 
from standardservice.scalessetup import gatherProcessStats
 

	
 
parser = optparse.OptionParser()
 
parser.add_option("-v", "--verbose", action="store_true", help="logging.DEBUG")
 
(options, args) = parser.parse_args()
 

	
 
log.setLevel(logging.DEBUG if options.verbose else logging.INFO)
 

	
 
gatherProcessStats()
 
stats = scales.collection(
 
    '/webServer',
 
    scales.RecentFpsStat('liveWebsocketFrameFps'),
 
    scales.IntStat('liveClients'),
 
)
 

	
light9/effect/sequencer.py
Show inline comments
 
@@ -17,18 +17,20 @@ from light9.ascoltami.musictime_client i
 
from light9.effect import effecteval
 
from light9.effect.settings import DeviceSettings
 
from light9.effect.simple_outputs import SimpleOutputs
 
from light9.namespaces import L9, RDF
 
from light9.newtypes import DeviceUri, DeviceAttr, NoteUri, Curve, Song
 
from rdfdb.syncedgraph import SyncedGraph
 
from standardservice.scalessetup import gatherProcessStats
 

	
 
from greplin import scales
 
import imp
 

	
 
log = logging.getLogger('sequencer')
 

	
 
gatherProcessStats()
 
updateStats = scales.collection(
 
    '/update/',
 
    scales.PmfStat('s0_getMusic', recalcPeriod=1),
 
    scales.PmfStat('s1_eval', recalcPeriod=1),
 
    scales.PmfStat('s2_sendToWeb', recalcPeriod=1),
 
    scales.PmfStat('s3_send', recalcPeriod=1),
light9/web/index.html
Show inline comments
 
@@ -6,12 +6,13 @@
 
    <script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
 
    <link rel="stylesheet" href="/style.css">
 
    <link rel="import" href="/lib/polymer/polymer.html">
 
  </head>
 
  <body>
 
      <script type="module"  src="stats-line.js"></script>
 
      <script type="module"  src="stats-process.js"></script>
 

	
 

	
 
     
 
    <dom-module id="service-button-row">
 
      <template>
 
        <style>
light9/web/stats-line.js
Show inline comments
 
@@ -17,19 +17,18 @@ class StatsLine extends LitElement {
 
    updated(changedProperties) {
 
        changedProperties.forEach((oldValue, propName) => {
 
            if (propName == 'name') {
 
                const reload = () => {
 
                    fetch(this.name + '/stats/?format=json').then((resp) => {
 
                        if (resp.ok) {
 
                    resp.json().then((msg) => {
 
                        
 
                        this.stats = msg;
 
                    setTimeout(reload, 1000);
 
                            resp.json().then((msg) => {
 
                                this.stats = msg;
 
                                setTimeout(reload, 1000);
 
                            });
 
                        }
 
                    });
 
                        }
 
                });
 
                }
 
                reload();
 
            }
 
        });
 
    }
 
    
 
@@ -75,16 +74,27 @@ class StatsLine extends LitElement {
 
            min-width: 6em;
 
        }
 
        `;
 
    }
 
    
 
    render() {
 
        const now = Date.now() / 1000;
 
        const table = (d, path) => {
 

	
 
            const cols = Object.keys(d);
 
            let cols = Object.keys(d);
 
            cols.sort();
 

	
 
            if (path.length == 0) {
 
                ['webServer', 'process'].forEach((earlyKey) => {
 
                    let i = cols.indexOf(earlyKey);
 
                    if (i != -1) {
 
                        cols = [earlyKey].concat(cols.slice(0, i), cols.slice(i + 1));
 
                    }
 
                });
 
            }
 
            
 
            const th = (col) =>  {
 
                return html`<th>${col}</th>`;
 
            };
 
            const td = (col)  => {
 
                const cell = d[col];
 
                return html`${drawLevel(cell, path.concat(col))}`;
 
@@ -127,13 +137,20 @@ class StatsLine extends LitElement {
 
                   <div>mean=${rounding(d.mean*1000, 3)}</div>
 
                   <div>sd=${rounding(d.stddev*1000, 3)}</div>
 
                   <div>99=${rounding(d['99percentile']*1000, 3)}</div>
 
                 `
 
            }, path));
 
        };
 
        const drawLevel = (d, path) => {           
 
        const drawLevel = (d, path) => {
 
            if (path.length == 1 && path[0] === 'process') {
 
                 const elem = this.shadowRoot.querySelector('#proc');
 
                if (elem) {
 
                    elem.data = d;
 
                }
 
                return html`<stats-process id="proc"></stats-process>`;
 
            }
 
            if (typeof d === 'object') {
 
                if (d instanceof TemplateResult) {
 
                    return html`<td class="val">${d}</td>`;
 
                } else if (d.count !== undefined && d.min !== undefined) {
 
                    return pmf(d, path);
 
                } else if (d.average !== undefined && d.recents !== undefined) {
light9/web/stats-process.js
Show inline comments
 
new file 100644
 
import { LitElement, TemplateResult, html, css } from '/node_modules/lit-element/lit-element.js';
 
import debug from '/lib/debug/debug-build-es6.js';
 
import { rounding }  from '/node_modules/significant-rounding/index.js';
 

	
 
const log = debug('process');
 

	
 
const remap = (x, lo, hi, outLo, outHi) => {
 
    return outLo + (outHi - outLo) * Math.max(0, Math.min(1, (x - lo) / (hi - lo)));
 
};
 

	
 
class StatsProcess extends LitElement {
 
    
 
    static get properties() {
 
        return {
 
            data: { type: Object },
 
        };
 
    }
 

	
 
    firstUpdated() {
 
        // inspired by https://codepen.io/qiruiyin/pen/qOopQx
 
        var context = this.shadowRoot.firstElementChild,
 
	    ctx = context.getContext('2d'),
 
	    w = 64,
 
	    h = 64,
 
	    revs = 0;   
 
	
 
	context.width = w;
 
	context.height = h;
 

	
 
        let prev = Date.now() / 1000;
 

	
 
        var animate = () => {
 
	    requestAnimationFrame( animate );
 

	
 
            const now = Date.now() / 1000;
 
            ctx.beginPath();
 
            // wrong type of fade- never goes to 0
 
            ctx.fillStyle = '#00000003';
 
            ctx.fillRect(0, 0, w, h);
 
            if (this.data.time < now - 2) {
 
                return;
 
            }
 
            const dt = now - prev;
 
            prev = now;
 

	
 
            const size = remap(this.data.memMb, /*in*/ 20, 600, /*out*/ 3, 30);
 
	    revs += dt * remap(this.data.cpuPercent, /*in*/ 0, 100, /*out*/ 4, 120);
 
            const rad  = remap(size, /*in*/ 3, 30, /*out*/ 14, 5);
 

	
 
	    var x = w/2 + rad * Math.cos(revs / 6.28),
 
		y = h/2 + rad * Math.sin(revs / 6.28);
 

	
 
	    ctx.save();
 
	    ctx.beginPath();
 
	    ctx.fillStyle = "hsl(194, 100%, 42%)";
 
	    ctx.arc(x, y, size, 0, 2*Math.PI);
 
	    ctx.fill();
 
	    ctx.restore();
 
	    
 
        };
 
        animate();
 
    }
 
    
 
    updated(changedProperties) {
 
        if (changedProperties.has('data')) {
 
            this.shadowRoot.firstElementChild.setAttribute('title', `cpu ${this.data.cpuPercent}% mem ${this.data.memMb}MB`);
 
        }
 
    }
 

	
 
    static get styles() {
 
        return css`
 
        :host {
 
           display: inline-block;
 
           width: 64px;
 
           height: 64px;
 
        }
 
        `;
 
    }
 
    
 
    render() {
 
        return html`<canvas></canvas>`;
 

	
 
    }
 
}
 
customElements.define('stats-process', StatsProcess);
 

	
requirements.txt
Show inline comments
 
@@ -42,6 +42,7 @@ git+http://github.com/drewp/scales.git@4
 
git+http://github.com/11craft/louie.git@f18bb71010c114eca9c6b88c96453340e3b39454#egg=louie
 
git+http://github.com/webpy/webpy.git@ace0f8954c28311004b33c7a513c6e40a3c02470#egg=web
 
https://github.com/drewp/cyclone/archive/python3.zip#egg=cyclone
 

	
 
cycloneerr==0.3.0
 
rdfdb==0.19.0
 
standardservice==0.6.0
0 comments (0 inline, 0 general)