Add webhook integrations, refactor
This commit is contained in:
parent
020a02ccb2
commit
bff422312c
|
@ -1,59 +0,0 @@
|
||||||
using System;
|
|
||||||
using Telegram.Bot;
|
|
||||||
using Telegram.Bot.Types.Enums;
|
|
||||||
using Telegram.Bot.Types.ReplyMarkups;
|
|
||||||
|
|
||||||
namespace Monithor.api {
|
|
||||||
public class Alerting {
|
|
||||||
public class TelegramTarget {
|
|
||||||
public TelegramTarget(TelegramBotClient client, string chatId, IMonitor monitor, string statusPageRoute, string displayName) {
|
|
||||||
_client = client;
|
|
||||||
_chatId = chatId;
|
|
||||||
Monitor = monitor;
|
|
||||||
_statusPageRoute = statusPageRoute;
|
|
||||||
_displayName = displayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly TelegramBotClient _client;
|
|
||||||
private readonly string _chatId;
|
|
||||||
public readonly IMonitor Monitor;
|
|
||||||
private readonly string _statusPageRoute;
|
|
||||||
private readonly string _displayName;
|
|
||||||
|
|
||||||
public async void SendMessage() {
|
|
||||||
var statusPageBtn = new InlineKeyboardMarkup(InlineKeyboardButton.WithUrl("Open status page", $"https://{_statusPageRoute}"));
|
|
||||||
var message = GetMessage(Monitor, _displayName);
|
|
||||||
try {
|
|
||||||
await _client.SendTextMessageAsync(_chatId, message, ParseMode.Default, replyMarkup: statusPageBtn);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
Console.WriteLine(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetMessage(IMonitor mon, string displayName) {
|
|
||||||
return mon.Status switch {
|
|
||||||
MonitorStatus.Up => $"🟢 {displayName} is UP.\n" + $"Outage duration: {mon.ResolvedAt.Subtract(mon.StartedAt).ToStringCustom()}",
|
|
||||||
|
|
||||||
MonitorStatus.Recovering => $"🟡 {displayName} is recovering.",
|
|
||||||
MonitorStatus.Down => $"🔴 {displayName} is DOWN.\n" + $"Cause: {mon.LastValue}\n" + $"Outage started {mon.StartedAt:yyyy'-'MM'-'dd HH':'mm':'ss %K}",
|
|
||||||
MonitorStatus.Unknown => null,
|
|
||||||
MonitorStatus.Validating => null,
|
|
||||||
_ => null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class TimeSpanExtensions {
|
|
||||||
public static string ToStringCustom(this TimeSpan timeSpan) {
|
|
||||||
var retstr = $"{timeSpan.Seconds}s";
|
|
||||||
if (timeSpan.Minutes > 0)
|
|
||||||
retstr = $"{timeSpan.Minutes}m {retstr}";
|
|
||||||
if (Math.Floor(timeSpan.TotalHours) > 0)
|
|
||||||
retstr = $"{Math.Floor(timeSpan.TotalHours)}h {retstr}";
|
|
||||||
|
|
||||||
return retstr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
29
Monithor.api/Alerting/General.cs
Normal file
29
Monithor.api/Alerting/General.cs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Monithor.api.Alerting {
|
||||||
|
public static class General {
|
||||||
|
internal static string GetMessage(IMonitor mon, string displayName) {
|
||||||
|
return mon.Status switch {
|
||||||
|
MonitorStatus.Up => $"🟢 {displayName} is UP.\n" + $"Outage duration: {mon.ResolvedAt.Subtract(mon.StartedAt).ToStringCustom()}",
|
||||||
|
|
||||||
|
MonitorStatus.Recovering => $"🟡 {displayName} is recovering.",
|
||||||
|
MonitorStatus.Down => $"🔴 {displayName} is DOWN.\n" + $"Cause: {mon.LastValue}\n" + $"Outage started {mon.StartedAt:yyyy'-'MM'-'dd HH':'mm':'ss %K}",
|
||||||
|
MonitorStatus.Unknown => null,
|
||||||
|
MonitorStatus.Validating => null,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TimeSpanExtensions {
|
||||||
|
public static string ToStringCustom(this TimeSpan timeSpan) {
|
||||||
|
var retstr = $"{timeSpan.Seconds}s";
|
||||||
|
if (timeSpan.Minutes > 0)
|
||||||
|
retstr = $"{timeSpan.Minutes}m {retstr}";
|
||||||
|
if (Math.Floor(timeSpan.TotalHours) > 0)
|
||||||
|
retstr = $"{Math.Floor(timeSpan.TotalHours)}h {retstr}";
|
||||||
|
|
||||||
|
return retstr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
Monithor.api/Alerting/ITarget.cs
Normal file
6
Monithor.api/Alerting/ITarget.cs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
namespace Monithor.api.Alerting {
|
||||||
|
public interface ITarget {
|
||||||
|
public void SendMessage();
|
||||||
|
public IMonitor Monitor { get; set; }
|
||||||
|
}
|
||||||
|
}
|
34
Monithor.api/Alerting/MattermostWebhookTarget.cs
Normal file
34
Monithor.api/Alerting/MattermostWebhookTarget.cs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types.Enums;
|
||||||
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
|
|
||||||
|
namespace Monithor.api.Alerting {
|
||||||
|
public class MattermostWebhookTarget : ITarget {
|
||||||
|
public MattermostWebhookTarget(string url, IMonitor monitor, string displayName, string username = "monithor-alerting", string channel = "") {
|
||||||
|
_url = url;
|
||||||
|
_channel = channel;
|
||||||
|
_username = username;
|
||||||
|
Monitor = monitor;
|
||||||
|
_displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly string _url;
|
||||||
|
private readonly string _channel;
|
||||||
|
private readonly string _username;
|
||||||
|
public IMonitor Monitor { get; set; }
|
||||||
|
private readonly string _displayName;
|
||||||
|
|
||||||
|
public void SendMessage() {
|
||||||
|
var message = General.GetMessage(Monitor, _displayName);
|
||||||
|
var json = $"{{ \"channel\": \"{_channel}\", \"username\": \"{_username}\", \"text\": \"{message}\" }}".Replace("\n", "\\n");;
|
||||||
|
try {
|
||||||
|
new WebClient().UploadString(_url, json);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Console.WriteLine(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
Monithor.api/Alerting/TelegramTarget.cs
Normal file
34
Monithor.api/Alerting/TelegramTarget.cs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types.Enums;
|
||||||
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
|
|
||||||
|
namespace Monithor.api.Alerting {
|
||||||
|
public class TelegramTarget : ITarget {
|
||||||
|
public TelegramTarget(TelegramBotClient client, string chatId, IMonitor monitor, string statusPageRoute, string displayName) {
|
||||||
|
_client = client;
|
||||||
|
_chatId = chatId;
|
||||||
|
Monitor = monitor;
|
||||||
|
_statusPageRoute = statusPageRoute;
|
||||||
|
_displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMonitor Monitor { get; set; }
|
||||||
|
|
||||||
|
private readonly TelegramBotClient _client;
|
||||||
|
private readonly string _chatId;
|
||||||
|
private readonly string _statusPageRoute;
|
||||||
|
private readonly string _displayName;
|
||||||
|
|
||||||
|
public async void SendMessage() {
|
||||||
|
var statusPageBtn = new InlineKeyboardMarkup(InlineKeyboardButton.WithUrl("Open status page", $"https://{_statusPageRoute}"));
|
||||||
|
var message = General.GetMessage(Monitor, _displayName);
|
||||||
|
try {
|
||||||
|
await _client.SendTextMessageAsync(_chatId, message, ParseMode.Default, replyMarkup: statusPageBtn);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Console.WriteLine(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
38
Monithor.api/Alerting/ZulipWebhookTarget.cs
Normal file
38
Monithor.api/Alerting/ZulipWebhookTarget.cs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types.Enums;
|
||||||
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
|
|
||||||
|
namespace Monithor.api.Alerting {
|
||||||
|
public class ZulipWebhookTarget : ITarget {
|
||||||
|
public ZulipWebhookTarget(string domain, string apikey, IMonitor monitor, string displayName, string stream, string topic = "monithor-alerting") {
|
||||||
|
_domain = domain;
|
||||||
|
_apikey = apikey;
|
||||||
|
_stream = stream;
|
||||||
|
_topic = topic;
|
||||||
|
Monitor = monitor;
|
||||||
|
_displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly string _domain;
|
||||||
|
private readonly string _apikey;
|
||||||
|
private readonly string _stream;
|
||||||
|
private readonly string _topic;
|
||||||
|
public IMonitor Monitor { get; set; }
|
||||||
|
private readonly string _displayName;
|
||||||
|
|
||||||
|
public void SendMessage() {
|
||||||
|
var message = General.GetMessage(Monitor, _displayName);
|
||||||
|
var json = $"{{ \"text\": \"{message}\" }}".Replace("\n", "\\n");
|
||||||
|
try {
|
||||||
|
var client = new WebClient();
|
||||||
|
client.Headers.Add("Content-Type", "application/json");
|
||||||
|
client.UploadString($"https://{_domain}/api/v1/external/slack_incoming?api_key={_apikey}&stream={_stream}&topic={_topic}", json);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Console.WriteLine(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ namespace Monithor.api {
|
||||||
new IcmpMonitor("placeholder-icmp", "host.your.domain"),
|
new IcmpMonitor("placeholder-icmp", "host.your.domain"),
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly List<Alerting.TelegramTarget> TelegramTargets = new() {
|
public static readonly List<Alerting.ITarget> Targets = new() {
|
||||||
new Alerting.TelegramTarget(TgClient, "1234", Monitors.First(p => p.Identifier == "placeholder-tcp"), "your.status.page", "SSH"),
|
new Alerting.TelegramTarget(TgClient, "1234", Monitors.First(p => p.Identifier == "placeholder-tcp"), "your.status.page", "SSH"),
|
||||||
new Alerting.TelegramTarget(TgClient, "1234", Monitors.First(p => p.Identifier == "placeholder-icmp"), "your.status.page", "Server"),
|
new Alerting.TelegramTarget(TgClient, "1234", Monitors.First(p => p.Identifier == "placeholder-icmp"), "your.status.page", "Server"),
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace Monithor.api {
|
||||||
public static void ProcessMonitors(bool notify = true) {
|
public static void ProcessMonitors(bool notify = true) {
|
||||||
foreach (var monitor in Config.Monitors.FindAll(monitor => monitor.Update(monitor.GetFluxItems(_influx, "5m")))) {
|
foreach (var monitor in Config.Monitors.FindAll(monitor => monitor.Update(monitor.GetFluxItems(_influx, "5m")))) {
|
||||||
if (notify) {
|
if (notify) {
|
||||||
Config.TelegramTargets.FindAll(p => p.Monitor == monitor).ForEach(p => p.SendMessage());
|
Config.Targets.FindAll(p => p.Monitor == monitor).ForEach(p => p.SendMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue