Mercurial > code > home > repos > front-door-lock
changeset 5:9eaa993ed373
monitoring
author | drewp@bigasterisk.com |
---|---|
date | Sun, 15 Oct 2023 18:47:45 -0700 |
parents | d0fa3638de2a |
children | f3786656cf4f |
files | front_door_lock.py src/MetricRow.ts src/main.ts |
diffstat | 3 files changed, 89 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/front_door_lock.py Sun Aug 27 13:18:36 2023 -0700 +++ b/front_door_lock.py Sun Oct 15 18:47:45 2023 -0700 @@ -31,7 +31,7 @@ from starlette.responses import JSONResponse from starlette.routing import Route from starlette_exporter import PrometheusMiddleware, handle_metrics - +from prometheus_client import Gauge from get_agent import getFoafAgent logging.basicConfig(level=logging.INFO) @@ -41,6 +41,8 @@ ctx = ROOM['frontDoorLockGraph'] lockUri = ROOM['frontDoorLock'] +MQTT_CONNECTED = Gauge('mqtt_connected', 'mqtt is connected') +HW_CONNECTED = Gauge('hw_connected', 'esp is connected') def output(graph: PatchableGraph, request: Request) -> JSONResponse: return JSONResponse({"demo": "hello"}) @@ -120,10 +122,14 @@ while True: try: async with self.client: + MQTT_CONNECTED.set(1) await self._handleMessages() except aiomqtt.MqttError: + MQTT_CONNECTED.set(0) log.error('mqtt reconnecting', exc_info=True) await asyncio.sleep(5) + finally: + MQTT_CONNECTED.set(0) async def _handleMessages(self): async with self.client.messages() as messages: @@ -140,6 +146,7 @@ def _stateFromMqtt(self, payload: str) -> URIRef: return { + '': ROOM['unknownState'], 'OFF': ROOM['locked'], 'ON': ROOM['unlocked'], }[payload] @@ -155,6 +162,7 @@ self.hw.writeHwLockStateToGraph(self._stateFromMqtt(payload)) case 'status': self.hw.setOnline(payload == 'online') + HW_CONNECTED.set(payload == 'online') case 'debug': log.info(f'hw debug: {payload}') # note: may include ansi colors case _:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/MetricRow.ts Sun Oct 15 18:47:45 2023 -0700 @@ -0,0 +1,67 @@ +import { LitElement, PropertyValueMap, css, html } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; + + +@customElement("metric-row") +export class MetricRow extends LitElement { + static styles = [ + css` + :host > div { + border: solid #eee; + border-width: 1px 0; + } + :host > div > span { + display: inline-block; + } + span.label { + width: 20em; + } + span.vmval { + width: 2em; + } + span.asof { + width: 15em; + } + .vmval { + font-weight: bold; + } + .asof { + color: gray; + } + `, + ]; + @property() label: string = "??"; + @property() q: string = ""; + @state() resultTime?: Date; + @state() resultValue?: string; + render() { + const graphUrl = new URL("https://bigasterisk.com/m/vmui/#/"); + + graphUrl.searchParams.append("g0.expr", this.q); + graphUrl.searchParams.append("g0.range_input", "6h"); + graphUrl.searchParams.append("g0.relative_time", "last_6_hours"); + return html`<div> + <span class='label'>${this.label}</span> + <span class="vmval"> ${this.resultValue || "..."} </span> + <span class="asof">${this.resultTime ? html`as of ${this.resultTime.toLocaleString("sv")}` : []}</span> + <span class='graph'><a href="${graphUrl.toString()}">[graph]</a> + </div>`; + } + + protected async update(changedProperties: PropertyValueMap<this>) { + if (changedProperties.has("q") && this.q) { + this.getMetricValue(this.q); + } + super.update(changedProperties); + } + + async getMetricValue(q: string) { + const vmapi = "https://bigasterisk.com/m/prometheus/api/v1"; + const queryUrl = new URL(vmapi + "/query"); + queryUrl.searchParams.append("query", q); + const resp = await (await fetch(queryUrl)).json(); + const v = resp.data.result[0].value; + this.resultTime = new Date(v[0] * 1000); + this.resultValue = v[1]; + } +}
--- a/src/main.ts Sun Aug 27 13:18:36 2023 -0700 +++ b/src/main.ts Sun Oct 15 18:47:45 2023 -0700 @@ -1,6 +1,7 @@ import { LitElement, TemplateResult, css, html } from "lit"; import { customElement, property } from "lit/decorators.js"; export { SgSource, SgView, StreamedGraph } from "@bigasterisk/streamed-graph"; +export { MetricRow } from "./MetricRow"; @customElement("fd-page") export class FdPage extends LitElement { @@ -48,8 +49,18 @@ <sg-view uri="#view"></sg-view> </streamed-graph> <p> - <a href="metrics">metrics</a> | - <a href="api/graph">graph</a> + <a href="metrics">metrics</a> | <a href="api/graph">graph</a> | + <a href="https://bigasterisk.com/k/clusters/local/namespaces/default/deployments/front-door-lock">deploy</a> | + <a href="https://bigasterisk.com/k/clusters/local/namespaces/default/deployments/front-door-lock/logs">logs</a> | + <a href="https://bigasterisk.com/vmalert/groups#group-14459482342649697182">alert group</a> + </p> + <p> + <metric-row label="reader esp32: mqtt connected " q='hw_connected{job="fingerprint"}'></metric-row> + <metric-row label="reader service: up " q='up{job="fingerprint"}'></metric-row> + <metric-row label="reader service: mqtt connected" q='mqtt_connected{job="fingerprint"}'></metric-row> + <metric-row label="Lock service (this page): up " q='up{job="front-door-lock"}'></metric-row> + <metric-row label="Lock service: mqtt connected " q='mqtt_connected{job="front-door-lock"}'></metric-row> + <metric-row label="Lock esp32: mqtt-connected " q='hw_connected{job="front-door-lock"}'></metric-row> </p> <bigast-loginbar></bigast-loginbar> `;