@ -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) |
@ -0,0 +1,34 @@ | |||
<h1>Shell scripts</h1> | |||
<p>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.</p> | |||
<h2>Using curl</h2> | |||
<div class="highlight"><pre><span></span><span class="ch">#!/bin/sh</span> | |||
<span class="c1"># Exit immediately if any command exits with a non-zero status:</span> | |||
<span class="nb">set</span> -e | |||
<span class="c1"># Do the work here</span> | |||
<span class="nb">echo</span> <span class="s2">"Pretending to to make backups..."</span> | |||
sleep <span class="m">5</span> | |||
<span class="nb">echo</span> <span class="s2">"Backup complete!"</span> | |||
<span class="c1"># As the last thing, ping SITE_NAME using curl:</span> | |||
<span class="hll">curl --retry <span class="m">3</span> PING_URL | |||
</span></pre></div> | |||
<h2>Using wget</h2> | |||
<div class="highlight"><pre><span></span><span class="ch">#!/bin/sh</span> | |||
<span class="c1"># Exit immediately if any command exits with a non-zero status:</span> | |||
<span class="nb">set</span> -e | |||
<span class="c1"># Do the work here</span> | |||
<span class="nb">echo</span> <span class="s2">"Pretending to to generate reports..."</span> | |||
sleep <span class="m">5</span> | |||
<span class="nb">echo</span> <span class="s2">"Report generation complete!"</span> | |||
<span class="c1"># As the last thing, ping SITE_NAME using wget:</span> | |||
<span class="hll">wget PING_URL -O /dev/null | |||
</span></pre></div> |
@ -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 | |||
``` |
@ -0,0 +1,7 @@ | |||
<h1>C</h1> | |||
<p>Below is an example of making a HTTP request to SITE_NAME from C#.</p> | |||
<div class="highlight"><pre><span></span><span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">client</span> <span class="p">=</span> <span class="k">new</span> <span class="n">System</span><span class="p">.</span><span class="n">Net</span><span class="p">.</span><span class="n">WebClient</span><span class="p">())</span> | |||
<span class="p">{</span> | |||
<span class="n">client</span><span class="p">.</span><span class="n">DownloadString</span><span class="p">(</span><span class="s">"PING_URL"</span><span class="p">);</span> | |||
<span class="p">}</span> | |||
</pre></div> |
@ -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"); | |||
} | |||
``` |
@ -0,0 +1,12 @@ | |||
<h1>Email</h1> | |||
<p>As an alternative to HTTP/HTTPS requests, you can "ping" checks by | |||
sending an emails to special email addresses.</p> | |||
<h2>Use Case: Email Delivery Monitoring</h2> | |||
<p>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 | |||
<strong>your emails are getting sent and delivered</strong>.</p> | |||
<p>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.</p> |
@ -0,0 +1,16 @@ | |||
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. |
@ -0,0 +1,26 @@ | |||
<h2>SITE_NAME</h2> | |||
<p>SITE_NAME is a service for monitoring cron jobs and similar periodic processes:</p> | |||
<ul> | |||
<li>SITE_NAME <strong>listens for pings</strong> from services being monitored.</li> | |||
<li>It <strong>keeps silent</strong> as long as pings arrive on time.</li> | |||
<li>It <strong>raises an alert</strong> as soon as a ping does not arrive on time.</li> | |||
</ul> | |||
<p>SITE_NAME works as a <a href="https://en.wikipedia.org/wiki/Dead_man%27s_switch">dead man's switch</a> for processes that need to | |||
run continuously or on regular, known schedule:</p> | |||
<ul> | |||
<li>filesystem, database backups</li> | |||
<li>task queues</li> | |||
<li>database replication status</li> | |||
<li>report generation scripts</li> | |||
<li>periodic data import and sync jobs</li> | |||
<li>periodic antivirus scans</li> | |||
<li>DDNS updater scripts</li> | |||
<li>SSL renewal scripts</li> | |||
</ul> | |||
<p>SITE_NAME is <em>not</em> the right tool for:</p> | |||
<ul> | |||
<li>monitoring website uptime by probing it with HTTP requests</li> | |||
<li>collecting application performance metrics</li> | |||
<li>error tracking</li> | |||
<li>log aggregation</li> | |||
</ul> |
@ -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 |
@ -0,0 +1,13 @@ | |||
<h1>Javascript</h1> | |||
<p>Below is an example of making a HTTP request to SITE_NAME from Node.js.</p> | |||
<div class="highlight"><pre><span></span><span class="kd">var</span> <span class="nx">https</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'https'</span><span class="p">);</span> | |||
<span class="nx">https</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"PING_URL"</span><span class="p">);</span> | |||
</pre></div> | |||
<p>You can also send pings from a browser environment. SITE_NAME sets the | |||
<code>Access-Control-Allow-Origin:*</code> CORS header, so cross-domain AJAX requests work.</p> | |||
<div class="highlight"><pre><span></span><span class="kd">var</span> <span class="nx">xhr</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">XMLHttpRequest</span><span class="p">();</span> | |||
<span class="nx">xhr</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="s1">'GET'</span><span class="p">,</span> <span class="s1">'PING_URL'</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span> | |||
<span class="nx">xhr</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span> | |||
</pre></div> |
@ -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); | |||
``` |
@ -0,0 +1,30 @@ | |||
<h1>Measuring Script Run Time</h1> | |||
<p>Append <code>/start</code> 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.</p> | |||
<p>Signalling a start kicks off a separate timer: the job now <strong>must</strong> signal a | |||
success within its configured "Grace Time", or it will get marked as "down".</p> | |||
<p>Below is a code example in Python:</p> | |||
<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">requests</span> | |||
<span class="n">URL</span> <span class="o">=</span> <span class="s2">"PING_URL"</span> | |||
<span class="c1"># "/start" kicks off a timer: if the job takes longer than</span> | |||
<span class="c1"># the configured grace time, the check will be marked as "down"</span> | |||
<span class="k">try</span><span class="p">:</span> | |||
<span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">URL</span> <span class="o">+</span> <span class="s2">"/start"</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span> | |||
<span class="k">except</span> <span class="n">requests</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">RequestException</span><span class="p">:</span> | |||
<span class="c1"># If the network request fails for any reason, we don't want</span> | |||
<span class="c1"># it to prevent the main job from running</span> | |||
<span class="k">pass</span> | |||
<span class="c1"># TODO: run the job here</span> | |||
<span class="n">fib</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="k">if</span> <span class="n">n</span> <span class="o"><</span> <span class="mi">2</span> <span class="k">else</span> <span class="n">fib</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">fib</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> | |||
<span class="k">print</span><span class="p">(</span><span class="s2">"F(42) = </span><span class="si">%d</span><span class="s2">"</span> <span class="o">%</span> <span class="n">fib</span><span class="p">(</span><span class="mi">42</span><span class="p">))</span> | |||
<span class="c1"># Signal success:</span> | |||
<span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">URL</span><span class="p">)</span> | |||
</pre></div> |
@ -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) | |||
``` |
@ -0,0 +1,109 @@ | |||
<h2>Monitoring Cron Jobs</h2> | |||
<p>SITE_NAME is perfectly suited for monitoring cron jobs. | |||
Let's look at an example: a machine with the following cron job:</p> | |||
<div class="highlight"><pre><span></span>$ crontab -l | |||
<span class="c1"># m h dom mon dow command</span> | |||
<span class="m">8</span> <span class="m">6</span> * * * /home/user/backup.sh | |||
</pre></div> | |||
<p>You can use SITE_NAME to get a notification whenever the <code>backup.sh</code> script does not | |||
complete successfully. Here is how to set that up.</p> | |||
<ol> | |||
<li> | |||
<p>If you have not already, sign up for a free SITE_NAME account.</p> | |||
</li> | |||
<li> | |||
<p>In your SITE_NAME account, <strong>add a new check</strong>.</p> | |||
<p>Note: in SITE_NAME, a <strong>check</strong> 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.</p> | |||
</li> | |||
<li> | |||
<p>Give the check <strong>a meaningful name</strong>. Good naming will become | |||
increasingly important as you add more checks to your account.</p> | |||
</li> | |||
<li> | |||
<p>Edit the check's <strong>schedule</strong>:</p> | |||
<ul> | |||
<li>change its type from "Simple" to "Cron"</li> | |||
<li>enter <code>8 6 * * *</code> in the cron epression field</li> | |||
<li>set the timezone to match your machine's timezone</li> | |||
</ul> | |||
</li> | |||
<li> | |||
<p>Take note of your check's unique <strong>ping URL</strong></p> | |||
</li> | |||
</ol> | |||
<p>Finally, edit your crontab and append a curl or wget call after the command:</p> | |||
<div class="highlight"><pre><span></span>$ crontab -e | |||
<span class="c1"># m h dom mon dow command</span> | |||
<span class="m">8</span> <span class="m">6</span> * * * /home/user/backup.sh <span class="o">&&</span> curl -fsS --retry <span class="m">3</span> PING_URL > /dev/null | |||
</pre></div> | |||
<p>Now, each time your cron job runs, it will send a HTTP request to the ping URL.</p> | |||
<p>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.</p> | |||
<p>This monitoring technique takes care of various failure scenarios that could | |||
potentially go unnoticed otherwise:</p> | |||
<ul> | |||
<li>The whole machine goes down (power outage, janitor stumbles on wires, VPS provider problems, etc.)</li> | |||
<li>cron daemon is not running, or has invalid configuration</li> | |||
<li>cron does start your task, but the task exits with non-zero exit code</li> | |||
</ul> | |||
<h2>Curl Options</h2> | |||
<p>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.</p> | |||
<table class="table curl-opts"> | |||
<tr> | |||
<th>&&</th> | |||
<td>Run curl only if <code>/home/user/backup.sh</code> exits with an exit code 0</td> | |||
</tr> | |||
<tr> | |||
<th> | |||
-f, --fail | |||
</th> | |||
<td>Makes curl treat non-200 responses as errors</td> | |||
</tr> | |||
<tr> | |||
<th>-s, --silent</th> | |||
<td>Silent or quiet mode. Don't show progress meter or error messages.</td> | |||
</tr> | |||
<tr> | |||
<th>-S, --show-error</th> | |||
<td>When used with -s it makes curl show error message if it fails.</td> | |||
</tr> | |||
<tr> | |||
<th>--retry <num></th> | |||
<td> | |||
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. | |||
</td> | |||
</tr> | |||
<tr> | |||
<th>> /dev/null</th> | |||
<td> | |||
Redirect curl's stdout to /dev/null (error messages go to stderr,) | |||
</td> | |||
</tr> | |||
</table> | |||
<h2>Looking up Your Machine's Time Zone</h2> | |||
<p>On modern GNU/Linux systems, you can look up the time zone using the | |||
<code>timedatectl status</code> command and looking for "Time zone" in its output:</p> | |||
<div class="highlight"><pre><span></span>$ 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 | |||
<span class="hll"> Time zone: Europe/Riga (EET, +0200) | |||
</span>System clock synchronized: yes | |||
NTP service: active | |||
RTC in local TZ: no | |||
</pre></div> |
@ -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. | |||
<table class="table curl-opts"> | |||
<tr> | |||
<th>&&</th> | |||
<td>Run curl only if <code>/home/user/backup.sh</code> exits with an exit code 0</td> | |||
</tr> | |||
<tr> | |||
<th> | |||
-f, --fail | |||
</th> | |||
<td>Makes curl treat non-200 responses as errors</td> | |||
</tr> | |||
<tr> | |||
<th>-s, --silent</th> | |||
<td>Silent or quiet mode. Don't show progress meter or error messages.</td> | |||
</tr> | |||
<tr> | |||
<th>-S, --show-error</th> | |||
<td>When used with -s it makes curl show error message if it fails.</td> | |||
</tr> | |||
<tr> | |||
<th>--retry <num></th> | |||
<td> | |||
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. | |||
</td> | |||
</tr> | |||
<tr> | |||
<th>> /dev/null</th> | |||
<td> | |||
Redirect curl's stdout to /dev/null (error messages go to stderr,) | |||
</td> | |||
</tr> | |||
</table> | |||
## 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 | |||
``` |
@ -0,0 +1,4 @@ | |||
<h1>PHP</h1> | |||
<p>Below is an example of making a HTTP request to SITE_NAME from PHP.</p> | |||
<div class="highlight"><pre><span></span><span class="x">file_get_contents('https://hc-ping.com/your-uuid-here');</span> | |||
</pre></div> |
@ -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'); | |||
``` |
@ -0,0 +1,23 @@ | |||
<h1>PowerShell</h1> | |||
<p>You can use <a href="https://msdn.microsoft.com/en-us/powershell/mt173057.aspx">PowerShell</a> | |||
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.</p> | |||
<p>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.</p> | |||
<div class="highlight"><pre><span></span><span class="c1"># inside a PowerShell script:</span> | |||
Invoke-RestMethod PING_URL | |||
</pre></div> | |||
<p>Save the above to e.g. <code>C:\Scripts\healthchecks.ps1</code>. | |||
Then use the following command in a Scheduled Task to run the script:</p> | |||
<div class="highlight"><pre><span></span>powershell.exe -ExecutionPolicy bypass -File C:<span class="se">\S</span>cripts<span class="se">\h</span>ealthchecks.ps1 | |||
</pre></div> | |||
<p>In simple cases, you can also pass the script to PowerShell directly, | |||
using the "-command" argument:</p> | |||
<div class="highlight"><pre><span></span><span class="c1"># Without an underlying script, passing the command to PowerShell directly:</span> | |||
powershell.exe -command <span class="p">&</span><span class="o">{</span>Invoke-RestMethod PING_URL<span class="o">}</span> | |||
</pre></div> |
@ -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} | |||
``` |
@ -0,0 +1,32 @@ | |||
<h1>Python</h1> | |||
<p>If you are already using the requests library, it's convenient to also use it here:</p> | |||
<div class="highlight"><pre><span></span><span class="c1"># using requests:</span> | |||
<span class="kn">import</span> <span class="nn">requests</span> | |||
<span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"PING_URL"</span><span class="p">)</span> | |||
</pre></div> | |||
<p>Otherwise, you can use the urllib standard module.</p> | |||
<div class="highlight"><pre><span></span><span class="c1"># urllib with python 3.x:</span> | |||
<span class="kn">import</span> <span class="nn">urllib.request</span> | |||
<span class="n">urllib</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="s2">"PING_URL"</span><span class="p">)</span> | |||
</pre></div> | |||
<div class="highlight"><pre><span></span><span class="c1"># urllib with python 2.x:</span> | |||
<span class="kn">import</span> <span class="nn">urllib</span> | |||
<span class="n">urllib</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="s2">"PING_URL"</span><span class="p">)</span> | |||
</pre></div> | |||
<p>You can include additional diagnostic information in the in the request body (for POST requests), or in the "User-Agent" request header:</p> | |||
<div class="highlight"><pre><span></span><span class="c1"># Passing diagnostic information in the POST body:</span> | |||
<span class="kn">import</span> <span class="nn">requests</span> | |||
<span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s2">"PING_URL"</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s2">"temperature=-7"</span><span class="p">)</span> | |||
</pre></div> | |||
<div class="highlight"><pre><span></span><span class="c1"># Passing diagnostic information in the User-Agent header:</span> | |||
<span class="kn">import</span> <span class="nn">requests</span> | |||
<span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"PING_URL"</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="p">{</span><span class="s2">"User-Agent"</span><span class="p">:</span> <span class="s2">"temperature=-7"</span><span class="p">})</span> | |||
</pre></div> |
@ -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"}) | |||
``` |
@ -0,0 +1,7 @@ | |||
<h1>Ruby</h1> | |||
<p>Below is an example of making a HTTP request to SITE_NAME from Ruby.</p> | |||
<div class="highlight"><pre><span></span><span class="nb">require</span> <span class="s1">'net/http'</span> | |||
<span class="nb">require</span> <span class="s1">'uri'</span> | |||
<span class="no">Net</span><span class="o">::</span><span class="no">HTTP</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="no">URI</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s1">'PING_URL'</span><span class="p">))</span> | |||
</pre></div> |
@ -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')) | |||
``` |
@ -0,0 +1,24 @@ | |||
<h1>Signalling failures</h1> | |||
<p>Append <code>/fail</code> to a ping URL and use it to actively signal a failure. | |||
Requesting the <code>/fail</code> 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.</p> | |||
<p>Below is a skeleton code example in Python which signals a failure when the | |||
work function returns an unexpected value or throws an exception:</p> | |||
<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">requests</span> | |||
<span class="n">URL</span> <span class="o">=</span> <span class="s2">"PING_URL"</span> | |||
<span class="k">def</span> <span class="nf">do_work</span><span class="p">():</span> | |||
<span class="c1"># Do your number crunching, backup dumping, newsletter sending work here.</span> | |||
<span class="c1"># Return a truthy value on success.</span> | |||
<span class="c1"># Return a falsy value or throw an exception on failure.</span> | |||
<span class="k">return</span> <span class="bp">True</span> | |||
<span class="n">success</span> <span class="o">=</span> <span class="bp">False</span> | |||
<span class="k">try</span><span class="p">:</span> | |||
<span class="n">success</span> <span class="o">=</span> <span class="n">do_work</span><span class="p">()</span> | |||
<span class="k">finally</span><span class="p">:</span> | |||
<span class="c1"># On success, requests PING_URL</span> | |||
<span class="c1"># On failure, requests PING_URL/fail</span> | |||
<span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">URL</span> <span class="k">if</span> <span class="n">success</span> <span class="k">else</span> <span class="n">URL</span> <span class="o">+</span> <span class="s2">"/fail"</span><span class="p">)</span> | |||
</pre></div> |
@ -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") | |||
``` |
@ -0,0 +1,3 @@ | |||
<li{% if slug == section %} class="active"{% endif %}> | |||
<a href="{% url 'hc-serve-doc' slug %}">{{ title }}</a> | |||
</li> |
@ -0,0 +1,22 @@ | |||
{% extends "front/base_docs.html" %} | |||
{% load compress static hc_extras %} | |||
{% block title %}Documentation - {% site_name %}{% endblock %} | |||
{% block description %} | |||
<meta name="description" content="Monitor any service that can make a HTTP request or send an email: cron jobs, Bash scripts, Python, Ruby, Node, PHP, JS, ..."> | |||
{% endblock %} | |||
{% block keywords %} | |||
<meta name="keywords" content="healthchecks, crontab monitoring, python health check, bash health check, cron monitoring, cron tutorial, cron howto, api health check, open source"> | |||
{% endblock %} | |||
{% block docs_content %}<div class="docs-content">{{ content|safe }}</div>{% endblock %} | |||
{% block scripts %} | |||
{% compress js %} | |||
<script src="{% static 'js/jquery-2.1.4.min.js' %}"></script> | |||
<script src="{% static 'js/bootstrap.min.js' %}"></script> | |||
<script src="{% static 'js/clipboard.min.js' %}"></script> | |||
<script src="{% static 'js/snippet-copy.js' %}"></script> | |||
{% endcompress %} | |||
{% endblock %} |