Annotationen im Grafana über die HTTP/MQTT API

This topic will contain a table of contents

@karsten und @mhies fragten:

Wie weit ist das eigentlich mit den Annotations gediehen? Gibts da eine rudimentäre Möglichkeit, Eingriffe zu dokumentieren?

Ja, die gibt es definitiv. Du kannst einen Zeitstempel hinterlassen und an diesen auch (eher etwas knappes) dran schreiben. @Andreas hatte dieses Feature im letzten großen Release für uns erschlossen. Das ist in der Kotori Doku beschrieben, man kann Annotations sowohl via HTTP als auch via MQTT setzen.

Feldnamen

While arbitrary fields can be submitted, Grafana evaluates the fields title, text and tags. It is possible to use HTML inside the text field, for example to link this event to another web application.

Es würde sich also anbieten, dort einen Link zu hinterlegen in dem dann das Event detailierter beschrieben ist.

Beispiel

http POST https://swarm.hiveeyes.org/api/hiveeyes/testdrive/area-42/node-1/event title='Some event' text='<a href="https://somewhere.example.org/events?reference=482a38ce-791e-11e6-b152-7cd1c55000be">see also</a>' tags='event,alert,important' reference='482a38ce-791e-11e6-b152-7cd1c55000be'

Nach POST kommt die URL zum Server in welchem auch der Pfad zu dem Datensatz beschrieben ist, vgl. die Beispiele in der Doku.

hiveeyes:  Realm. Bei uns meist `hiveeyes`.
testdrive: Eigentümer (Imker)
area-42:   Location (Standort)
node-1:    Node (Beute)

Erläuterung

Durch den Endpoint /event weiß Kotori, dass die folgenden Daten als Annotation behandelt werden müssen. Diese wird dann spezifiziert durch den Titel der Annotation title= und die tags (als Komma separierte Liste) tags= die später im Grafana durchsuchbar sind. Der eigentliche Inhalt wird in dem Feld text= hinterlegt.
In dem obigen Beispiel hätten wir dort einen Link nach https://somewhere.example.org/events?refer ... der sich hinter see also verstecken würde.

Ein wichtiges Feature gerade bei der manuellen Eingabe ermöglicht das Feld time= durch welches Annotations auch retrospektiv gesetzt werden können. Rechtshändisch kann time= in verschiedenen Formaten beschrieben werden.

@einsiedlerkrebs: Vielen Dank für die ausführliche Beschreibung!

Hier gibt es ein kleines Beispiel mit Annotationen zu sehen, die über die oben beschriebene API gesetzt wurden.

Python MQTT Beispiel

… ein kleines Python Beispiel aufgrund einer Frage, wie man das MQTT Topic am besten universell berechnet, ohne die entsprechenden Adressinformationen redundant kodieren zu müssen:

# Compute MQTT bus topics (data vs. event)

mqtt_topic_template = u'{realm}/{network}/{gateway}/{node}/{kind}.json'
mqtt_address = dict(
    realm   = 'hiveeyes',
    network = 'c0b2ba47-cad8-4cb3-94b5-abf72d971b73',     # Imker
    gateway = 'test-42',                                  # Standort
    node    = 'node-1'                                    # Bienenstock
)

mqtt_data_topic  = mqtt_topic_template.format(kind='data', **mqtt_address)
mqtt_event_topic = mqtt_topic_template.format(kind='event', **mqtt_address)

Wunderbar, das hat geklappt - vielen Dank! Siehe:

ich versuche gerade manuell eine anmerkung zu setzen, finde mich aber nicht zurecht. wo kann ich dann da ‘time=…’ eingeben?
ich sehe nur
name | datasource | colour
und dann je nach gewählter datasource:
query
column mappings:
title | tags | text
oder:
filters:
type | max limit

hab mich auch nochmal versucht, an der anleitung zu orientieren, dort geht es aber nach dem hinweis auf den ‘add new’-button auch nicht weiter…

Hi @mois,

Grafana ermöglicht es noch nicht, interaktiv Annotationen zu setzen. Es ist aber in Planung, wenn man will kann man hier dafür abstimmen:

Auch wir haben leider noch kein alternatives User Interface dazu. Die Beschreibung von @einsiedlerkrebs bezieht sich auf die API, mit der Markus Hies bereits erfolgreich Annotations gesetzt hat. Das klappt sowohl per MQTT als auch via HTTP, je nachdem was Dir lieber ist. Du findest das komplette Beispiel “set-mqtt-annotation.py” von Markus Hies unter

via:

… hier der relevante Auszug davon, wie Du das Feld "time=" manuell setzen kannst:

event = {
    "time": "2017-03-04T16:48:00Z",
    "title": "Futterwabe",
    "text" : "zusaetzliche Futterwabe von Hubert 2kg",
    "tags" : "event,Fuetterung,muc,mh"
}

Bitte beachte, dass in diesem Beispiel mit dem Suffix “Z” die Zeitzone UTC gemeint ist. Andere Möglichkeiten findest Du in der Dokumentation der möglichen Zeitstempelformate. Wenn Du Zeitstempel in der aktuellen Zeitzone von “Europe/Berlin” senden willst, benutze einfach “2016-12-07T18:30:15” oder expliziter “2016-12-07T18:30:15+0100” im Winter bzw. “2017-06-07T18:30:15+0200” zur Sommerzeit (DST).

Viele Grüße,
Andreas.

Um das nochmal präziser zu machen: Diese Anleitung von Grafana bezieht sich darauf, wie man das Dashboard entsprechend konfiguriert, dass Annotations angezeigt werden können:

Click the Add tab to add a new annotation query.

Die entsprechenden Einstellungen werden beim Anlegen des Dashboards durch unser Backend jedoch bereits automatisch vorgenommen, so dass man sich als Endanwender nicht mehr darum kümmern muss.

ok. ich verstehe. hab also httpie installiert und versuche mich jetzt mit entsprechenden requests:

mois@weidenteich ~ $ http POST http://swarm.hiveeyes.org/api/mqttkit-1/27041c2a-8afd-4a1e-b3ae-44233fa1f06b/mois/yun/event title='Sonne' text='Die Sonne kommt um die Ecke. <b>juhu!</b>' tags='test' reference='27041c2a-8afd-4a1e-b3ae-44233fa1f06b' time='2017-03-15T15:51:00'

mois@weidenteich ~ $ http POST http://swarm.hiveeyes.org/api/mqttkit-1/testdrive/area-42/node-1/event title='Sonne' text='Die Sonne kommt um die Ecke. <b>juhu!</b>' tags='test' reference='27041c2a-8afd-4a1e-b3ae-44233fa1f06b' time='2017-03-15T15:51:00'

mois@weidenteich ~ $ http POST http://swarm.hiveeyes.org/api/mqttkit-1/testdrive/mois/yun/event title='Sonne' text='Die Sonne kommt um die Ecke. <b>juhu!</b>' tags='test' reference='27041c2a-8afd-4a1e-b3ae-44233fa1f06b' time='2017-03-15T15:51:00'

kriege immer:

HTTP/1.1 404 Not Found
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html
Date: Thu, 16 Mar 2017 00:09:01 GMT
Server: nginx/1.6.2
Transfer-Encoding: chunked

<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.6.2</center>
</body>
</html>

ich nehme an, ich habe noch nicht ganz verstanden, wie ich die url zusammenbauen muss. oder?

Hallo Markus,

Richtig, mit der folgenden kleinen Transferleistung klappts:

  1. https statt http!
  2. realm “hiveeyes” statt “mqttkit-1”

Für die Tests im Trockendock nicht vergessen, vorher sicherheitshalber ein zwei Datenpunkte an den entsprechenden Kanal zu schicken, damit das Dashboard entsprechend angelegt und die Ereignisquelle darin verdrahtet wird.

Viele Grüße,
Andreas.

ja, vielen dank. das “s” wars vor allen dingen. wärs nicht so spät, hätt ichs vielleicht hingekriegt mit dem transfer, denn das ur-posting von @einsiedlerkrebs macht’s eigentlich sehr klar, auch für http…

Das funktionierte scheinbar bereits, gratuliere!

ja, war ja nur ein bisschen die linkspfelitaste gedrückt halten und dann ein “s” ;-)
vielsten dank und gute nacht!

habe die Beispielzeile nochmal überarbeitet. Das war alles nur theoretisch zusammgefasst, daher danke @mois fürs praktische testen!

A post was split to a new topic: Ereignisse interaktiv im Grafana annotieren

Welche Schnittstelle nutzen wir in der Zukunft?

Wir haben ja jetzt die beiden Möglichkeiten annotations über den

erzeugen.

Wenn ich es richtig gesehen habe erscheinen die annotations via Kotori auf allen Panels eines Dashboards während zumindest die interaktiv erzeugten nur im Panel angezeigt werden von dem sie aus erzeugt wurden.

Welche Methode sollen wir zukünftig nutzen? Landen beide Wege in der gleichen Datenbank?

Wie würde der native HTTP-Aufruf über die Kommandozeile mt einem json-Objekt ausschauen, s.: Annotations HTTP API  | Grafana Documentation

Hintergrund: Ich würde gerne die Phänologie-Daten eines Standorts exemplarisch in ein Grafana-Panel schreiben.

1 Like

Ich habe es jetzt mal mit der “alten” API über so was versucht

http POST https://swarm.hiveeyes.org/api/hiveeyes/phenodata/berlin/dahlem/event title='Schneeglöckchen' text='Blüte Beginn' tags='phenodata,berlin,dahlem,schneeglöckchen,blüte beginn' time='2018-02-17T00:00:00 CET'
http POST https://swarm.hiveeyes.org/api/hiveeyes/phenodata/berlin/dahlem/event title='Hasel' text='Blüte Beginn' tags='phenodata,berlin,dahlem,hasel,blüte beginn' time='2018-02-19T00:00:00 CET'
http POST https://swarm.hiveeyes.org/api/hiveeyes/phenodata/berlin/dahlem/event title='Kornelkirsche' text='Blüte Beginn' tags='phenodata,berlin,dahlem,kornelkirsche,blüte beginn' time='2018-03-06T00:00:00 CET'
http POST https://swarm.hiveeyes.org/api/hiveeyes/phenodata/berlin/dahlem/event title='Huflattich' text='Blüte Beginn' tags='phenodata,berlin,dahlem,huflattich,blüte beginn' time='2018-03-10T00:00:00 CET'
http POST https://swarm.hiveeyes.org/api/hiveeyes/phenodata/berlin/dahlem/event title='Forsythie' text='Blüte Beginn' tags='phenodata,berlin,dahlem,forsythie,blüte beginn' time='2018-03-27T00:00:00 CET'
http POST https://swarm.hiveeyes.org/api/hiveeyes/phenodata/berlin/dahlem/event title='Winterraps' text='Längenwachstum Beginn' tags='phenodata,berlin,dahlem,winterraps,längenwachstum beginn' time='2018-03-28T00:00:00 CET'
http POST https://swarm.hiveeyes.org/api/hiveeyes/phenodata/berlin/dahlem/event title='Schlehe' text='Blüte Beginn' tags='phenodata,berlin,dahlem,schlehe,blüte beginn' time='2018-03-29T00:00:00 CET'
http POST https://swarm.hiveeyes.org/api/hiveeyes/phenodata/berlin/dahlem/event title='Rosskastanie' text='Austrieb Beginn' tags='phenodata,berlin,dahlem,rosskastanie,austrieb beginn' time='2018-03-29T00:00:00 CET'
http POST https://swarm.hiveeyes.org/api/hiveeyes/phenodata/berlin/dahlem/event title='Sal-Weide' text='Blüte Beginn' tags='phenodata,berlin,dahlem,sal-weide,blüte beginn' time='2018-03-30T00:00:00 CET'
http POST https://swarm.hiveeyes.org/api/hiveeyes/phenodata/berlin/dahlem/event title='Stachelbeere' text='Austrieb Beginn' tags='phenodata,berlin,dahlem,stachelbeere,austrieb beginn' time='2018-03-30T00:00:00 CET'
http POST https://swarm.hiveeyes.org/api/hiveeyes/phenodata/berlin/dahlem/event title='Hänge-Birke' text='Austrieb Beginn' tags='phenodata,berlin,dahlem,hänge-birke,austrieb beginn' time='2018-03-31T00:00:00 CET'
http POST https://swarm.hiveeyes.org/api/hiveeyes/phenodata/berlin/dahlem/event title='Apfel, frühe Reife' text='Austrieb Beginn' tags='phenodata,berlin,dahlem,apfel, frühe reife,austrieb beginn' time='2018-04-01T00:00:00 CET'
http POST https://swarm.hiveeyes.org/api/hiveeyes/phenodata/berlin/dahlem/event title='Spitz-Ahorn' text='Blüte Beginn' tags='phenodata,berlin,dahlem,spitz-ahorn,blüte beginn' time='2018-04-02T00:00:00 CET'

Die Aufrufe habe ich mir mit den über phenodata erzeugten Listen und einer Excel-Datei gebastelt, kann man sicher auch nett mit Python scripten: :-)

add-annotations-berlin-dahlem-2018.xlsx (16.1 KB)

Edit: Hier muss man noch etwas nachbessern, der tag “Apfel, frühe Reife” wird wegen des Kommas in zwei tags geteilt, d.h. entweder “,” ersetzen oder maskieren. (to be done ;-)

Hier eine kleiner Einblick, es fehlen noch ein paar Events, da ich die Aufrufe zusammen in die Komandozeile kopiert haben und sich mein Rechner oder der Server etwas verschluckt hat.

https://swarm.hiveeyes.org/grafana/d/yjkf6okik/phenodata-berlin-dahlem

1 Like

Das ist leider nicht so, default ist keine annotation aktiviert:

Die dann tatsächlich einzurichten ist gar nicht so einfach, weil man erst mal rausfinden muss wie die Datenbank / “Tabelle” / Untergruppe genau benannt ist.

Weiter passen die Feldnamen nicht, im Demo-annotation dashboard gibt es drei Felder

während bei meiner neu erzeugten Datenbank nur zwei Felder erscheinen

Und die werden auch nicht korrekt zugeordnet

die Tags erscheinen da wo eigentlich der Titel hin soll …

Wenn es annotations gibt, die genau den gleichen timestamp haben

2018-03-29 Schlehe 
2018-03-29 Rosskastanie

ich habe beide mit time=‘2018-03-29T00:00:00 CET’ eingetragen - erscheint immer nur die zuletzt eingetragene. :-(

Klar, alle, die automatisch ‘on-boarded’ haben (z.B. alle “hiveeyes open-hive-* automatic”) haben (mindestens) einen Kanal namens Events default_1. Beim manuellen Anlegen eines dashboards, so wie Du das jetzt bestimmt gemacht hast, passiert das nicht.

1 Like