mirror of
https://github.com/moan0s/alertbot.git
synced 2024-10-01 06:25:35 -04:00
Add grafana to supported solutions, add helpstring
This commit is contained in:
parent
678fb11ed2
commit
ae082066d9
@ -2,7 +2,7 @@
|
||||
|
||||
**Prerequisites:**
|
||||
* A maubot instance: Please [refer to the docs](https://docs.mau.fi/maubot/usage/setup/index.html) for setting up one
|
||||
* An instance of alertmanager
|
||||
* An instance of alertmanager or grafana or a similar alerting program that is able to send webhooks
|
||||
|
||||
**Getting the code**
|
||||
|
||||
@ -74,3 +74,10 @@ curl --header "Content-Type: application/json" \
|
||||
--data "@data.json" \
|
||||
https://webhook.hyteck.de/_matrix/maubot/plugin/maubot/webhook
|
||||
```
|
||||
|
||||
|
||||
# Grafana setup
|
||||
|
||||
The grafana setup is fairly simple and can be used to forward grafana alerts to matrix.
|
||||
|
||||
![Screenshot of the Grafana Setup](grafana.png)
|
82
alertbot.py
82
alertbot.py
@ -2,47 +2,109 @@ from maubot import Plugin, MessageEvent
|
||||
from maubot.handlers import web, command
|
||||
from aiohttp.web import Request, Response, json_response
|
||||
import json
|
||||
import datetime
|
||||
|
||||
helpstring = f"""# Alertbot
|
||||
|
||||
To control the alertbot you can use the following commands:
|
||||
* `!help`: To show this help
|
||||
* `!ping`: To check if the bot is alive
|
||||
* `!raw`: To toggle raw mode (where webhook data is not parsed but simply forwarded as copyable text)
|
||||
* `!roomid`: To let the bot show you the current matrix room id
|
||||
* `!url`: To let the bot show you the webhook url
|
||||
|
||||
More information is on [Github](https://github.com/moan0s/alertbot)
|
||||
"""
|
||||
|
||||
|
||||
def get_alert_messages(alertmanager_data: dict) -> list:
|
||||
def get_alert_messages(alertmanager_data: dict, raw_mode=False) -> list:
|
||||
"""
|
||||
Returns a list of messages in markdown format
|
||||
|
||||
:param raw_mode: Toggles a mode where the data is not parsed but simply returned as code block in a message
|
||||
:param alertmanager_data:
|
||||
:return: List of alert messages in markdown format
|
||||
"""
|
||||
if raw_mode:
|
||||
return ["**Data received**\n```\n" + str(alertmanager_data).strip("\n").strip() + "\n```"]
|
||||
messages = []
|
||||
""" try:
|
||||
# Check if grafana alert/resolved
|
||||
if alertmanager_data['alerts']:
|
||||
messages.append(grafana_alert_to_markdown(alertmanager_data))
|
||||
|
||||
except KeyError:
|
||||
"""
|
||||
for alert in alertmanager_data["alerts"]:
|
||||
messages.append(alert_to_markdown(alert))
|
||||
return messages
|
||||
|
||||
|
||||
def alert_to_markdown(alert: dict) -> str:
|
||||
if alert["fingerprint"]:
|
||||
return grafana_alert_to_markdown(alert)
|
||||
else:
|
||||
return prometheus_alert_to_markdown(alert)
|
||||
|
||||
|
||||
def grafana_alert_to_markdown(alert: dict) -> str:
|
||||
"""
|
||||
Converst a alert json to markdown
|
||||
Converts a grafana alert json to markdown
|
||||
|
||||
:param alert:
|
||||
:return: Alert as fomatted markdown
|
||||
"""
|
||||
datetime_format = "%Y-%m-%dT%H:%M:%S%z"
|
||||
if alert['status'] == "firing":
|
||||
message = (
|
||||
f"""**Firing 🔥**: {alert['labels']['alertname']}
|
||||
|
||||
* **Instance:** {alert["valueString"]}
|
||||
* **Silence:** {alert["silenceURL"]}
|
||||
* **Started at:** {alert['startsAt']}
|
||||
* **Fingerprint:** {alert['fingerprint']}
|
||||
"""
|
||||
)
|
||||
if alert['status'] == "resolved":
|
||||
end_at = datetime.datetime.strptime(alert['endsAt'], datetime_format)
|
||||
start_at = datetime.datetime.strptime(alert['startsAt'], datetime_format)
|
||||
message = (
|
||||
f"""**Resolved 🥳**: {alert['labels']['alertname']}
|
||||
|
||||
* **Duration until resolved:** {end_at - start_at}
|
||||
* **Fingerprint:** {alert['fingerprint']}
|
||||
"""
|
||||
)
|
||||
return message
|
||||
|
||||
|
||||
def prometheus_alert_to_markdown(alert: dict) -> str:
|
||||
"""
|
||||
Converts a prometheus alert json to markdown
|
||||
|
||||
:param alert:
|
||||
:return: Alert as fomatted markdown
|
||||
"""
|
||||
|
||||
message = (
|
||||
f"""**{alert['status']}**: {alert['annotations']['description']}
|
||||
|
||||
* **Alertname:** {alert["labels"]['alertname']}
|
||||
* **Instance:** {alert["labels"]['instance']}
|
||||
* **Job:** {alert["labels"]['job']}
|
||||
"""
|
||||
"""
|
||||
)
|
||||
return message
|
||||
|
||||
|
||||
|
||||
class AlertBot(Plugin):
|
||||
raw_mode = False
|
||||
|
||||
async def send_alert(self, req, room):
|
||||
text = await req.text()
|
||||
self.log.info(text)
|
||||
content = json.loads(f"{text}")
|
||||
for message in get_alert_messages(content):
|
||||
for message in get_alert_messages(content, self.raw_mode):
|
||||
self.log.debug(f"Sending alert to {room}")
|
||||
await self.client.send_markdown(room, message)
|
||||
|
||||
@ -66,3 +128,13 @@ class AlertBot(Plugin):
|
||||
async def url(self, evt: MessageEvent) -> None:
|
||||
"""Answers with the url of the webhook"""
|
||||
await evt.reply(f"`{self.webapp_url}/webhook`")
|
||||
|
||||
@command.new()
|
||||
async def raw(self, evt: MessageEvent) -> None:
|
||||
self.raw_mode = not self.raw_mode
|
||||
"""Switches the bot to raw mode or disables raw mode (mode where data is not formatted but simply forwarded)"""
|
||||
await evt.reply(f"Mode is now: `{'raw' if self.raw_mode else 'normal'} mode`")
|
||||
|
||||
@command.new()
|
||||
async def help(self, evt: MessageEvent) -> None:
|
||||
await self.client.send_markdown(evt.room_id, helpstring)
|
||||
|
Loading…
Reference in New Issue
Block a user