louislam / uptime-kuma

A fancy self-hosted monitoring tool
https://uptime.kuma.pet
MIT License
56.1k stars 5.05k forks source link

Add zulip as a notification provider #1052

Open Rems08 opened 2 years ago

Rems08 commented 2 years ago

⚠️ Please verify that this feature request has NOT been suggested before.

🏷️ Feature Request Type

New Notification

🔖 Feature description

I would like to send a detailed notification from my kuma-uptime to my self-hosted zulip server. That's why I can't use aprise (enterprise proxy)

✔️ Solution

If you could create a native zulip notification that would be great!

❓ Alternatives

No response

📝 Additional Context

No response

tplecko commented 2 years ago

I have written a simple webhook that resides on the same machine as Uptime Kuma, and just reposts the data in zulip format as a message to a stream. Also, this way, if the status is a failure, I can tag people and groups.

tplecko commented 2 years ago
<?php 
$data = json_decode(file_get_contents('php://input'), true);
$content = 
"| Name | Hostname |\n".
"|---|---|\n".
"| ".$data['monitor']['name']." | ".$data['monitor']['hostname']." |\n\n".
"| Message |\n".
"|---|\n".
"| ".$data['msg']." |\n";

$payload = array (
    'type'        => 'stream',
    'to'          => 'infrastructure',
    'subject'     => $data['monitor']['name'],
    'content'     => $content
);

$ch = curl_init('https://<zulip-url>/api/v1/messages');
curl_setopt($ch, CURLOPT_USERPWD, '<bot-name>:<bot-password>');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
?>

One simple if ($data['heartbeat']['status']=='0') will allow you to customize the message (you don't have to pass the data from Uptime Kuma to Zulip as-is

Also, make sure that content type is application/json.

AdamJSoftware commented 1 year ago

Containerized it https://hub.docker.com/repository/docker/databending/kuma-to-zulip

eXtrem0us commented 8 months ago

Hey Guys -On the Uptime Kuma side, We used Slack as Notification Type (don't fill the Channel Name field!) -On the Zulip side, we used Slack too. Just check the Zulip Integration for Slack documents.

This works for us and fulfills our needs. However there are some small downsides of this workaround. Uptime Kuma sends some special characters to Zulip that makes some rectangles appear above the alert messages, instead of creating proper tables. I couldn't find the section of code that generates these pipes "|" and dashes "-". (In this case, this issue may be relevant) Screenshot at 2023-12-28 17-16-34

The other issue is that we can not specify the topic name besides stream name in the Webhook URL section. This is the Zulip webhook URL template: https://[Zulip Hostname]/api/v1/external/slack_incoming?api_key=[Robot API Key]&stream=UpTime-Kuma&topic=[Monitor Name]. I couldn't find documents that tell us how to make the Webhook URL dynamic.

eXtrem0us commented 7 months ago

Eventually, I wrote a Logstash config, which

Logstash config

```logstash input { http { id => "uptimekuma-log" port => 10221 codec => json { charset => "UTF-8" } } } filter { mutate { add_field => { "monitor_url" => "%{[monitor][url]}" "monitor_friendly_name" => "%{[monitor][name]}" "alert_type" => "%{[heartbeat][status]}" "alert_details" => "%{[msg]}" "alert_friendly_duration" => "" } } if [heartbeat][status] == 0 { mutate { add_field => { "alert_type_friendly_name" => "Down" } } } else { mutate { add_field => { "alert_type_friendly_name" => "Up" } } } ruby { code => ' seconds = event.get("[heartbeat][duration]").to_i minutes = seconds / 60 seconds %= 60 hours = minutes / 60 minutes %= 60 event.set("alert_friendly_duration", "#{hours} hour(s), #{minutes} minute(s) and #{seconds} second(s)") ' } mutate { remove_field => ["headers", "monitor", "heartbeat", "msg", "@version", "@timestamp", "host"] } } output { http { url => "https://zulip.myhostname.com/api/v1/external/uptimerobot?api_key=abcdefghijklmnopqr&stream=Uptime-Kuma&" http_method => "post" format => "json" mapping => { "monitor_url" => "%{monitor_url}" "monitor_friendly_name" => "%{monitor_friendly_name}" "alert_type" => "%{alert_type}" "alert_type_friendly_name" => "%{alert_type_friendly_name}" "alert_details" => "%{alert_details}" "alert_friendly_duration" => "%{alert_friendly_duration}" } } } ```

alexmv commented 5 months ago

Uptime Kuma sends some special characters to Zulip that makes some rectangles appear above the alert messages, instead of creating proper tables.

See zulip/zulip@1b692984cefcd15421a1edac835278a6c91c08d7 -- specifically, Zulip's markdown syntax requires a header row at the top of a table. Since Slack's "fields" concept does not have headers, merely rendering every field in a 2-wide table left-to-right-top-to-bottom, we chose to insert an empty "header" row, resulting in the black bar, and then insert the provided content into the "body" of the two-wide table.

If you want to improve this rendering for Uptime Kuma messages your options are:

See https://zulip.com/api/incoming-webhooks-overview for a discussion of both of these options.