mirror of
https://github.com/healthchecks/healthchecks.git
synced 2025-04-05 05:15:26 +00:00
Update transport classes to use Transport.last_ping() consistently
* Instead of check.n_pings (int) use last_ping().n * Instead of check.last_ping (datetime) use last_ping().created There is a time gap from creating a flip object to processing it (sending out an alert). We want the notification to reflect the check's state at the moment the flip was created. To do this, we use the Transport.last_ping() helper method which retrieves the last ping *that is not newer than the flip*. This commit updates transport classes and templates to use Transport.last_ping() consistently everywhere.
This commit is contained in:
parent
d8a46349a8
commit
83f161d657
49 changed files with 264 additions and 140 deletions
hc/api
tests
test_notify_apprise.pytest_notify_call.pytest_notify_discord.pytest_notify_email.pytest_notify_gotify.pytest_notify_group.pytest_notify_line.pytest_notify_matrix.pytest_notify_mattermost.pytest_notify_msteams.pytest_notify_ntfy.pytest_notify_opsgenie.pytest_notify_pagertree.pytest_notify_pd.pytest_notify_pushbullet.pytest_notify_pushover.pytest_notify_rocketchat.pytest_notify_signal.pytest_notify_slack.pytest_notify_sms.pytest_notify_spike.pytest_notify_telegram.pytest_notify_trello.pytest_notify_victorops.pytest_notify_webhook.pytest_notify_whatsapp.pytest_notify_zulip.py
transports.pytemplates
emails
integrations
apprise_description.htmlgotify_message.htmllinenotify_message.htmlmatrix_description.htmlmatrix_description_formatted.htmlntfy_message.htmlopsgenie_description.htmlopsgenie_note.htmlpagertree_description.htmlpd_last_ping.htmlpushbullet_message.htmlpushover_message.htmlsignal_message.htmlsms_message.htmlspike_description.htmltelegram_message.htmltrello_desc.htmlvictorops_description.htmlzulip_content.html
|
@ -9,7 +9,7 @@ from unittest.mock import Mock, patch
|
|||
from django.test.utils import override_settings
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
try:
|
||||
|
@ -30,9 +30,14 @@ class NotifyAppriseTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
self.channel.kind = "apprise"
|
||||
self.channel.value = "123"
|
||||
|
@ -56,7 +61,7 @@ class NotifyAppriseTestCase(BaseTestCase):
|
|||
|
||||
body = mock_apprise.return_value.notify.call_args.kwargs["body"]
|
||||
self.assertIn("Foo is DOWN", body)
|
||||
self.assertIn("Last ping was an hour ago.", body)
|
||||
self.assertIn("Last ping was 10 minutes ago.", body)
|
||||
|
||||
@patch("apprise.Apprise")
|
||||
@override_settings(APPRISE_ENABLED=False)
|
||||
|
@ -69,8 +74,7 @@ class NotifyAppriseTestCase(BaseTestCase):
|
|||
@patch("apprise.Apprise")
|
||||
@override_settings(APPRISE_ENABLED=True)
|
||||
def test_it_handles_no_last_ping(self, mock_apprise: Mock) -> None:
|
||||
self.check.last_ping = None
|
||||
self.check.save()
|
||||
self.ping.delete()
|
||||
|
||||
mock_aobj = Mock()
|
||||
mock_aobj.add.return_value = True
|
||||
|
|
|
@ -24,7 +24,7 @@ class NotifyCallTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
|
|
|
@ -19,11 +19,12 @@ class NotifyDiscordTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=61)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
|
@ -54,6 +55,7 @@ class NotifyDiscordTestCase(BaseTestCase):
|
|||
|
||||
fields = {f["title"]: f["value"] for f in attachment["fields"]}
|
||||
self.assertEqual(fields["Last Ping"], "Success, an hour ago")
|
||||
self.assertEqual(fields["Total Pings"], "112233")
|
||||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_rewrites_discordapp_com(self, mock_post: Mock) -> None:
|
||||
|
|
|
@ -27,12 +27,12 @@ class NotifyEmailTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.n_pings = 112233
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.n = 1
|
||||
self.ping.created = now() - td(minutes=61)
|
||||
self.ping.n = 112233
|
||||
self.ping.remote_addr = "1.2.3.4"
|
||||
self.ping.body_raw = b"Body Line 1\nBody Line 2"
|
||||
self.ping.save()
|
||||
|
@ -103,6 +103,10 @@ class NotifyEmailTestCase(BaseTestCase):
|
|||
self.assertIn("112233", email.body)
|
||||
self.assertIn("112233", html)
|
||||
|
||||
# Last ping time
|
||||
self.assertIn("an hour ago", email.body)
|
||||
self.assertIn("an hour ago", html)
|
||||
|
||||
# Last ping body
|
||||
self.assertIn("Body Line 1\nBody Line 2", email.body)
|
||||
self.assertIn("Body Line 1<br>Body Line 2", html)
|
||||
|
@ -136,7 +140,7 @@ class NotifyEmailTestCase(BaseTestCase):
|
|||
|
||||
code, n = get_object.call_args.args
|
||||
self.assertEqual(code, str(self.check.code))
|
||||
self.assertEqual(n, 1)
|
||||
self.assertEqual(n, 112233)
|
||||
|
||||
def test_it_shows_cron_schedule(self) -> None:
|
||||
self.check.kind = "cron"
|
||||
|
|
|
@ -8,7 +8,7 @@ from unittest.mock import Mock, patch
|
|||
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
|
@ -21,9 +21,14 @@ class NotifyGotidyTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
self.channel.kind = "gotify"
|
||||
self.channel.value = json.dumps({"url": "https://example.org", "token": "abc"})
|
||||
|
@ -48,7 +53,7 @@ class NotifyGotidyTestCase(BaseTestCase):
|
|||
payload = mock_post.call_args.kwargs["json"]
|
||||
self.assertEqual(payload["title"], "Foo is DOWN")
|
||||
self.assertIn(self.check.cloaked_url(), payload["message"])
|
||||
self.assertIn("Last ping was an hour ago.", payload["message"])
|
||||
self.assertIn("Last ping was 10 minutes ago.", payload["message"])
|
||||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_handles_subpath(self, mock_post: Mock) -> None:
|
||||
|
@ -137,8 +142,7 @@ class NotifyGotidyTestCase(BaseTestCase):
|
|||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_handles_no_last_ping(self, mock_post: Mock) -> None:
|
||||
self.check.last_ping = None
|
||||
self.check.save()
|
||||
self.ping.delete()
|
||||
|
||||
mock_post.return_value.status_code = 200
|
||||
self.channel.notify(self.flip)
|
||||
|
|
|
@ -22,7 +22,7 @@ class NotifyGroupTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.channel_email = Channel(project=self.project)
|
||||
|
|
|
@ -7,7 +7,7 @@ from unittest.mock import Mock, patch
|
|||
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
|
@ -20,9 +20,14 @@ class NotifyLineTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
self.channel.kind = "linenotify"
|
||||
self.channel.value = "fake-token"
|
||||
|
@ -45,7 +50,7 @@ class NotifyLineTestCase(BaseTestCase):
|
|||
params = mock_post.call_args.kwargs["params"]
|
||||
self.assertEqual(headers["Authorization"], "Bearer fake-token")
|
||||
self.assertIn("""The check "Foo" is DOWN""", params["message"])
|
||||
self.assertIn("Last ping was an hour ago.", params["message"])
|
||||
self.assertIn("Last ping was 10 minutes ago.", params["message"])
|
||||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_does_not_escape_message(self, mock_post: Mock) -> None:
|
||||
|
@ -63,8 +68,7 @@ class NotifyLineTestCase(BaseTestCase):
|
|||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_handles_no_last_ping(self, mock_post: Mock) -> None:
|
||||
self.check.last_ping = None
|
||||
self.check.save()
|
||||
self.ping.delete()
|
||||
|
||||
mock_post.return_value.status_code = 200
|
||||
self.channel.notify(self.flip)
|
||||
|
|
|
@ -9,7 +9,7 @@ from urllib.parse import quote
|
|||
from django.test.utils import override_settings
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
|
@ -25,9 +25,14 @@ class NotifyMatrixTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
self.channel.kind = "matrix"
|
||||
self.channel.value = "!foo:example.org"
|
||||
|
@ -53,13 +58,12 @@ class NotifyMatrixTestCase(BaseTestCase):
|
|||
|
||||
payload = mock_post.call_args.kwargs["json"]
|
||||
self.assertIn("Foo is DOWN.", payload["body"])
|
||||
self.assertIn("Last ping was an hour ago.", payload["body"])
|
||||
self.assertIn("Last ping was an hour ago.", payload["formatted_body"])
|
||||
self.assertIn("Last ping was 10 minutes ago.", payload["body"])
|
||||
self.assertIn("Last ping was 10 minutes ago.", payload["formatted_body"])
|
||||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_handles_no_last_ping(self, mock_post: Mock) -> None:
|
||||
self.check.last_ping = None
|
||||
self.check.save()
|
||||
self.ping.delete()
|
||||
|
||||
mock_post.return_value.status_code = 200
|
||||
self.channel.notify(self.flip)
|
||||
|
|
|
@ -21,11 +21,12 @@ class NotifyMattermostTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=61)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
|
@ -54,6 +55,7 @@ class NotifyMattermostTestCase(BaseTestCase):
|
|||
|
||||
fields = {f["title"]: f["value"] for f in attachment["fields"]}
|
||||
self.assertEqual(fields["Last Ping"], "Success, an hour ago")
|
||||
self.assertEqual(fields["Total Pings"], "112233")
|
||||
|
||||
@override_settings(MATTERMOST_ENABLED=False)
|
||||
def test_it_requires_mattermost_enabled(self) -> None:
|
||||
|
|
|
@ -21,11 +21,12 @@ class NotifyMsTeamsTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=61)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
|
@ -58,6 +59,7 @@ class NotifyMsTeamsTestCase(BaseTestCase):
|
|||
|
||||
facts = {f["name"]: f["value"] for f in payload["sections"][0]["facts"]}
|
||||
self.assertEqual(facts["Last Ping:"], "Success, an hour ago")
|
||||
self.assertEqual(facts["Total Pings:"], "112233")
|
||||
|
||||
# The payload should not contain check's code
|
||||
serialized = json.dumps(payload)
|
||||
|
|
|
@ -23,11 +23,12 @@ class NotifyNtfyTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.n = 1
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.remote_addr = "1.2.3.4"
|
||||
self.ping.save()
|
||||
|
||||
|
@ -61,8 +62,8 @@ class NotifyNtfyTestCase(BaseTestCase):
|
|||
self.assertIn("Project: Alices Project", payload["message"])
|
||||
self.assertIn("Tags: foo, bar", payload["message"])
|
||||
self.assertIn("Period: 1 day", payload["message"])
|
||||
self.assertIn("Total Pings: 123", payload["message"])
|
||||
self.assertIn("Last Ping: Success, now", payload["message"])
|
||||
self.assertIn("Total Pings: 112233", payload["message"])
|
||||
self.assertIn("Last Ping: Success, 10 minutes ago", payload["message"])
|
||||
|
||||
self.assertEqual(payload["actions"][0]["url"], self.check.cloaked_url())
|
||||
self.assertNotIn("All the other checks are up.", payload["message"])
|
||||
|
|
|
@ -9,7 +9,7 @@ from unittest.mock import Mock, patch
|
|||
from django.test.utils import override_settings
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
|
@ -22,9 +22,14 @@ class NotifyOpsgenieTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
self.channel.kind = "opsgenie"
|
||||
self.channel.value = value
|
||||
|
@ -49,8 +54,8 @@ class NotifyOpsgenieTestCase(BaseTestCase):
|
|||
payload = mock_post.call_args.kwargs["json"]
|
||||
self.assertIn("""The check "Foo" is DOWN.""", payload["message"])
|
||||
self.assertIn("""The check "Foo" is DOWN.""", payload["description"])
|
||||
self.assertIn("Last ping was an hour ago.", payload["description"])
|
||||
self.assertIn("Last ping was an hour ago.", payload["note"])
|
||||
self.assertIn("Last ping was 10 minutes ago.", payload["description"])
|
||||
self.assertIn("Last ping was 10 minutes ago.", payload["note"])
|
||||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_opsgenie_with_legacy_value(self, mock_post: Mock) -> None:
|
||||
|
@ -124,8 +129,7 @@ class NotifyOpsgenieTestCase(BaseTestCase):
|
|||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_handles_no_last_ping(self, mock_post: Mock) -> None:
|
||||
self._setup_data(json.dumps({"key": "123", "region": "us"}))
|
||||
self.check.last_ping = None
|
||||
self.check.save()
|
||||
self.ping.delete()
|
||||
mock_post.return_value.status_code = 202
|
||||
|
||||
self.channel.notify(self.flip)
|
||||
|
|
|
@ -8,7 +8,7 @@ from unittest.mock import Mock, patch
|
|||
from django.test.utils import override_settings
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
|
@ -21,9 +21,14 @@ class NotifyPagertreeTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
self.channel.kind = "pagertree"
|
||||
self.channel.value = "123"
|
||||
|
@ -45,7 +50,7 @@ class NotifyPagertreeTestCase(BaseTestCase):
|
|||
payload = mock_post.call_args.kwargs["json"]
|
||||
self.assertEqual(payload["event_type"], "trigger")
|
||||
self.assertIn("Foo is DOWN.", payload["description"])
|
||||
self.assertIn("Last ping was an hour ago.", payload["description"])
|
||||
self.assertIn("Last ping was 10 minutes ago.", payload["description"])
|
||||
|
||||
@override_settings(PAGERTREE_ENABLED=False)
|
||||
def test_it_requires_pagertree_enabled(self) -> None:
|
||||
|
@ -68,8 +73,7 @@ class NotifyPagertreeTestCase(BaseTestCase):
|
|||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_handles_no_last_ping(self, mock_post: Mock) -> None:
|
||||
self.check.last_ping = None
|
||||
self.check.save()
|
||||
self.ping.delete()
|
||||
mock_post.return_value.status_code = 200
|
||||
|
||||
self.channel.notify(self.flip)
|
||||
|
|
|
@ -9,7 +9,7 @@ from unittest.mock import Mock, patch
|
|||
from django.test.utils import override_settings
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
|
@ -23,9 +23,14 @@ class NotifyPdTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
self.channel.kind = "pd"
|
||||
self.channel.value = value
|
||||
|
@ -51,6 +56,8 @@ class NotifyPdTestCase(BaseTestCase):
|
|||
self.assertEqual(payload["details"]["Description"], "Description goes here")
|
||||
self.assertEqual(payload["event_type"], "trigger")
|
||||
self.assertEqual(payload["service_key"], "123")
|
||||
self.assertEqual(payload["details"]["Last ping"], "10 minutes ago")
|
||||
self.assertEqual(payload["details"]["Total pings"], 112233)
|
||||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_shows_schedule_and_tz(self, mock_post: Mock) -> None:
|
||||
|
|
|
@ -7,7 +7,7 @@ from unittest.mock import Mock, patch
|
|||
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
|
@ -20,9 +20,14 @@ class NotifyPushbulletTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
self.channel.kind = "pushbullet"
|
||||
self.channel.value = "fake-token"
|
||||
|
@ -47,7 +52,7 @@ class NotifyPushbulletTestCase(BaseTestCase):
|
|||
payload = kwargs["json"]
|
||||
self.assertEqual(payload["type"], "note")
|
||||
self.assertIn("""The check "Foo" is DOWN.""", payload["body"])
|
||||
self.assertIn("""Last ping was an hour ago.""", payload["body"])
|
||||
self.assertIn("""Last ping was 10 minutes ago.""", payload["body"])
|
||||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_handles_up(self, mock_post: Mock) -> None:
|
||||
|
@ -79,8 +84,8 @@ class NotifyPushbulletTestCase(BaseTestCase):
|
|||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_handles_no_last_ping(self, mock_post: Mock) -> None:
|
||||
self.ping.delete()
|
||||
self.check.status = "down"
|
||||
self.check.last_ping = None
|
||||
self.check.save()
|
||||
mock_post.return_value.status_code = 200
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ from unittest.mock import Mock, patch
|
|||
from django.test.utils import override_settings
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification, TokenBucket
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping, TokenBucket
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
API = "https://api.pushover.net/1"
|
||||
|
@ -24,9 +24,14 @@ class NotifyPushoverTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
self.channel.kind = "po"
|
||||
self.channel.value = value
|
||||
|
@ -53,6 +58,9 @@ class NotifyPushoverTestCase(BaseTestCase):
|
|||
payload = mock_post.call_args.kwargs["data"]
|
||||
self.assertEqual(payload["title"], "🔴 Foo")
|
||||
self.assertEqual(payload["url"], self.check.cloaked_url())
|
||||
self.assertIn("112233", payload["message"])
|
||||
self.assertIn("10 minutes ago", payload["message"])
|
||||
|
||||
# Only one check in the project, so there should be no note about
|
||||
# other checks:
|
||||
self.assertNotIn("All the other checks are up.", payload["message"])
|
||||
|
|
|
@ -20,11 +20,12 @@ class NotifyRocketChatTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=61)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
|
@ -54,6 +55,7 @@ class NotifyRocketChatTestCase(BaseTestCase):
|
|||
attachment = mock_post.call_args.kwargs["json"]["attachments"][0]
|
||||
fields = {f["title"]: f["value"] for f in attachment["fields"]}
|
||||
self.assertEqual(fields["Last Ping"], "Success, an hour ago")
|
||||
self.assertEqual(fields["Total Pings"], "112233")
|
||||
|
||||
@override_settings(ROCKETCHAT_ENABLED=False)
|
||||
def test_it_requires_rocketchat_enabled(self) -> None:
|
||||
|
|
|
@ -81,12 +81,13 @@ class NotifySignalTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.n_pings = 123
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.n = 1
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.remote_addr = "1.2.3.4"
|
||||
self.ping.body_raw = b"Body Line 1\nBody Line 2"
|
||||
self.ping.save()
|
||||
|
@ -127,8 +128,8 @@ class NotifySignalTestCase(BaseTestCase):
|
|||
self.assertIn("Project: Alices Project", params["message"])
|
||||
self.assertIn("Tags: foo, bar", params["message"])
|
||||
self.assertIn("Period: 1 day", params["message"])
|
||||
self.assertIn("Total Pings: 123", params["message"])
|
||||
self.assertIn("Last Ping: Success, now", params["message"])
|
||||
self.assertIn("Total Pings: 112233", params["message"])
|
||||
self.assertIn("Last Ping: Success, 10 minutes ago", params["message"])
|
||||
self.assertIn("+123456789", params["recipient"])
|
||||
|
||||
# Only one check in the project, so there should be no note about
|
||||
|
@ -151,7 +152,7 @@ class NotifySignalTestCase(BaseTestCase):
|
|||
|
||||
assert socketobj.req
|
||||
params = socketobj.req["params"]
|
||||
self.assertIn("Last Ping: Exit status 123, now", params["message"])
|
||||
self.assertIn("Last Ping: Exit status 123, 10 minutes ago", params["message"])
|
||||
|
||||
@patch("hc.api.transports.socket.socket")
|
||||
def test_it_shows_schedule_and_tz(self, socket: Mock) -> None:
|
||||
|
|
|
@ -23,11 +23,12 @@ class NotifySlackTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=61)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
|
@ -60,6 +61,7 @@ class NotifySlackTestCase(BaseTestCase):
|
|||
|
||||
fields = {f["title"]: f["value"] for f in attachment["fields"]}
|
||||
self.assertEqual(fields["Last Ping"], "Success, an hour ago")
|
||||
self.assertEqual(fields["Total Pings"], "112233")
|
||||
self.assertNotIn("Last Ping Body", fields)
|
||||
|
||||
# The payload should not contain check's code
|
||||
|
|
|
@ -10,7 +10,7 @@ from django.core import mail
|
|||
from django.test.utils import override_settings
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
|
@ -24,9 +24,14 @@ class NotifySmsTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
spec = {"value": "+1234567890", "up": False, "down": True}
|
||||
self.channel = Channel(project=self.project, kind="sms")
|
||||
self.channel.value = json.dumps(spec)
|
||||
|
@ -50,7 +55,7 @@ class NotifySmsTestCase(BaseTestCase):
|
|||
self.assertEqual(payload["From"], "+000")
|
||||
self.assertNotIn("\xa0", payload["Body"])
|
||||
self.assertIn("""The check "Foo" is DOWN.""", payload["Body"])
|
||||
self.assertIn("""Last ping was an hour ago.""", payload["Body"])
|
||||
self.assertIn("""Last ping was 10 minutes ago.""", payload["Body"])
|
||||
|
||||
n = Notification.objects.get()
|
||||
callback_path = f"/api/v3/notifications/{n.code}/status"
|
||||
|
@ -175,8 +180,7 @@ class NotifySmsTestCase(BaseTestCase):
|
|||
@override_settings(TWILIO_FROM="+000", TWILIO_MESSAGING_SERVICE_SID=None)
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_handles_no_last_ping(self, mock_post: Mock) -> None:
|
||||
self.check.last_ping = None
|
||||
self.check.save()
|
||||
self.ping.delete()
|
||||
mock_post.return_value.status_code = 200
|
||||
|
||||
self.channel.notify(self.flip)
|
||||
|
|
|
@ -8,7 +8,7 @@ from unittest.mock import Mock, patch
|
|||
from django.test.utils import override_settings
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
|
@ -21,9 +21,14 @@ class NotifySpikeTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
self.channel.kind = "spike"
|
||||
self.channel.value = "https://spike.example.org"
|
||||
|
@ -46,7 +51,7 @@ class NotifySpikeTestCase(BaseTestCase):
|
|||
self.assertEqual(payload["check_id"], str(self.check.code))
|
||||
self.assertEqual(payload["title"], "Foo is DOWN")
|
||||
self.assertIn("Foo is DOWN.", payload["message"])
|
||||
self.assertIn("Last ping was an hour ago.", payload["message"])
|
||||
self.assertIn("Last ping was 10 minutes ago.", payload["message"])
|
||||
|
||||
@override_settings(SPIKE_ENABLED=False)
|
||||
def test_it_requires_spike_enabled(self) -> None:
|
||||
|
@ -70,8 +75,7 @@ class NotifySpikeTestCase(BaseTestCase):
|
|||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_handles_no_last_ping(self, mock_post: Mock) -> None:
|
||||
self.check.last_ping = None
|
||||
self.check.save()
|
||||
self.ping.delete()
|
||||
mock_post.return_value.status_code = 200
|
||||
|
||||
self.channel.notify(self.flip)
|
||||
|
|
|
@ -22,12 +22,13 @@ class NotifyTelegramTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.n_pings = 1
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=61)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
|
@ -58,8 +59,8 @@ class NotifyTelegramTestCase(BaseTestCase):
|
|||
self.assertIn("<b>Project:</b> Alices Project\n", payload["text"])
|
||||
self.assertIn("<b>Tags:</b> foo, bar, baz\n", payload["text"])
|
||||
self.assertIn("<b>Period:</b> 1 day\n", payload["text"])
|
||||
self.assertIn("<b>Total Pings:</b> 1\n", payload["text"])
|
||||
self.assertIn("<b>Last Ping:</b> Success, an hour ago", payload["text"])
|
||||
self.assertIn("<b>Total Pings:</b> 112233\n", payload["text"])
|
||||
self.assertIn("<b>Last Ping:</b> Success, 10 minutes ago", payload["text"])
|
||||
|
||||
# Only one check in the project, so there should be no note about
|
||||
# other checks:
|
||||
|
@ -76,7 +77,9 @@ class NotifyTelegramTestCase(BaseTestCase):
|
|||
self.channel.notify(self.flip)
|
||||
|
||||
payload = mock_post.call_args.kwargs["json"]
|
||||
self.assertIn("<b>Last Ping:</b> Exit status 123, an hour ago", payload["text"])
|
||||
self.assertIn(
|
||||
"<b>Last Ping:</b> Exit status 123, 10 minutes ago", payload["text"]
|
||||
)
|
||||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_sends_to_thread(self, mock_post: Mock) -> None:
|
||||
|
|
|
@ -7,7 +7,7 @@ from unittest.mock import Mock, patch
|
|||
from django.test.utils import override_settings
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
|
@ -21,9 +21,14 @@ class NotifyTrelloTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
self.channel.kind = "trello"
|
||||
self.channel.value = json.dumps(
|
||||
|
@ -53,7 +58,7 @@ class NotifyTrelloTestCase(BaseTestCase):
|
|||
self.assertEqual(params["idList"], "fake-list-id")
|
||||
self.assertEqual(params["name"], "Down: Foo")
|
||||
self.assertIn("Full Details", params["desc"])
|
||||
self.assertIn("**Last Ping:** an hour ago", params["desc"])
|
||||
self.assertIn("**Last Ping:** 10 minutes ago", params["desc"])
|
||||
self.assertEqual(params["key"], "fake-trello-app-key")
|
||||
self.assertEqual(params["token"], "fake-token")
|
||||
|
||||
|
@ -92,8 +97,7 @@ class NotifyTrelloTestCase(BaseTestCase):
|
|||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_handles_no_last_ping(self, mock_post: Mock) -> None:
|
||||
self.check.last_ping = None
|
||||
self.check.save()
|
||||
self.ping.delete()
|
||||
mock_post.return_value.status_code = 200
|
||||
|
||||
self.channel.notify(self.flip)
|
||||
|
|
|
@ -8,7 +8,7 @@ from unittest.mock import Mock, patch
|
|||
from django.test.utils import override_settings
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
|
@ -21,9 +21,14 @@ class NotifyVictorOpsTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
self.channel.kind = "victorops"
|
||||
self.channel.value = "123"
|
||||
|
@ -45,7 +50,7 @@ class NotifyVictorOpsTestCase(BaseTestCase):
|
|||
payload = mock_post.call_args.kwargs["json"]
|
||||
self.assertEqual(payload["message_type"], "CRITICAL")
|
||||
self.assertIn("Foo is DOWN.", payload["state_message"])
|
||||
self.assertIn("Last ping was an hour ago.", payload["state_message"])
|
||||
self.assertIn("Last ping was 10 minutes ago.", payload["state_message"])
|
||||
|
||||
@override_settings(VICTOROPS_ENABLED=False)
|
||||
def test_it_requires_victorops_enabled(self) -> None:
|
||||
|
@ -89,8 +94,7 @@ class NotifyVictorOpsTestCase(BaseTestCase):
|
|||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_handles_no_last_ping(self, mock_post: Mock) -> None:
|
||||
self.check.last_ping = None
|
||||
self.check.save()
|
||||
self.ping.delete()
|
||||
mock_post.return_value.status_code = 200
|
||||
|
||||
self.channel.notify(self.flip)
|
||||
|
|
|
@ -22,11 +22,12 @@ class NotifyWebhookTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = self.check.last_ping
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.body_raw = b"Body Line 1\nBody Line 2"
|
||||
self.ping.exitstatus = 123
|
||||
self.ping.save()
|
||||
|
|
|
@ -32,7 +32,7 @@ class NotifyWhatsAppTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
definition = {"value": "+1234567890", "up": True, "down": True}
|
||||
|
|
|
@ -9,7 +9,7 @@ from unittest.mock import Mock, patch
|
|||
from django.test.utils import override_settings
|
||||
from django.utils.timezone import now
|
||||
|
||||
from hc.api.models import Channel, Check, Flip, Notification
|
||||
from hc.api.models import Channel, Check, Flip, Notification, Ping
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
|
@ -22,9 +22,14 @@ class NotifyZulipTestCase(BaseTestCase):
|
|||
# Transport classes should use flip.new_status,
|
||||
# so the status "paused" should not appear anywhere
|
||||
self.check.status = "paused"
|
||||
self.check.last_ping = now() - td(minutes=61)
|
||||
self.check.last_ping = now()
|
||||
self.check.save()
|
||||
|
||||
self.ping = Ping(owner=self.check)
|
||||
self.ping.created = now() - td(minutes=10)
|
||||
self.ping.n = 112233
|
||||
self.ping.save()
|
||||
|
||||
self.channel = Channel(project=self.project)
|
||||
self.channel.kind = "zulip"
|
||||
self.channel.value = json.dumps(self.definition())
|
||||
|
@ -59,7 +64,7 @@ class NotifyZulipTestCase(BaseTestCase):
|
|||
payload = mock_post.call_args.kwargs["data"]
|
||||
self.assertEqual(payload["topic"], "Foobar is DOWN")
|
||||
self.assertIn("is **DOWN**.", payload["content"])
|
||||
self.assertIn("Last ping was an hour ago.", payload["content"])
|
||||
self.assertIn("Last ping was 10 minutes ago.", payload["content"])
|
||||
|
||||
# payload should not contain check's code
|
||||
serialized = json.dumps(payload)
|
||||
|
@ -137,8 +142,7 @@ class NotifyZulipTestCase(BaseTestCase):
|
|||
|
||||
@patch("hc.api.transports.curl.request", autospec=True)
|
||||
def test_it_handles_no_last_ping(self, mock_post: Mock) -> None:
|
||||
self.check.last_ping = None
|
||||
self.check.save()
|
||||
self.ping.delete()
|
||||
mock_post.return_value.status_code = 200
|
||||
|
||||
self.channel.notify(self.flip)
|
||||
|
|
|
@ -463,13 +463,13 @@ class Slackalike(HttpTransport):
|
|||
fields.add("Schedule", fix_asterisks(check.schedule))
|
||||
fields.add("Time Zone", check.tz)
|
||||
|
||||
fields.add("Total Pings", str(check.n_pings))
|
||||
|
||||
if ping := self.last_ping(flip):
|
||||
fields.add("Total Pings", str(ping.n))
|
||||
created_str = naturaltime(ping.created)
|
||||
formatted_kind = ping.get_kind_display()
|
||||
fields.add("Last Ping", f"{formatted_kind}, {created_str}")
|
||||
else:
|
||||
fields.add("Total Pings", "0")
|
||||
fields.add("Last Ping", "Never")
|
||||
|
||||
body = get_ping_body(ping, maxlen=1000)
|
||||
|
@ -553,10 +553,11 @@ class Opsgenie(HttpTransport):
|
|||
payload: JSONDict = {"alias": str(check.code), "source": settings.SITE_NAME}
|
||||
|
||||
if flip.new_status == "down":
|
||||
ctx = {"check": check, "ping": self.last_ping(flip)}
|
||||
payload["tags"] = cast(JSONValue, check.tags_list())
|
||||
payload["message"] = tmpl("opsgenie_message.html", check=check)
|
||||
payload["note"] = tmpl("opsgenie_note.html", check=check)
|
||||
payload["description"] = tmpl("opsgenie_description.html", check=check)
|
||||
payload["message"] = tmpl("opsgenie_message.html", **ctx)
|
||||
payload["note"] = tmpl("opsgenie_note.html", **ctx)
|
||||
payload["description"] = tmpl("opsgenie_description.html", **ctx)
|
||||
|
||||
url = "https://api.opsgenie.com/v2/alerts"
|
||||
if self.channel.opsgenie.region == "eu":
|
||||
|
@ -576,10 +577,11 @@ class PagerDuty(HttpTransport):
|
|||
raise TransportError("PagerDuty notifications are not enabled.")
|
||||
|
||||
check = flip.owner
|
||||
ping = self.last_ping(flip)
|
||||
details = {
|
||||
"Project": check.project.name,
|
||||
"Total pings": check.n_pings,
|
||||
"Last ping": tmpl("pd_last_ping.html", check=check),
|
||||
"Total pings": ping.n if ping else 0,
|
||||
"Last ping": tmpl("pd_last_ping.html", ping=ping),
|
||||
}
|
||||
if check.desc:
|
||||
details["Description"] = check.desc
|
||||
|
@ -612,7 +614,11 @@ class PagerTree(HttpTransport):
|
|||
|
||||
url = self.channel.value
|
||||
headers = {"Content-Type": "application/json"}
|
||||
ctx = {"check": flip.owner, "status": flip.new_status}
|
||||
ctx = {
|
||||
"check": flip.owner,
|
||||
"status": flip.new_status,
|
||||
"ping": self.last_ping(flip),
|
||||
}
|
||||
payload = {
|
||||
"incident_key": str(flip.owner.code),
|
||||
"event_type": "trigger" if flip.new_status == "down" else "resolve",
|
||||
|
@ -628,12 +634,17 @@ class PagerTree(HttpTransport):
|
|||
|
||||
class Pushbullet(HttpTransport):
|
||||
def notify(self, flip: Flip, notification: Notification) -> None:
|
||||
text = tmpl("pushbullet_message.html", check=flip.owner, status=flip.new_status)
|
||||
url = "https://api.pushbullet.com/v2/pushes"
|
||||
headers = {
|
||||
"Access-Token": self.channel.value,
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
text = tmpl(
|
||||
"pushbullet_message.html",
|
||||
check=flip.owner,
|
||||
status=flip.new_status,
|
||||
ping=self.last_ping(flip),
|
||||
)
|
||||
payload = {"type": "note", "title": settings.SITE_NAME, "body": text}
|
||||
self.post(url, json=payload, headers=headers)
|
||||
|
||||
|
@ -754,9 +765,8 @@ class RocketChat(HttpTransport):
|
|||
fields.add("Schedule", fix_asterisks(check.schedule))
|
||||
fields.add("Time Zone", check.tz)
|
||||
|
||||
fields.add("Total Pings", str(check.n_pings))
|
||||
|
||||
if ping := self.last_ping(flip):
|
||||
fields.add("Total Pings", str(ping.n))
|
||||
created_str = naturaltime(ping.created)
|
||||
formatted_kind = ping.get_kind_display()
|
||||
fields.add("Last Ping", f"{formatted_kind}, {created_str}")
|
||||
|
@ -766,6 +776,7 @@ class RocketChat(HttpTransport):
|
|||
text = f"{body_size} {bytes_str}, [show body]({ping_url})"
|
||||
fields.add("Last Ping Body", text)
|
||||
else:
|
||||
fields.add("Total Pings", "0")
|
||||
fields.add("Last Ping", "Never")
|
||||
|
||||
return result
|
||||
|
@ -788,7 +799,11 @@ class VictorOps(HttpTransport):
|
|||
if not settings.VICTOROPS_ENABLED:
|
||||
raise TransportError("Splunk On-Call notifications are not enabled.")
|
||||
|
||||
ctx = {"check": flip.owner, "status": flip.new_status}
|
||||
ctx = {
|
||||
"check": flip.owner,
|
||||
"status": flip.new_status,
|
||||
"ping": self.last_ping(flip),
|
||||
}
|
||||
mtype = "CRITICAL" if flip.new_status == "down" else "RECOVERY"
|
||||
payload = {
|
||||
"entity_id": str(flip.owner.code),
|
||||
|
@ -812,7 +827,11 @@ class Matrix(HttpTransport):
|
|||
return url
|
||||
|
||||
def notify(self, flip: Flip, notification: Notification) -> None:
|
||||
ctx = {"check": flip.owner, "status": flip.new_status}
|
||||
ctx = {
|
||||
"check": flip.owner,
|
||||
"status": flip.new_status,
|
||||
"ping": self.last_ping(flip),
|
||||
}
|
||||
plain = tmpl("matrix_description.html", **ctx)
|
||||
formatted = tmpl("matrix_description_formatted.html", **ctx)
|
||||
payload = {
|
||||
|
@ -943,6 +962,7 @@ class Sms(HttpTransport):
|
|||
"sms_message.html",
|
||||
check=flip.owner,
|
||||
status=flip.new_status,
|
||||
ping=self.last_ping(flip),
|
||||
site_name=settings.SITE_NAME,
|
||||
)
|
||||
|
||||
|
@ -1085,10 +1105,15 @@ class Trello(HttpTransport):
|
|||
if not settings.TRELLO_APP_KEY:
|
||||
raise TransportError("Trello notifications are not enabled.")
|
||||
|
||||
ctx = {
|
||||
"check": flip.owner,
|
||||
"status": flip.new_status,
|
||||
"ping": self.last_ping(flip),
|
||||
}
|
||||
params = {
|
||||
"idList": self.channel.trello.list_id,
|
||||
"name": tmpl("trello_name.html", check=flip.owner, status=flip.new_status),
|
||||
"desc": tmpl("trello_desc.html", check=flip.owner),
|
||||
"name": tmpl("trello_name.html", **ctx),
|
||||
"desc": tmpl("trello_desc.html", **ctx),
|
||||
"key": settings.TRELLO_APP_KEY,
|
||||
"token": self.channel.trello.token,
|
||||
}
|
||||
|
@ -1103,9 +1128,9 @@ class Apprise(HttpTransport):
|
|||
raise TransportError("Apprise is disabled and/or not installed")
|
||||
|
||||
a = apprise.Apprise()
|
||||
check, status = flip.owner, flip.new_status
|
||||
check, status, ping = flip.owner, flip.new_status, self.last_ping(flip)
|
||||
title = tmpl("apprise_title.html", check=check, status=status)
|
||||
body = tmpl("apprise_description.html", check=check, status=status)
|
||||
body = tmpl("apprise_description.html", check=check, status=status, ping=ping)
|
||||
|
||||
a.add(self.channel.value)
|
||||
|
||||
|
@ -1150,12 +1175,12 @@ class MsTeams(HttpTransport):
|
|||
facts.append({"name": "Schedule:", "value": fix_asterisks(check.schedule)})
|
||||
facts.append({"name": "Time Zone:", "value": check.tz})
|
||||
|
||||
facts.append({"name": "Total Pings:", "value": str(check.n_pings)})
|
||||
|
||||
if ping := self.last_ping(flip):
|
||||
facts.append({"name": "Total Pings:", "value": str(ping.n)})
|
||||
text = f"{ping.get_kind_display()}, {naturaltime(ping.created)}"
|
||||
facts.append({"name": "Last Ping:", "value": text})
|
||||
else:
|
||||
facts.append({"name": "Total Pings:", "value": "0"})
|
||||
facts.append({"name": "Last Ping:", "value": "Never"})
|
||||
|
||||
body = get_ping_body(ping, maxlen=1000)
|
||||
|
@ -1197,7 +1222,12 @@ class Zulip(HttpTransport):
|
|||
|
||||
url = self.channel.zulip.site + "/api/v1/messages"
|
||||
auth = (self.channel.zulip.bot_email, self.channel.zulip.api_key)
|
||||
content = tmpl("zulip_content.html", check=flip.owner, status=flip.new_status)
|
||||
content = tmpl(
|
||||
"zulip_content.html",
|
||||
check=flip.owner,
|
||||
status=flip.new_status,
|
||||
ping=self.last_ping(flip),
|
||||
)
|
||||
data = {
|
||||
"type": self.channel.zulip.mtype,
|
||||
"to": self.channel.zulip.to,
|
||||
|
@ -1215,7 +1245,11 @@ class Spike(HttpTransport):
|
|||
|
||||
url = self.channel.value
|
||||
headers = {"Content-Type": "application/json"}
|
||||
ctx = {"check": flip.owner, "status": flip.new_status}
|
||||
ctx = {
|
||||
"check": flip.owner,
|
||||
"status": flip.new_status,
|
||||
"ping": self.last_ping(flip),
|
||||
}
|
||||
payload = {
|
||||
"check_id": str(flip.owner.code),
|
||||
"title": tmpl("spike_title.html", **ctx),
|
||||
|
@ -1234,7 +1268,12 @@ class LineNotify(HttpTransport):
|
|||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"Authorization": "Bearer %s" % self.channel.linenotify_token,
|
||||
}
|
||||
msg = tmpl("linenotify_message.html", check=flip.owner, status=flip.new_status)
|
||||
ctx = {
|
||||
"check": flip.owner,
|
||||
"status": flip.new_status,
|
||||
"ping": self.last_ping(flip),
|
||||
}
|
||||
msg = tmpl("linenotify_message.html", **ctx)
|
||||
self.post(self.URL, headers=headers, params={"message": msg})
|
||||
|
||||
|
||||
|
@ -1406,6 +1445,7 @@ class Gotify(HttpTransport):
|
|||
ctx = {
|
||||
"check": flip.owner,
|
||||
"status": flip.new_status,
|
||||
"ping": self.last_ping(flip),
|
||||
"down_checks": self.down_checks(flip.owner),
|
||||
}
|
||||
payload = {
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
<td style="padding-right: 32px; padding-bottom: 8px; vertical-align: top;">
|
||||
<b>Total Pings</b><br>
|
||||
{{ check.n_pings }}
|
||||
{% if ping %}{{ ping.n }}{% else %}0{% endif %}
|
||||
{% if check.created %}(since {{ check.created|date:'M j, Y' }}){% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
{% line %}Time Zone: {{ check.tz }}{% endline %}
|
||||
{% endif %}
|
||||
|
||||
{% line %}Total pings: {{ check.n_pings }} {% if check.created %}(since {{ check.created|date:'M j, Y' }}){% endif %}{% endline %}
|
||||
{% line %}Total pings: {% if ping %}{{ ping.n }}{% else %}0{% endif %} {% if check.created %}(since {{ check.created|date:'M j, Y' }}){% endif %}{% endline %}
|
||||
|
||||
{% if ping %}
|
||||
{% line %}Last ping: {{ ping.created|naturaltime }}{% if ping.remote_addr %}, from {{ ping.remote_addr }}{% endif %}{% endline %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% load humanize %}
|
||||
{{ check.name_then_code }} is {{ status|upper }}.
|
||||
{% if status == "down" and check.last_ping %}
|
||||
Last ping was {{ check.last_ping|naturaltime }}.
|
||||
{% if status == "down" and ping %}
|
||||
Last ping was {{ ping.created|naturaltime }}.
|
||||
{% endif %}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% load humanize linemode %}{% linemode %}
|
||||
{% if status == "down" %}
|
||||
{% line %}🔴 The check [{{ check.name_then_code }}]({{ check.cloaked_url }}) is **DOWN**.{% if check.last_ping %} Last ping was {{ check.last_ping|naturaltime }}.{% endif %}{% endline %}
|
||||
{% line %}🔴 The check [{{ check.name_then_code }}]({{ check.cloaked_url }}) is **DOWN**.{% if ping %} Last ping was {{ ping.created|naturaltime }}.{% endif %}{% endline %}
|
||||
{% else %}
|
||||
{% line %}🟢 The check [{{ check.name_then_code }}]({{ check.cloaked_url }}) is now **UP**.{% endline %}
|
||||
{% endif %}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% load humanize %}
|
||||
{% if status == "down" %}
|
||||
The check "{{ check.name_then_code|safe }}" is DOWN.{% if check.last_ping %} Last ping was {{ check.last_ping|naturaltime }}.{% endif %}
|
||||
The check "{{ check.name_then_code|safe }}" is DOWN.{% if ping %} Last ping was {{ ping.created|naturaltime }}.{% endif %}
|
||||
{% else %}
|
||||
The check "{{ check.name_then_code|safe }}" is now UP.
|
||||
{% endif %}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% load humanize %}
|
||||
{% if status == "down" %}
|
||||
{{ check.name_then_code }} is DOWN.{% if check.last_ping %} Last ping was {{ check.last_ping|naturaltime }}.{% endif %}
|
||||
{{ check.name_then_code }} is DOWN.{% if ping %} Last ping was {{ ping.created|naturaltime }}.{% endif %}
|
||||
{% else %}
|
||||
{{ check.name_then_code }} is now UP.
|
||||
{% endif %}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% load humanize %}
|
||||
{% if status == "down" %}
|
||||
🔴 <b>{{ check.name_then_code }}</b> is <b>DOWN</b>.{% if check.last_ping %} Last ping was {{ check.last_ping|naturaltime }}.{% endif %}
|
||||
🔴 <b>{{ check.name_then_code }}</b> is <b>DOWN</b>.{% if ping %} Last ping was {{ ping.created|naturaltime }}.{% endif %}
|
||||
{% else %}
|
||||
🟢 <b>{{ check.name_then_code }}</b> is now <b>UP</b>.
|
||||
{% endif %}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
{% line %}Time Zone: {{ check.tz }}{% endline %}
|
||||
{% endif %}
|
||||
|
||||
{% line %}Total Pings: {{ check.n_pings }}{% endline %}
|
||||
{% line %}Total Pings: {% if ping %}{{ ping.n }}{% else %}0{% endif %}{% endline %}
|
||||
|
||||
{% if ping is None %}
|
||||
{% line %}Last Ping: Never{% endline %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load hc_extras humanize %}
|
||||
The check "{{ check.name_then_code }}" is DOWN.
|
||||
{% if check.kind == "simple" %}Expecting to receive a ping every {{ check.timeout|hc_duration }}.{% endif %}
|
||||
{% if check.last_ping %}Last ping was {{ check.last_ping|naturaltime }}.{% endif %}
|
||||
{% if ping %}Last ping was {{ ping.created|naturaltime }}.{% endif %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load hc_extras humanize %}
|
||||
|
||||
{% if check.kind == "simple" %}Expecting to receive a ping every {{ check.timeout|hc_duration }}.{% endif %}
|
||||
{% if check.last_ping %}Last ping was {{ check.last_ping|naturaltime }}.{% endif %}
|
||||
{% if ping %}Last ping was {{ ping.created|naturaltime }}.{% endif %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% load humanize %}
|
||||
{{ check.name_then_code }} is {{ status|upper }}.
|
||||
{% if status == "down" and check.last_ping %}
|
||||
Last ping was {{ check.last_ping|naturaltime }}.
|
||||
{% if status == "down" and ping %}
|
||||
Last ping was {{ ping.created|naturaltime }}.
|
||||
{% endif %}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% load humanize %}
|
||||
{% if check.last_ping %}
|
||||
{{ check.last_ping|naturaltime }}
|
||||
{% if ping %}
|
||||
{{ ping.created|naturaltime }}
|
||||
{% else %}
|
||||
Never
|
||||
{% endif %}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% load humanize %}
|
||||
|
||||
{% if status == "down" %}
|
||||
The check "{{ check.name_then_code|safe }}" is DOWN.{% if check.last_ping %} Last ping was {{ check.last_ping|naturaltime }}.{% endif %}
|
||||
The check "{{ check.name_then_code|safe }}" is DOWN.{% if ping %} Last ping was {{ ping.created|naturaltime }}.{% endif %}
|
||||
{% else %}
|
||||
The check "{{ check.name_then_code|safe }}" received a ping and is now UP.
|
||||
{% endif %}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
{% line %}<b>Time Zone:</b> {{ check.tz }}{% endline %}
|
||||
{% endif %}
|
||||
|
||||
{% line %}<b>Total Pings:</b> {{ check.n_pings }}{% endline %}
|
||||
{% line %}<b>Total Pings:</b> {% if ping %}{{ ping.n }}{% else %}0{% endif %}{% endline %}
|
||||
|
||||
{% if ping is None %}
|
||||
{% line %}<b>Last Ping:</b> Never{% endline %}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
{% line %}<b>Time Zone:</b> {{ check.tz }}{% endline %}
|
||||
{% endif %}
|
||||
|
||||
{% line %}<b>Total Pings:</b> {{ check.n_pings }}{% endline %}
|
||||
{% line %}<b>Total Pings:</b> {% if ping %}{{ ping.n }}{% else %}0{% endif %}{% endline %}
|
||||
|
||||
{% if ping is None %}
|
||||
{% line %}<b>Last Ping:</b> Never{% endline %}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% load humanize %}
|
||||
{% if status == "down" %}
|
||||
{{ site_name }}: The check "{{ check.name_then_code|safe }}" is DOWN.{% if check.last_ping %} Last ping was {{ check.last_ping|naturaltime }}.{% endif %}
|
||||
{{ site_name }}: The check "{{ check.name_then_code|safe }}" is DOWN.{% if ping %} Last ping was {{ ping.created|naturaltime }}.{% endif %}
|
||||
{% else %}
|
||||
{{ site_name }}: The check "{{ check.name_then_code|safe }}" is UP.
|
||||
{% endif %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% load humanize %}
|
||||
{{ check.name_then_code|safe }} is {{ status|upper }}.
|
||||
{% if status == "down" and check.last_ping %}
|
||||
Last ping was {{ check.last_ping|naturaltime }}.
|
||||
{% if status == "down" and ping %}
|
||||
Last ping was {{ ping.created|naturaltime }}.
|
||||
{% endif %}
|
|
@ -23,7 +23,7 @@
|
|||
{% line %}<b>Time Zone:</b> {{ check.tz }}{% endline %}
|
||||
{% endif %}
|
||||
|
||||
{% line %}<b>Total Pings:</b> {{ check.n_pings }}{% endline %}
|
||||
{% line %}<b>Total Pings:</b> {% if ping %}{{ ping.n }}{% else %}0{% endif %}{% endline %}
|
||||
|
||||
{% if ping is None %}
|
||||
{% line %}<b>Last Ping:</b> Never{% endline %}
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
**Time Zone:** {{ check.tz }}
|
||||
{% endif %}
|
||||
|
||||
**Last Ping:** {{ check.last_ping|naturaltime|default:"never" }}
|
||||
**Last Ping:** {% if ping %}{{ ping.created|naturaltime }}{% else %}never{% endif %}
|
||||
|
||||
[Full Details @ {% site_name %}]({{ check.cloaked_url }})
|
|
@ -1,7 +1,7 @@
|
|||
{% load humanize %}
|
||||
{% if status == "down" %}
|
||||
{{ check.name_then_code|safe }} is DOWN.
|
||||
{% if check.last_ping %}Last ping was {{ check.last_ping|naturaltime }}.{% endif %}
|
||||
{% if ping %}Last ping was {{ ping.created|naturaltime }}.{% endif %}
|
||||
{% else %}
|
||||
{{ check.name_then_code|safe }} received a ping and is now UP
|
||||
{% endif %}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% load hc_extras humanize %}
|
||||
|
||||
[{{ check.name_then_code }}]({{ check.cloaked_url }}) is **{{ status|upper }}**. {% if status == "down" and check.last_ping %}Last ping was {{ check.last_ping|naturaltime }}.{% endif %}
|
||||
[{{ check.name_then_code }}]({{ check.cloaked_url }}) is **{{ status|upper }}**. {% if status == "down" and ping %}Last ping was {{ ping.created|naturaltime }}.{% endif %}
|
||||
|
||||
{% if check.desc %}
|
||||
---
|
||||
|
|
Loading…
Add table
Reference in a new issue