Examples
Copy-paste snippets for pinging FlatLyne from shell, cron, common languages, and schedulers.
This page shows how to ping FlatLyne from the tools your jobs already run in. Every snippet sets a timeout and handles errors, so a slow or failed ping can never hang or crash the job it's monitoring.
The examples use https://api.flatlyne.com/CSps9LOZGccsl2o7ieL0_YrQyZJtkGK_0H1u30FJ-NI as the ping URL. Replace it with the URL from your check's page. Every ping URL accepts both GET and POST, and a successful ping returns 200 with the plain-text body PONG.
Shell and crontab
Add curl after your command with &&, so the ping only goes out when the job succeeds.
PING_URL=https://api.flatlyne.com/CSps9LOZGccsl2o7ieL0_YrQyZJtkGK_0H1u30FJ-NI
0 2 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 5 -o /dev/null "$PING_URL"The first line sets PING_URL, a variable cron passes to the command. Here's what each flag does:
| Flag | Effect |
|---|---|
-f | Exit non-zero on an HTTP error (such as 404 for a wrong URL) instead of printing the error page. |
-sS | Hide the progress bar, but still print errors. |
-m 10 | Give up on an attempt after 10 seconds. |
--retry 5 | Retry up to 5 times on transient errors: timeouts and HTTP 408, 429, 500, 502, 503 and 504, waiting longer between each try. |
-o /dev/null | Discard the PONG body, so cron doesn't email it to you. |
If the host has wget but not curl, use this instead:
PING_URL=https://api.flatlyne.com/CSps9LOZGccsl2o7ieL0_YrQyZJtkGK_0H1u30FJ-NI
0 2 * * * /usr/local/bin/backup.sh && wget -q -T 10 -t 5 -O /dev/null "$PING_URL"-T 10 is the timeout and -t 5 is the total number of tries.
Reporting the exit status
Use ; instead of && and append $? to the URL, so the job's exit code goes to FlatLyne either way. 0 counts as success, and any other number marks the check as failed straight away. See Failures, exit codes and start pings for the details.
PING_URL=https://api.flatlyne.com/CSps9LOZGccsl2o7ieL0_YrQyZJtkGK_0H1u30FJ-NI
0 2 * * * /usr/local/bin/backup.sh; curl -fsS -m 10 --retry 5 -o /dev/null "$PING_URL/$?"Sending the job's output
Send the job's output as a POST body and it appears with the ping on your check's page. FlatLyne stores the first 10 KB (10,240 bytes) of each body and drops the rest, so send the last 10 KB, where errors usually are.
#!/bin/sh
output=$(/usr/local/bin/backup.sh 2>&1)
status=$?
printf '%s\n' "$output" | tail -c 10240 \
| curl -fsS -m 10 --retry 5 -o /dev/null --data-binary @- \
"https://api.flatlyne.com/CSps9LOZGccsl2o7ieL0_YrQyZJtkGK_0H1u30FJ-NI/$status"
exit $statusThe script exits with the job's own status, so whatever runs it still sees the real result.
Languages
Each snippet reads the ping URL from the FLATLYNE_PING_URL environment variable and defines a small ping helper that logs a failure instead of raising it. Call it with /start before the work, /fail if the work fails, and no suffix when it succeeds.
This version uses only the standard library.
import os
import sys
import urllib.request
PING_URL = os.environ["FLATLYNE_PING_URL"]
def ping(suffix=""):
try:
with urllib.request.urlopen(PING_URL + suffix, timeout=10):
pass
except Exception as exc: # a failed ping must never fail the job
print(f"FlatLyne ping failed: {exc}", file=sys.stderr)
ping("/start")
try:
run_backup()
except Exception:
ping("/fail")
raise
ping()Docker
docker run exits with the container's exit code, so the same && and $? patterns work.
docker run --rm registry.example.com/backup-db:1.4; \
curl -fsS -m 10 --retry 5 -o /dev/null \
"https://api.flatlyne.com/CSps9LOZGccsl2o7ieL0_YrQyZJtkGK_0H1u30FJ-NI/$?"Kubernetes CronJob
Run the job and the ping in one shell, report the exit status, then exit with it so Kubernetes still sees the real result. Keep the ping URL in a Secret, and make sure the image includes curl.
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup-db-nightly
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: Never
containers:
- name: backup
image: registry.example.com/backup-db:1.4
command: ["/bin/sh", "-c"]
args:
- |
/usr/local/bin/backup.sh
status=$?
curl -fsS -m 10 --retry 5 -o /dev/null \
"$PING_URL/$status" || true
exit $status
env:
- name: PING_URL
valueFrom:
secretKeyRef:
name: flatlyne
key: backup-db-nightly-urlGitHub Actions
Ping on success in one step and send a /fail ping in another. continue-on-error stops a failed ping from failing the workflow. Store the ping URL as a repository secret named FLATLYNE_PING_URL.
name: Nightly backup
on:
schedule:
- cron: "0 2 * * *"
jobs:
backup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./scripts/backup.sh
- name: Ping FlatLyne
if: success()
continue-on-error: true
env:
PING_URL: ${{ secrets.FLATLYNE_PING_URL }}
run: curl -fsS -m 10 --retry 5 -o /dev/null "$PING_URL"
- name: Report failure to FlatLyne
if: failure()
continue-on-error: true
env:
PING_URL: ${{ secrets.FLATLYNE_PING_URL }}
run: curl -fsS -m 10 --retry 5 -o /dev/null "$PING_URL/fail"GitHub can start scheduled workflows late when its runners are busy, so give the check a generous grace period. See Schedules.
systemd timer
ExecStartPost runs only after ExecStart succeeds, so it sends the success ping. The - prefix keeps a failed ping from marking the service as failed. OnFailure starts a second unit that sends the /fail ping.
[Unit]
Description=Nightly database backup
OnFailure=backup-db-nightly-fail.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
ExecStartPost=-/usr/bin/curl -fsS -m 10 --retry 5 -o /dev/null \
https://api.flatlyne.com/CSps9LOZGccsl2o7ieL0_YrQyZJtkGK_0H1u30FJ-NI[Unit]
Description=Report a failed nightly backup to FlatLyne
[Service]
Type=oneshot
ExecStart=-/usr/bin/curl -fsS -m 10 --retry 5 -o /dev/null \
https://api.flatlyne.com/CSps9LOZGccsl2o7ieL0_YrQyZJtkGK_0H1u30FJ-NI/fail[Unit]
Description=Run the database backup every night at 02:00
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.targetEnable the timer with systemctl enable --now backup-db-nightly.timer.