diff --git a/CHANGELOG.md b/CHANGELOG.md index 545140f1..24db3641 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. - Show sub-second durations with higher precision, 2 digits after decimal point (#321) - Replace the gear icon with three horizontal dots icon (#322) - Add a Pause button in the checks list (#312) +- Documentation in Markdown ### Bug Fixes - Increase the allowable length of Matrix room alias to 100 (#320) diff --git a/hc/front/management/commands/render_docs.py b/hc/front/management/commands/render_docs.py new file mode 100644 index 00000000..3415da87 --- /dev/null +++ b/hc/front/management/commands/render_docs.py @@ -0,0 +1,29 @@ +import os + +from django.conf import settings +from django.core.management.base import BaseCommand +import markdown + + +class Command(BaseCommand): + help = "Renders Markdown to HTML" + + def handle(self, *args, **options): + extensions = ["fenced_code", "codehilite", "tables"] + ec = {"codehilite": {"css_class": "highlight"}} + + docs_path = os.path.join(settings.BASE_DIR, "templates/docs") + for doc in os.listdir(docs_path): + if not doc.endswith(".md"): + continue + + print("Rendering %s" % doc) + + src_path = os.path.join(docs_path, doc) + dst_path = os.path.join(docs_path, doc[:-3] + ".html") + + text = open(src_path, "r", encoding="utf-8").read() + html = markdown.markdown(text, extensions=extensions, extension_configs=ec) + + with open(dst_path, "w", encoding="utf-8") as f: + f.write(html) diff --git a/hc/front/urls.py b/hc/front/urls.py index 68df1844..55142d5b 100644 --- a/hc/front/urls.py +++ b/hc/front/urls.py @@ -76,4 +76,5 @@ urlpatterns = [ path("docs/api/", views.docs_api, name="hc-docs-api"), path("docs/cron/", views.docs_cron, name="hc-docs-cron"), path("docs/resources/", views.docs_resources, name="hc-docs-resources"), + path("docs//", views.serve_doc, name="hc-serve-doc"), ] diff --git a/hc/front/views.py b/hc/front/views.py index 93474128..c34c53a8 100644 --- a/hc/front/views.py +++ b/hc/front/views.py @@ -1,5 +1,6 @@ from datetime import datetime, timedelta as td import json +import os from urllib.parse import urlencode from croniter import croniter @@ -276,6 +277,28 @@ def docs(request): return render(request, "front/docs.html", ctx) +def serve_doc(request, doc): + path = os.path.join(settings.BASE_DIR, "templates/docs", doc + ".html") + if not os.path.exists(path): + raise Http404("not found") + + content = open(path, "r", encoding="utf-8").read() + content = content.replace("SITE_NAME", settings.SITE_NAME) + content = content.replace("PING_URL", settings.PING_ENDPOINT + "your-uuid-here") + content = content.replace( + "PING_EMAIL", "your-uuid-here@%s" % settings.PING_EMAIL_DOMAIN + ) + + ctx = { + "page": "docs", + "section": "home", + "section": doc, + "content": content, + } + + return render(request, "front/docs_single.html", ctx) + + def docs_api(request): ctx = { "page": "docs", @@ -290,8 +313,7 @@ def docs_api(request): def docs_cron(request): - ctx = {"page": "docs", "section": "cron"} - return render(request, "front/docs_cron.html", ctx) + return render(request, "front/docs_cron.html", {}) def docs_resources(request): diff --git a/static/css/channels.css b/static/css/channels.css index ad21fdfc..b4f2c3f9 100644 --- a/static/css/channels.css +++ b/static/css/channels.css @@ -192,7 +192,7 @@ table.channels-table > tbody > tr > th { float: left; font-size: 24px; width: 48px; - heigth: 48px; + height: 48px; background: #7ec1ea; border-radius: 32px; text-align: center; diff --git a/static/css/docs.css b/static/css/docs.css index f6b70a5c..0cbf9752 100644 --- a/static/css/docs.css +++ b/static/css/docs.css @@ -4,9 +4,18 @@ list-style: none; } -.docs-nav li a { +.docs-nav li { display: block; - padding-bottom: 10px; + margin-bottom: 10px; +} + +.docs-nav li.nav-header { + color: #333; + font-weight: bold; +} + +li + li.nav-header { + margin-top: 20px; } .docs-nav li.active > a { @@ -74,3 +83,11 @@ a.section:hover { border-radius: 4px; } +.docs-content li { + line-height: 2; +} + +.docs-content img { + max-width: 100%; + border: 6px solid #DDD; +} diff --git a/templates/base.html b/templates/base.html index 3cde5167..9c460703 100644 --- a/templates/base.html +++ b/templates/base.html @@ -124,7 +124,7 @@ {% endif %}
  • - Docs + Docs
  • {% if request.user.is_authenticated %} diff --git a/templates/docs/bash.html b/templates/docs/bash.html new file mode 100644 index 00000000..9d2ddd97 --- /dev/null +++ b/templates/docs/bash.html @@ -0,0 +1,34 @@ +

    Shell scripts

    +

    You can easily add SITE_NAME monitoring to a shell script. All you +have to do is make a HTTP request at the end of the script. curl and wget +are two common command line HTTP clients for that.

    +

    Using curl

    +
    #!/bin/sh
    +
    +# Exit immediately if any command exits with a non-zero status:
    +set -e
    +
    +# Do the work here
    +echo "Pretending to to make backups..."
    +sleep 5
    +echo "Backup complete!"
    +
    +# As the last thing, ping SITE_NAME using curl:
    +curl --retry 3 PING_URL
    +
    + + +

    Using wget

    +
    #!/bin/sh
    +
    +# Exit immediately if any command exits with a non-zero status:
    +set -e
    +
    +# Do the work here
    +echo "Pretending to to generate reports..."
    +sleep 5
    +echo "Report generation complete!"
    +
    +# As the last thing, ping SITE_NAME using wget:
    +wget PING_URL -O /dev/null
    +
    \ No newline at end of file diff --git a/templates/docs/bash.md b/templates/docs/bash.md new file mode 100644 index 00000000..05f9b660 --- /dev/null +++ b/templates/docs/bash.md @@ -0,0 +1,39 @@ +# Shell scripts + +You can easily add SITE_NAME monitoring to a shell script. All you +have to do is make a HTTP request at the end of the script. curl and wget +are two common command line HTTP clients for that. + +## Using curl + +```bash hl_lines="12" +#!/bin/sh + +# Exit immediately if any command exits with a non-zero status: +set -e + +# Do the work here +echo "Pretending to to make backups..." +sleep 5 +echo "Backup complete!" + +# As the last thing, ping SITE_NAME using curl: +curl --retry 3 PING_URL +``` + +## Using wget + +```bash hl_lines="12" +#!/bin/sh + +# Exit immediately if any command exits with a non-zero status: +set -e + +# Do the work here +echo "Pretending to to generate reports..." +sleep 5 +echo "Report generation complete!" + +# As the last thing, ping SITE_NAME using wget: +wget PING_URL -O /dev/null +``` \ No newline at end of file diff --git a/templates/docs/csharp.html b/templates/docs/csharp.html new file mode 100644 index 00000000..ebfb87c6 --- /dev/null +++ b/templates/docs/csharp.html @@ -0,0 +1,7 @@ +

    C

    +

    Below is an example of making a HTTP request to SITE_NAME from C#.

    +
    using (var client = new System.Net.WebClient())
    +{
    +       client.DownloadString("PING_URL");
    +}
    +
    \ No newline at end of file diff --git a/templates/docs/csharp.md b/templates/docs/csharp.md new file mode 100644 index 00000000..af60190e --- /dev/null +++ b/templates/docs/csharp.md @@ -0,0 +1,10 @@ +# C# + +Below is an example of making a HTTP request to SITE_NAME from C#. + +```csharp +using (var client = new System.Net.WebClient()) +{ + client.DownloadString("PING_URL"); +} +``` \ No newline at end of file diff --git a/templates/docs/email.html b/templates/docs/email.html new file mode 100644 index 00000000..1d1aab8b --- /dev/null +++ b/templates/docs/email.html @@ -0,0 +1,12 @@ +

    Email

    +

    As an alternative to HTTP/HTTPS requests, you can "ping" checks by +sending an emails to special email addresses.

    +

    Use Case: Email Delivery Monitoring

    +

    Consider a cron job which runs weekly and sends weekly email +reports to a list of e-mail addresses. You have already set up a check to get alerted +when your cron job fails to run. But what you ultimately want to check is if +your emails are getting sent and delivered.

    +

    The solution: set up another check, and add its email address to your list of +recipient email addresses. Set its Period to 1 week. As long as your weekly email +script runs correctly, and there are no email delivery issues, +SITE_NAME will regularly receive an email, and the check and will stay up.

    \ No newline at end of file diff --git a/templates/docs/email.md b/templates/docs/email.md new file mode 100644 index 00000000..352787c8 --- /dev/null +++ b/templates/docs/email.md @@ -0,0 +1,16 @@ +# Email + +As an alternative to HTTP/HTTPS requests, you can "ping" checks by +sending an emails to special email addresses. + +## Use Case: Email Delivery Monitoring + +Consider a cron job which runs weekly and sends weekly email +reports to a list of e-mail addresses. You have already set up a check to get alerted +when your cron job fails to run. But what you ultimately want to check is if +**your emails are getting sent and delivered**. + +The solution: set up another check, and add its email address to your list of +recipient email addresses. Set its Period to 1 week. As long as your weekly email +script runs correctly, and there are no email delivery issues, +SITE_NAME will regularly receive an email, and the check and will stay up. diff --git a/templates/docs/introduction.html b/templates/docs/introduction.html new file mode 100644 index 00000000..869f03f0 --- /dev/null +++ b/templates/docs/introduction.html @@ -0,0 +1,26 @@ +

    SITE_NAME

    +

    SITE_NAME is a service for monitoring cron jobs and similar periodic processes:

    + +

    SITE_NAME works as a dead man's switch for processes that need to +run continuously or on regular, known schedule:

    + +

    SITE_NAME is not the right tool for:

    + \ No newline at end of file diff --git a/templates/docs/introduction.md b/templates/docs/introduction.md new file mode 100644 index 00000000..0b362572 --- /dev/null +++ b/templates/docs/introduction.md @@ -0,0 +1,26 @@ +## SITE_NAME + +SITE_NAME is a service for monitoring cron jobs and similar periodic processes: + +* SITE_NAME **listens for pings** from services being monitored. +* It **keeps silent** as long as pings arrive on time. +* It **raises an alert** as soon as a ping does not arrive on time. + +SITE_NAME works as a [dead man's switch](https://en.wikipedia.org/wiki/Dead_man%27s_switch) for processes that need to +run continuously or on regular, known schedule: + +* filesystem, database backups +* task queues +* database replication status +* report generation scripts +* periodic data import and sync jobs +* periodic antivirus scans +* DDNS updater scripts +* SSL renewal scripts + +SITE_NAME is *not* the right tool for: + +* monitoring website uptime by probing it with HTTP requests +* collecting application performance metrics +* error tracking +* log aggregation diff --git a/templates/docs/javascript.html b/templates/docs/javascript.html new file mode 100644 index 00000000..2dd7ee40 --- /dev/null +++ b/templates/docs/javascript.html @@ -0,0 +1,13 @@ +

    Javascript

    +

    Below is an example of making a HTTP request to SITE_NAME from Node.js.

    +
    var https = require('https');
    +https.get("PING_URL");
    +
    + + +

    You can also send pings from a browser environment. SITE_NAME sets the +Access-Control-Allow-Origin:* CORS header, so cross-domain AJAX requests work.

    +
    var xhr = new XMLHttpRequest();
    +xhr.open('GET', 'PING_URL', true);
    +xhr.send(null);
    +
    \ No newline at end of file diff --git a/templates/docs/javascript.md b/templates/docs/javascript.md new file mode 100644 index 00000000..28881533 --- /dev/null +++ b/templates/docs/javascript.md @@ -0,0 +1,17 @@ +# Javascript + +Below is an example of making a HTTP request to SITE_NAME from Node.js. + +```js +var https = require('https'); +https.get("PING_URL"); +``` + +You can also send pings from a browser environment. SITE_NAME sets the +`Access-Control-Allow-Origin:*` CORS header, so cross-domain AJAX requests work. + +```js +var xhr = new XMLHttpRequest(); +xhr.open('GET', 'PING_URL', true); +xhr.send(null); +``` diff --git a/templates/docs/measuring_script_run_time.html b/templates/docs/measuring_script_run_time.html new file mode 100644 index 00000000..1c77ecb7 --- /dev/null +++ b/templates/docs/measuring_script_run_time.html @@ -0,0 +1,30 @@ +

    Measuring Script Run Time

    +

    Append /start to a ping URL and use it to signal when a job starts. + After receiving a start signal, Healthchecks.io will show the check as "Started". + It will store the "start" events and display the job execution times. The job + execution times are calculated as the time gaps between adjacent "start" and + "complete" events.

    +

    Signalling a start kicks off a separate timer: the job now must signal a +success within its configured "Grace Time", or it will get marked as "down".

    +

    Below is a code example in Python:

    +
    import requests
    +URL = "PING_URL"
    +
    +
    +# "/start" kicks off a timer: if the job takes longer than
    +# the configured grace time, the check will be marked as "down"
    +try:
    +    requests.get(URL + "/start", timeout=5)
    +except requests.exceptions.RequestException:
    +    # If the network request fails for any reason, we don't want
    +    # it to prevent the main job from running
    +    pass
    +
    +
    +# TODO: run the job here
    +fib = lambda n: n if n < 2 else fib(n - 1) + fib(n - 2)
    +print("F(42) = %d" % fib(42))
    +
    +# Signal success:
    +requests.get(URL)
    +
    \ No newline at end of file diff --git a/templates/docs/measuring_script_run_time.md b/templates/docs/measuring_script_run_time.md new file mode 100644 index 00000000..fb289bf0 --- /dev/null +++ b/templates/docs/measuring_script_run_time.md @@ -0,0 +1,35 @@ +# Measuring Script Run Time + + Append `/start` to a ping URL and use it to signal when a job starts. + After receiving a start signal, Healthchecks.io will show the check as "Started". + It will store the "start" events and display the job execution times. The job + execution times are calculated as the time gaps between adjacent "start" and + "complete" events. + +Signalling a start kicks off a separate timer: the job now **must** signal a +success within its configured "Grace Time", or it will get marked as "down". + +Below is a code example in Python: + +```python +import requests +URL = "PING_URL" + + +# "/start" kicks off a timer: if the job takes longer than +# the configured grace time, the check will be marked as "down" +try: + requests.get(URL + "/start", timeout=5) +except requests.exceptions.RequestException: + # If the network request fails for any reason, we don't want + # it to prevent the main job from running + pass + + +# TODO: run the job here +fib = lambda n: n if n < 2 else fib(n - 1) + fib(n - 2) +print("F(42) = %d" % fib(42)) + +# Signal success: +requests.get(URL) +``` diff --git a/templates/docs/monitoring_cron_jobs.html b/templates/docs/monitoring_cron_jobs.html new file mode 100644 index 00000000..eef612db --- /dev/null +++ b/templates/docs/monitoring_cron_jobs.html @@ -0,0 +1,109 @@ +

    Monitoring Cron Jobs

    +

    SITE_NAME is perfectly suited for monitoring cron jobs. +Let's look at an example: a machine with the following cron job:

    +
    $ crontab -l
    +# m h dom mon dow command
    +  8 6 * * * /home/user/backup.sh
    +
    + + +

    You can use SITE_NAME to get a notification whenever the backup.sh script does not +complete successfully. Here is how to set that up.

    +
      +
    1. +

      If you have not already, sign up for a free SITE_NAME account.

      +
    2. +
    3. +

      In your SITE_NAME account, add a new check.

      +

      Note: in SITE_NAME, a check represents a single service you want to +monitor. For example, a single cron job. For each additional cron job you will +create another check. SITE_NAME pricing plans are structured primarily +around how many checks you can have in the account.

      +
    4. +
    5. +

      Give the check a meaningful name. Good naming will become +increasingly important as you add more checks to your account.

      +
    6. +
    7. +

      Edit the check's schedule:

      +
        +
      • change its type from "Simple" to "Cron"
      • +
      • enter 8 6 * * * in the cron epression field
      • +
      • set the timezone to match your machine's timezone
      • +
      +
    8. +
    9. +

      Take note of your check's unique ping URL

      +
    10. +
    +

    Finally, edit your crontab and append a curl or wget call after the command:

    +
    $ crontab -e
    +# m h dom mon dow command
    +  8 6 * * * /home/user/backup.sh && curl -fsS --retry 3 PING_URL > /dev/null
    +
    + + +

    Now, each time your cron job runs, it will send a HTTP request to the ping URL.

    +

    Since SITE_NAME knows the schedule of your cron job, it can calculate +the dates and times when the job should run. As soon as your cron job doesn't +report at an expected time, SITE_NAME will send you a notification.

    +

    This monitoring technique takes care of various failure scenarios that could +potentially go unnoticed otherwise:

    + +

    Curl Options

    +

    The extra options tells curl to not print anything to standard output unless +there is an error. Feel free to adjust the curl options to suit your needs.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    &&Run curl only if /home/user/backup.sh exits with an exit code 0
    + -f, --fail + Makes curl treat non-200 responses as errors
    -s, --silentSilent or quiet mode. Don't show progress meter or error messages.
    -S, --show-errorWhen used with -s it makes curl show error message if it fails.
    --retry <num> + If a transient error is returned when curl tries to perform a + transfer, it will retry this number of times before giving up. + Setting the number to 0 makes curl do no retries + (which is the default). Transient error means either: a timeout, + an FTP 4xx response code or an HTTP 5xx response code. +
    > /dev/null + Redirect curl's stdout to /dev/null (error messages go to stderr,) +
    + +

    Looking up Your Machine's Time Zone

    +

    On modern GNU/Linux systems, you can look up the time zone using the +timedatectl status command and looking for "Time zone" in its output:

    +
    $ timedatectl status
    +
    +               Local time: C  2020-01-23 12:35:50 EET
    +           Universal time: C  2020-01-23 10:35:50 UTC
    +                 RTC time: C  2020-01-23 10:35:50
    +                Time zone: Europe/Riga (EET, +0200)
    +System clock synchronized: yes
    +              NTP service: active
    +          RTC in local TZ: no
    +
    \ No newline at end of file diff --git a/templates/docs/monitoring_cron_jobs.md b/templates/docs/monitoring_cron_jobs.md new file mode 100644 index 00000000..a286e378 --- /dev/null +++ b/templates/docs/monitoring_cron_jobs.md @@ -0,0 +1,113 @@ +## Monitoring Cron Jobs + +SITE_NAME is perfectly suited for monitoring cron jobs. +Let's look at an example: a machine with the following cron job: + +```bash +$ crontab -l +# m h dom mon dow command + 8 6 * * * /home/user/backup.sh +``` + +You can use SITE_NAME to get a notification whenever the `backup.sh` script does not +complete successfully. Here is how to set that up. + +1. If you have not already, sign up for a free SITE_NAME account. + +1. In your SITE_NAME account, **add a new check**. + + Note: in SITE_NAME, a **check** represents a single service you want to + monitor. For example, a single cron job. For each additional cron job you will + create another check. SITE_NAME pricing plans are structured primarily + around how many checks you can have in the account. + +1. Give the check **a meaningful name**. Good naming will become +increasingly important as you add more checks to your account. + +1. Edit the check's **schedule**: + + * change its type from "Simple" to "Cron" + * enter `8 6 * * *` in the cron epression field + * set the timezone to match your machine's timezone + +1. Take note of your check's unique **ping URL** + +Finally, edit your crontab and append a curl or wget call after the command: + +```bash +$ crontab -e +# m h dom mon dow command + 8 6 * * * /home/user/backup.sh && curl -fsS --retry 3 PING_URL > /dev/null +``` + +Now, each time your cron job runs, it will send a HTTP request to the ping URL. + +Since SITE_NAME knows the schedule of your cron job, it can calculate +the dates and times when the job should run. As soon as your cron job doesn't +report at an expected time, SITE_NAME will send you a notification. + +This monitoring technique takes care of various failure scenarios that could +potentially go unnoticed otherwise: + +* The whole machine goes down (power outage, janitor stumbles on wires, VPS provider problems, etc.) +* cron daemon is not running, or has invalid configuration +* cron does start your task, but the task exits with non-zero exit code + +## Curl Options + +The extra options tells curl to not print anything to standard output unless +there is an error. Feel free to adjust the curl options to suit your needs. + + + + + + + + + + + + + + + + + + + + + + + + + + +
    &&Run curl only if /home/user/backup.sh exits with an exit code 0
    + -f, --fail + Makes curl treat non-200 responses as errors
    -s, --silentSilent or quiet mode. Don't show progress meter or error messages.
    -S, --show-errorWhen used with -s it makes curl show error message if it fails.
    --retry <num> + If a transient error is returned when curl tries to perform a + transfer, it will retry this number of times before giving up. + Setting the number to 0 makes curl do no retries + (which is the default). Transient error means either: a timeout, + an FTP 4xx response code or an HTTP 5xx response code. +
    > /dev/null + Redirect curl's stdout to /dev/null (error messages go to stderr,) +
    + +## Looking up Your Machine's Time Zone + +On modern GNU/Linux systems, you can look up the time zone using the +`timedatectl status` command and looking for "Time zone" in its output: + +```text hl_lines="6" +$ timedatectl status + + Local time: C  2020-01-23 12:35:50 EET + Universal time: C  2020-01-23 10:35:50 UTC + RTC time: C  2020-01-23 10:35:50 + Time zone: Europe/Riga (EET, +0200) +System clock synchronized: yes + NTP service: active + RTC in local TZ: no +``` \ No newline at end of file diff --git a/templates/docs/php.html b/templates/docs/php.html new file mode 100644 index 00000000..0901a278 --- /dev/null +++ b/templates/docs/php.html @@ -0,0 +1,4 @@ +

    PHP

    +

    Below is an example of making a HTTP request to SITE_NAME from PHP.

    +
    file_get_contents('https://hc-ping.com/your-uuid-here');
    +
    \ No newline at end of file diff --git a/templates/docs/php.md b/templates/docs/php.md new file mode 100644 index 00000000..be674a48 --- /dev/null +++ b/templates/docs/php.md @@ -0,0 +1,7 @@ +# PHP + +Below is an example of making a HTTP request to SITE_NAME from PHP. + +```php +file_get_contents('https://hc-ping.com/your-uuid-here'); +``` \ No newline at end of file diff --git a/templates/docs/powershell.html b/templates/docs/powershell.html new file mode 100644 index 00000000..f14dfe4b --- /dev/null +++ b/templates/docs/powershell.html @@ -0,0 +1,23 @@ +

    PowerShell

    +

    You can use PowerShell + and Windows Task Scheduler to automate various tasks on a Windows system. + From within a PowerShell script it is also easy to ping SITE_NAME.

    +

    Here is a simple PowerShell script that pings SITE_NAME. When scheduled to +run with Task Scheduler, it will essentially just send regular "I'm alive" messages. +You can of course extend it to do more things.

    +
    # inside a PowerShell script:
    +Invoke-RestMethod PING_URL
    +
    + + +

    Save the above to e.g. C:\Scripts\healthchecks.ps1. +Then use the following command in a Scheduled Task to run the script:

    +
    powershell.exe -ExecutionPolicy bypass -File C:\Scripts\healthchecks.ps1
    +
    + + +

    In simple cases, you can also pass the script to PowerShell directly, +using the "-command" argument:

    +
    # Without an underlying script, passing the command to PowerShell directly:
    +powershell.exe -command &{Invoke-RestMethod PING_URL}
    +
    \ No newline at end of file diff --git a/templates/docs/powershell.md b/templates/docs/powershell.md new file mode 100644 index 00000000..84d51ee8 --- /dev/null +++ b/templates/docs/powershell.md @@ -0,0 +1,29 @@ +# PowerShell + + You can use [PowerShell](https://msdn.microsoft.com/en-us/powershell/mt173057.aspx) + and Windows Task Scheduler to automate various tasks on a Windows system. + From within a PowerShell script it is also easy to ping SITE_NAME. + +Here is a simple PowerShell script that pings SITE_NAME. When scheduled to +run with Task Scheduler, it will essentially just send regular "I'm alive" messages. +You can of course extend it to do more things. + +```bash +# inside a PowerShell script: +Invoke-RestMethod PING_URL +``` + +Save the above to e.g. `C:\Scripts\healthchecks.ps1`. +Then use the following command in a Scheduled Task to run the script: + +```bash +powershell.exe -ExecutionPolicy bypass -File C:\Scripts\healthchecks.ps1 +``` + +In simple cases, you can also pass the script to PowerShell directly, +using the "-command" argument: + +```bash +# Without an underlying script, passing the command to PowerShell directly: +powershell.exe -command &{Invoke-RestMethod PING_URL} +``` diff --git a/templates/docs/python.html b/templates/docs/python.html new file mode 100644 index 00000000..7a490b98 --- /dev/null +++ b/templates/docs/python.html @@ -0,0 +1,32 @@ +

    Python

    +

    If you are already using the requests library, it's convenient to also use it here:

    +
    # using requests:
    +import requests
    +requests.get("PING_URL")
    +
    + + +

    Otherwise, you can use the urllib standard module.

    +
    # urllib with python 3.x:
    +import urllib.request
    +urllib.request.urlopen("PING_URL")
    +
    + + +
    # urllib with python 2.x:
    +import urllib
    +urllib.urlopen("PING_URL")
    +
    + + +

    You can include additional diagnostic information in the in the request body (for POST requests), or in the "User-Agent" request header:

    +
    # Passing diagnostic information in the POST body:
    +import requests
    +requests.post("PING_URL", data="temperature=-7")
    +
    + + +
    # Passing diagnostic information in the User-Agent header:
    +import requests
    +requests.get("PING_URL", headers={"User-Agent": "temperature=-7"})
    +
    \ No newline at end of file diff --git a/templates/docs/python.md b/templates/docs/python.md new file mode 100644 index 00000000..809643ca --- /dev/null +++ b/templates/docs/python.md @@ -0,0 +1,37 @@ +# Python + +If you are already using the requests library, it's convenient to also use it here: + +```python +# using requests: +import requests +requests.get("PING_URL") +``` + +Otherwise, you can use the urllib standard module. + +```python +# urllib with python 3.x: +import urllib.request +urllib.request.urlopen("PING_URL") +``` + +```python +# urllib with python 2.x: +import urllib +urllib.urlopen("PING_URL") +``` + +You can include additional diagnostic information in the in the request body (for POST requests), or in the "User-Agent" request header: + +```python +# Passing diagnostic information in the POST body: +import requests +requests.post("PING_URL", data="temperature=-7") +``` + +```python +# Passing diagnostic information in the User-Agent header: +import requests +requests.get("PING_URL", headers={"User-Agent": "temperature=-7"}) +``` diff --git a/templates/docs/ruby.html b/templates/docs/ruby.html new file mode 100644 index 00000000..e73e6b57 --- /dev/null +++ b/templates/docs/ruby.html @@ -0,0 +1,7 @@ +

    Ruby

    +

    Below is an example of making a HTTP request to SITE_NAME from Ruby.

    +
    require 'net/http'
    +require 'uri'
    +
    +Net::HTTP.get(URI.parse('PING_URL'))
    +
    \ No newline at end of file diff --git a/templates/docs/ruby.md b/templates/docs/ruby.md new file mode 100644 index 00000000..0b3e33f3 --- /dev/null +++ b/templates/docs/ruby.md @@ -0,0 +1,10 @@ +# Ruby + +Below is an example of making a HTTP request to SITE_NAME from Ruby. + +```ruby +require 'net/http' +require 'uri' + +Net::HTTP.get(URI.parse('PING_URL')) +``` \ No newline at end of file diff --git a/templates/docs/signalling_failures.html b/templates/docs/signalling_failures.html new file mode 100644 index 00000000..3d76b33c --- /dev/null +++ b/templates/docs/signalling_failures.html @@ -0,0 +1,24 @@ +

    Signalling failures

    +

    Append /fail to a ping URL and use it to actively signal a failure. +Requesting the /fail URL will immediately mark the check as "down". +You can use this feature to minimize the delay from your monitored service failing +to you getting a notification.

    +

    Below is a skeleton code example in Python which signals a failure when the +work function returns an unexpected value or throws an exception:

    +
    import requests
    +URL = "PING_URL"
    +
    +def do_work():
    +    # Do your number crunching, backup dumping, newsletter sending work here.
    +    # Return a truthy value on success.
    +    # Return a falsy value or throw an exception on failure.
    +    return True
    +
    +success = False
    +try:
    +    success = do_work()
    +finally:
    +    # On success, requests PING_URL
    +    # On failure, requests PING_URL/fail
    +    requests.get(URL if success else URL + "/fail")
    +
    \ No newline at end of file diff --git a/templates/docs/signalling_failures.md b/templates/docs/signalling_failures.md new file mode 100644 index 00000000..49fe04f9 --- /dev/null +++ b/templates/docs/signalling_failures.md @@ -0,0 +1,28 @@ +# Signalling failures + +Append `/fail` to a ping URL and use it to actively signal a failure. +Requesting the `/fail` URL will immediately mark the check as "down". +You can use this feature to minimize the delay from your monitored service failing +to you getting a notification. + +Below is a skeleton code example in Python which signals a failure when the +work function returns an unexpected value or throws an exception: + +```python +import requests +URL = "PING_URL" + +def do_work(): + # Do your number crunching, backup dumping, newsletter sending work here. + # Return a truthy value on success. + # Return a falsy value or throw an exception on failure. + return True + +success = False +try: + success = do_work() +finally: + # On success, requests PING_URL + # On failure, requests PING_URL/fail + requests.get(URL if success else URL + "/fail") +``` diff --git a/templates/front/base_docs.html b/templates/front/base_docs.html index 89c49a3a..f923ab0c 100644 --- a/templates/front/base_docs.html +++ b/templates/front/base_docs.html @@ -4,25 +4,39 @@ {% block content %}
    -
    +
      -
    • - How {% site_name %} Works -
    • -
    • - API Reference -
    • -
    • - Cron Syntax +
    • + {% include "front/docs_nav_item.html" with slug="introduction" title="Introduction" %} + {% include "front/docs_nav_item.html" with slug="monitoring_cron_jobs" title="Monitoring cron jobs" %} + {% include "front/docs_nav_item.html" with slug="signalling_failures" title="Signalling failures" %} + {% include "front/docs_nav_item.html" with slug="measuring_script_run_time" title="Measuring script run time" %} + + + {% include "front/docs_nav_item.html" with slug="bash" title="Bash" %} + {% include "front/docs_nav_item.html" with slug="python" title="Python" %} + {% include "front/docs_nav_item.html" with slug="ruby" title="Ruby" %} + {% include "front/docs_nav_item.html" with slug="php" title="PHP" %} + {% include "front/docs_nav_item.html" with slug="csharp" title="C#" %} + {% include "front/docs_nav_item.html" with slug="javascript" title="Javascript" %} + {% include "front/docs_nav_item.html" with slug="powershell" title="PowerShell" %} + {% include "front/docs_nav_item.html" with slug="email" title="Email" %} + + + + API -
    • - Third-Party Resources +
    • + Third-party resources
    • + + +
    • Cron Syntax Cheatsheet
    -
    +
    {% block docs_content %} {% endblock %}
    diff --git a/templates/front/docs_cron.html b/templates/front/docs_cron.html index 47a667a1..43927a14 100644 --- a/templates/front/docs_cron.html +++ b/templates/front/docs_cron.html @@ -1,4 +1,4 @@ -{% extends "front/base_docs.html" %} +{% extends "base.html" %} {% load hc_extras %} {% block title %}Cron Syntax Cheatsheet - {% site_name %}{% endblock %} @@ -11,7 +11,7 @@ {% endblock %} -{% block docs_content %} +{% block content %}

    Cron Syntax Cheatsheet

    diff --git a/templates/front/docs_nav_item.html b/templates/front/docs_nav_item.html new file mode 100644 index 00000000..4613cd12 --- /dev/null +++ b/templates/front/docs_nav_item.html @@ -0,0 +1,3 @@ + + {{ title }} + \ No newline at end of file diff --git a/templates/front/docs_single.html b/templates/front/docs_single.html new file mode 100644 index 00000000..7e2a3263 --- /dev/null +++ b/templates/front/docs_single.html @@ -0,0 +1,22 @@ +{% extends "front/base_docs.html" %} +{% load compress static hc_extras %} + +{% block title %}Documentation - {% site_name %}{% endblock %} +{% block description %} + +{% endblock %} +{% block keywords %} + +{% endblock %} + + +{% block docs_content %}
    {{ content|safe }}
    {% endblock %} + +{% block scripts %} +{% compress js %} + + + + +{% endcompress %} +{% endblock %}