@ -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 %} |