changeset 2357:ccd04278e357

metrics cleanup
author drewp@bigasterisk.com
date Sat, 03 Jun 2023 17:15:40 -0700
parents 6394d7d71974
children 24664f7ae65e
files light9/collector/collector.py light9/collector/collector_client_asyncio.py light9/collector/service.py light9/effect/sequencer/eval_faders.py light9/effect/sequencer/sequencer.py light9/homepage/ServiceButtonRow.ts light9/homepage/StatsLine.ts
diffstat 7 files changed, 49 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/light9/collector/collector.py	Sat Jun 03 16:02:39 2023 -0700
+++ b/light9/collector/collector.py	Sat Jun 03 17:15:40 2023 -0700
@@ -3,6 +3,7 @@
 from typing import Dict, List, Set, Tuple, cast
 from light9.typedgraph import typedValue
 
+from prometheus_client import Summary
 from rdfdb.syncedgraph.syncedgraph import SyncedGraph
 from rdflib import URIRef
 
@@ -16,6 +17,7 @@
 
 log = logging.getLogger('collector')
 
+STAT_SETATTR = Summary('set_attr', 'setAttr calls')
 
 def makeDmxMessageIndex(base: DmxIndex, offset: DmxIndex) -> DmxMessageIndex:
     return DmxMessageIndex(base + offset - 1)
@@ -99,6 +101,7 @@
             end = typedValue(float, self.graph, remap, L9['end'])
             self.remapOut[(dev, attr)] = OutputRange((start, end))
 
+    @STAT_SETATTR.time()
     def setAttrs(self, client: ClientType, clientSession: ClientSessionType, settings: DeviceSettings, sendTime: UnixTime):
         """
         Given DeviceSettings, we resolve conflicting values,
--- a/light9/collector/collector_client_asyncio.py	Sat Jun 03 16:02:39 2023 -0700
+++ b/light9/collector/collector_client_asyncio.py	Sat Jun 03 17:15:40 2023 -0700
@@ -9,7 +9,7 @@
 
 log = logging.getLogger('coll_client')
 
-SESS = Summary('coll_client_new_session', 'aiohttp.ClientSession')
+ZMQ_SEND = Summary('zmq_send', 'calls')
 
 
 def toCollectorJson(client, session, settings: DeviceSettings) -> str:
@@ -30,6 +30,7 @@
         self.socket.connect('tcp://127.0.0.1:9203')  #todo: tie to :collectorZmq in graph
         # old version used: 'tcp://%s:%s' % (service.host, service.port)
 
+    @ZMQ_SEND.time()
     async def send(self, client: str, session: str, settings: DeviceSettings):
         msg = toCollectorJson(client, session, settings).encode('utf8')
         # log.info(f'zmq send {len(msg)}')
--- a/light9/collector/service.py	Sat Jun 03 16:02:39 2023 -0700
+++ b/light9/collector/service.py	Sat Jun 03 17:15:40 2023 -0700
@@ -20,7 +20,6 @@
 from light9.namespaces import L9
 from light9.run_local import log
 from light9.zmqtransport import parseJsonMessage
-from prometheus_client import Summary
 from rdfdb.syncedgraph.syncedgraph import SyncedGraph
 from starlette.applications import Starlette
 from starlette.endpoints import WebSocketEndpoint
@@ -34,7 +33,6 @@
 import zmq
 import zmq.asyncio
 
-STAT_SETATTR = Summary('set_attr', 'setAttr calls')
 
 # this is the rate sent to usb
 RATE = 20
@@ -65,15 +63,14 @@
 
 
 async def PutAttrs(collector: Collector, request):
-    with STAT_SETATTR.time():
-        try:
-            body = await request.body()
-        except ClientDisconnect:
-            log.warning("PUT /attrs request disconnected- ignoring")
-            return Response('', status_code=400)
-        client, clientSession, settings, sendTime = parseJsonMessage(collector.graph, body)
-        collector.setAttrs(client, clientSession, settings, sendTime)
-        return Response('', status_code=202)
+    try:
+        body = await request.body()
+    except ClientDisconnect:
+        log.warning("PUT /attrs request disconnected- ignoring")
+        return Response('', status_code=400)
+    client, clientSession, settings, sendTime = parseJsonMessage(collector.graph, body)
+    collector.setAttrs(client, clientSession, settings, sendTime)
+    return Response('', status_code=202)
 
 
 async def zmqListener(collector):
--- a/light9/effect/sequencer/eval_faders.py	Sat Jun 03 16:02:39 2023 -0700
+++ b/light9/effect/sequencer/eval_faders.py	Sat Jun 03 17:15:40 2023 -0700
@@ -18,8 +18,8 @@
 
 log = logging.getLogger('seq.fader')
 
-COMPILE = Summary('compile_graph_fader', '')
-COMPUTE_ALL_FADERS = Summary('compute_all_faders', '')
+COMPILE = Summary('compile_graph_fader', 'compile')
+COMPUTE_ALL_FADERS = Summary('compute_all_faders', 'compile')
 
 @dataclass
 class Fader:
--- a/light9/effect/sequencer/sequencer.py	Sat Jun 03 16:02:39 2023 -0700
+++ b/light9/effect/sequencer/sequencer.py	Sat Jun 03 17:15:40 2023 -0700
@@ -83,7 +83,6 @@
         self.graph.addHandler(self.compileGraph)
         #self.updateLoop()
 
-    @metrics('compile_graph').time()
     def compileGraph(self) -> None:
         """rebuild our data from the graph"""
         for song in self.graph.subjects(RDF.type, L9['Song']):
@@ -93,7 +92,6 @@
 
             self.graph.addHandler(compileSong)
 
-    @metrics('compile_song').time()
     def compileSong(self, song: Song) -> None:
         anyErrors = False
         self.notes[song] = []
@@ -131,7 +129,6 @@
                 await asyncio.sleep(delay)
                 continue
 
-    @metrics('update_call').time()
     async def update(self):
         with metrics('update_s0_getMusic').time():
             musicState = {'t':123.0,'song':'http://light9.bigasterisk.com/show/dance2019/song5'}#self.music.getLatest()
--- a/light9/homepage/ServiceButtonRow.ts	Sat Jun 03 16:02:39 2023 -0700
+++ b/light9/homepage/ServiceButtonRow.ts	Sat Jun 03 17:15:40 2023 -0700
@@ -24,6 +24,7 @@
         display: inline-block;
         margin-right: 3px;
         flex-grow: 1;
+        min-width: 9em;
       }
       .window {
       }
--- a/light9/homepage/StatsLine.ts	Sat Jun 03 16:02:39 2023 -0700
+++ b/light9/homepage/StatsLine.ts	Sat Jun 03 17:15:40 2023 -0700
@@ -58,6 +58,7 @@
                   setTimeout(reload, 1000);
                 })
                 .catch((err) => {
+                  log(`${this.name} failing`, err)
                   setTimeout(reload, 1000);
                 });
             } else {
@@ -73,13 +74,13 @@
     });
   }
   extractProcessStats(stats: Metrics) {
-    stats.forEach((row) => {
+    stats.forEach((row: Metric) => {
       if (row.name == "process_resident_memory_bytes") {
-        this.mem = parseFloat(row.metrics[0].value) / 1024 / 1024;
+        this.mem = parseFloat(row.metrics[0].value!) / 1024 / 1024;
       }
       if (row.name == "process_cpu_seconds_total") {
         const now = Date.now() / 1000;
-        const cpuSecondsTotal = parseFloat(row.metrics[0].value);
+        const cpuSecondsTotal = parseFloat(row.metrics[0].value!);
         this.cpu = (cpuSecondsTotal - this.prevCpuTotal) / (now - this.prevCpuNow);
         this.prevCpuTotal = cpuSecondsTotal;
         this.prevCpuNow = now;
@@ -106,6 +107,7 @@
       th {
         padding: 2px 4px;
         background: #2f2f2f;
+        text-align: left;
       }
       td {
         padding: 0;
@@ -204,11 +206,10 @@
     } else if (m.type == "UNTYPED") {
       return html`${v.value}`;
     } else if (m.type == "SUMMARY") {
-      log(v);
       if (!v.count) {
         return html`err: summary without count`;
       }
-      return html`c=${v.count} percall=${((v.count && v.sum ? v.sum / v.count : 0) * 1000).toPrecision(3)}ms`;
+      return html`n=${v.count} percall=${((v.count && v.sum ? v.sum / v.count : 0) * 1000).toPrecision(3)}ms`;
     } else {
       throw m.type;
     }
@@ -230,7 +231,7 @@
       if (delta > maxDelta) maxDelta = delta;
     }
     prev = 0;
-    const maxBarH = 60;
+    const maxBarH = 30;
     for (let level in b) {
       let count = parseFloat(b[level]);
       let delta = count - prev;
@@ -247,6 +248,24 @@
     return html`${firstLevel} ${lines} ${lastLevel}`;
   }
 
+  tightLabel(labs: { [key: string]: string }): string {
+    const d: { [key: string]: string } = {}
+    for (let k in labs) {
+      if (k == 'app_name') continue;
+      if (k == 'output') continue;
+      if (k=='status_code'&&labs[k]=="200") continue;
+      d[k] = labs[k]
+    }
+    const ret = JSON.stringify(d)
+    return ret == "{}" ? "" : ret
+  }
+  tightMetric(name: string): string {
+    return name
+    .replace('starlette', '⭐')
+    .replace("_request" ,"_req")
+    .replace("_duration" ,"_dur")
+    .replace('_seconds', '_s')
+  }
   render() {
     const now = Date.now() / 1000;
 
@@ -255,31 +274,31 @@
       <div>
         <table>
           ${displayedStats.map(
-            (row, rowNum) => html`
+      (row, rowNum) => html`
               <tr>
-                <th>${row.type.slice(0, 1)} ${row.name}</th>
+                <th>${this.tightMetric(row.name)}</th>
                 <td>
                   <table>
                     ${row.metrics.map(
-                      (v) => html`
+        (v) => html`
                         <tr>
-                          <td>${JSON.stringify(v.labels)}</td>
+                          <td>${this.tightLabel(v.labels)}</td>
                           <td>${this.valueDisplay(row, v)}</td>
                         </tr>
                       `
-                    )}
+      )}
                   </table>
                 </td>
                 ${rowNum == 0
-                  ? html`
+          ? html`
                       <td rowspan="${displayedStats.length}">
                         <stats-process id="proc" cpu="${this.cpu}" mem="${this.mem}"></stats-process>
                       </td>
                     `
-                  : ""}
+          : ""}
               </tr>
             `
-          )}
+    )}
         </table>
       </div>
     `;