MQTT notifications for Grafana

@Andreas and me were talking about latest Grafana development. Grafana is bundled with Kotori and therefore Hiveeyes for almost 3 major versions. Some features seems to be developed just like we wish…

Anyhow, since some versions Grafana knows Alerting which rounds it up as a monitoring tool even for unattended use. It is very handy, to define a alerting while looking at the data (graph) and even have the threshold in sight. It is possible to cluster different queries into one alert.

As it is with alerting, a tool needs its notification sinks in order to let the user know about a alert. While Grafana already ships some long lasting or even modern sinks there will always be wishes about one or another.

One should not expect a graphing tool, to full fill all the favours one could have, like e.g. MQTTwarn. No. … Unless, Grafana would have mqtt as notification sink. This way a Grafana admin could provide the fill mqttwarn stack to it users.

Therefore, this page might collect some starting points where and roughly how, MQTT could be embedded into Grafana.

Grafanas alert services resting here
Since Go would be the language to go, Paho-client would again be the tool of choice.

This is the default example for a mqtt client written in Go

package main

import (
  //import the Paho Go MQTT library
  MQTT ""

//define a function for the default message handler
var f MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) {
  fmt.Printf("TOPIC: %s\n", msg.Topic())
  fmt.Printf("MSG: %s\n", msg.Payload())

func main() {
  //create a ClientOptions struct setting the broker address, clientid, turn
  //off trace output and set the default message handler
  opts := MQTT.NewClientOptions().AddBroker("tcp://")

  //create and start a client using the above ClientOptions
  c := MQTT.NewClient(opts)
  if token := c.Connect(); token.Wait() && token.Error() != nil {

  //subscribe to the topic /go-mqtt/sample and request messages to be delivered
  //at a maximum qos of zero, wait for the receipt to confirm the subscription
  if token := c.Subscribe("go-mqtt/sample", 0, nil); token.Wait() && token.Error() != nil {

  //Publish 5 messages to /go-mqtt/sample at qos 1 and wait for the receipt
  //from the server after sending each message
  for i := 0; i < 5; i++ {
    text := fmt.Sprintf("this is msg #%d!", i)
    token := c.Publish("go-mqtt/sample", 0, false, text)

  time.Sleep(3 * time.Second)

  //unsubscribe from /go-mqtt/sample
  if token := c.Unsubscribe("go-mqtt/sample"); token.Wait() && token.Error() != nil {


Grafanas base notifier could be a good starting point as well.

package notifiers

import (
	m ""

type NotifierBase struct {
	Name        string
	Type        string
	Id          int64
	IsDeault    bool
	UploadImage bool

func NewNotifierBase(id int64, isDefault bool, name, notifierType string, model *simplejson.Json) NotifierBase {
	uploadImage := model.Get("uploadImage").MustBool(true)

	return NotifierBase{
		Id:          id,
		Name:        name,
		IsDeault:    isDefault,
		Type:        notifierType,
		UploadImage: uploadImage,

func defaultShouldNotify(context *alerting.EvalContext) bool {
	if context.PrevAlertState == context.Rule.State {
		return false
	if (context.PrevAlertState == m.AlertStatePending) && (context.Rule.State == m.AlertStateOK) {
		return false
	return true

func (n *NotifierBase) GetType() string {
	return n.Type

func (n *NotifierBase) NeedsImage() bool {
	return n.UploadImage

func (n *NotifierBase) GetNotifierId() int64 {
	return n.Id

func (n *NotifierBase) GetIsDefault() bool {
	return n.IsDeault
1 Like

Here is a list of alerting services natively supported by Grafana:

Threema and Telegram as popular IM services are also supported. Unfortunately WhatsApp has not a real useful official API.

There are some nerdy beekeeper out there but SMS (uhhh, I know it’s anachronistic) will be a requirement for some “normal” beekeeper and in case it isn’t it will be WhatsApp. ;-)

While we can confirm this, this piece of FOSS looks promising until FB will add a native API: