From ac82c2252b06ac802ada6020fac88e7fed008bb5 Mon Sep 17 00:00:00 2001
From: Jan David Mol <mol@astron.nl>
Date: Thu, 2 Jun 2022 17:08:16 +0200
Subject: [PATCH] Added SVG example

---
 docs/source/monitoring.rst      | 64 +++++++++++++++++++++++++++++++++
 grafana-central/lofar-svglib.js | 52 +++++++++++++++++++++++++++
 2 files changed, 116 insertions(+)
 create mode 100644 grafana-central/lofar-svglib.js

diff --git a/docs/source/monitoring.rst b/docs/source/monitoring.rst
index 5cd699f..a3cfb04 100644
--- a/docs/source/monitoring.rst
+++ b/docs/source/monitoring.rst
@@ -126,3 +126,67 @@ To add *colours* for each dot, we need to combine the position with the value of
 In which `HBAT_PWR_on_R` represents the power of an HBAT element, which we sum per tile over all elements using `sum by (host, x)`. The output of this, the first line, will determine the colour. The position is added by using `group_by`, which adds the critical `str_value` of the `HBAT_reference_geohash_R`. By using `+ on(...) (... * 0)`, we make sure the metric value is not influenced by the value of the geohash metric.
 
 The colour is configured in the *Data Layer* by setting `Marker Color` to `Value`, and configuring the `Thresholds` at the bottom for the actual colour to be used for each range of values.
+
+SVG Panels
+------------------------------------
+
+It is possible to display an SVG picture, and have areas of it highlight based on query results. We find the `ACE.SVG <https://grafana.com/grafana/plugins/aceiot-svg-panel/>`_ plugin to be useful.
+
+An example setup can be constructed as follows:
+
+* Add a query with the *Alerta UI* data source, with:
+
+  * Rename query to ``AlertaAlerts``,
+  * ``URL`` set to ``http://alerta-server:8080/api/alerts``,
+  * ``Rows/Root`` set to ``alerts``,
+  * Add ``Query Param``: key ``status`` value ``open`` (to filter out any closed alerts).
+
+* Add a query with the *Grafana API* data source, with:
+
+  * Rename query to ``GrafanaAlerts``,
+  * ``URL`` set to ``http://localhost:3000/api/alertmanager/grafana/api/v2/alerts``,
+  * ``Rows/Root`` set to ``alerts``.
+
+* Add a query with the *Prometheus* data source, with:
+
+  * Rename query to ``PrometheusData``,
+  * Query set to f.e. ``scrape_samples_scraped``.
+
+* Load an SVG, with at least 2 named regions,
+* Under ``SVG Mappings``, map these two regions to the names ``RegionA`` and ``RegionB``,
+* Put the content of `lofar-svglib.js <https://git.astron.nl/lofar2.0/operations-central-management/-/tree/main/grafana-central/lofar-svglib.js>`_ in ``User JS Init Code``.
+* Put the following code in ``User JS Render Code``::
+
+    // find the right data series
+    let series = data.series.find(
+      x => x.refId == "PrometheusData"
+        && x.fields[1].labels.device == "total"
+    )
+
+    // use the last value
+    let buffer = series.fields[1].values.buffer
+    let lastValue = buffer[buffer.length-1]
+
+    // colour RegionA accordingly
+    svgmap.RegionA.css('fill', lastValue > 1 ? '#f00' : '#0f0')
+
+    // link it to a fixed URL
+    svgmap.RegionA.linkTo(function(link) {
+      link.to('http://www.google.com').target('_blank')
+    })
+
+    // lookup an alert
+    alert = get_alert(data, "test")
+
+    // colour RegionB accordingly
+    svgmap.RegionB.css('fill', alert.colour)
+
+    // link it to the alert URL
+    if (alert.href) {
+      svgmap.RegionB.linkTo(function(link) {
+        link.to(alert.href).target('_blank')
+      })
+    }
+
+    console.log("refreshed")
+
diff --git a/grafana-central/lofar-svglib.js b/grafana-central/lofar-svglib.js
new file mode 100644
index 0000000..d1f71fd
--- /dev/null
+++ b/grafana-central/lofar-svglib.js
@@ -0,0 +1,52 @@
+// Lookup an alert in Grafana
+get_grafana_alert = (data, name) => {
+  series = data.series.find(
+    x => x.refId == "GrafanaAlerts"
+  )
+
+  return series.meta.custom.data.find(
+    x => x.labels.alertname == name
+  )
+}
+
+// Lookup an alert in Alerta
+get_alerta_alert = (data, name) => {
+  series = data.series.find(
+    x => x.refId == "AlertaAlerts"
+  )
+
+  return series.meta.custom.data.alerts.find(
+    x => x.event == name
+  )
+}
+
+// Return everything about an alert
+get_alert = (data, name) => {
+  let grafana_alert = get_grafana_alert(data, name)
+  let alerta_alert = get_alerta_alert(data, name)
+
+  if (alerta_alert) {
+    href = alerta_alert.href
+
+    if (grafana_alert)
+      colour = 'red'
+    else
+      colour = 'orange'
+  } else if (grafana_alert) {
+    // firing
+    colour = 'red'
+
+    href = '/alerting/grafana/'+ grafana_alert.labels.__alert_rule_uid__ +'/view'
+  } else {
+    colour = 'green'
+    href = undefined
+  }
+
+  return {
+    name: name,
+    alerta_alert: alerta_alert,
+    grafana_alert: grafana_alert,
+    colour: colour,
+    href: href
+  }
+}
-- 
GitLab