Pinger depuis n’importe quel langage

Des extraits prêts à copier pour pinger une URL heartbeat SteadyCron en cas de succès et d’échec — Bash, Python, Node.js, PHP, Ruby, Go, PowerShell, Docker et systemd.

Un heartbeat n’est qu’une URL que vous appelez lorsque votre tâche s’exécute. Copiez un extrait ci-dessous, remplacez <votre-jeton-ping>, et vous êtes surveillé. En cas de succès, pingez l’URL de base ; en cas d’échec, /fail ; éventuellement /start d’abord pour détecter les exécutions bloquées.

Votre URL de ping ressemble à https://ping.steadycron.com/<votre-jeton-ping> — vous la trouverez sur la page du check après avoir créé un heartbeat.

curl (une ligne)

curl -fsS -m 10 --retry 3 https://ping.steadycron.com/<votre-jeton-ping>

-f échoue sur les erreurs HTTP, -s est silencieux, -m 10 plafonne la durée, --retry 3 survit à un bref incident réseau.

Bash (start / success / fail)

#!/usr/bin/env bash
set -euo pipefail
TOKEN=<votre-jeton-ping>
PING="https://ping.steadycron.com/$TOKEN"

curl -fsS -m 10 "$PING/start"            # tâche démarrée

if ./run-job.sh; then
  curl -fsS -m 10 "$PING"                # succès
else
  curl -fsS -m 10 "$PING/fail"           # échec explicite
fi

Encapsuler n’importe quelle commande

Pinge automatiquement /fail si la commande se termine par un code non nul — sans modifier la tâche elle-même :

TOKEN=<votre-jeton-ping>
PING="https://ping.steadycron.com/$TOKEN"
./run-job.sh && curl -fsS "$PING" || curl -fsS "$PING/fail"

Python

import subprocess
import urllib.request

TOKEN = "<votre-jeton-ping>"
PING = f"https://ping.steadycron.com/{TOKEN}"

def ping(suffix=""):
    try:
        urllib.request.urlopen(PING + suffix, timeout=10)
    except Exception:
        pass  # la surveillance ne doit jamais casser la tâche

ping("/start")
try:
    subprocess.run(["./run-job.sh"], check=True)
    ping()           # succès
except subprocess.CalledProcessError:
    ping("/fail")    # échec

Node.js

const TOKEN = "<votre-jeton-ping>";
const PING = `https://ping.steadycron.com/${TOKEN}`;

const ping = (suffix = "") =>
  fetch(PING + suffix, { signal: AbortSignal.timeout(10_000) }).catch(() => {});

await ping("/start");
try {
  await runJob();
  await ping();          // succès
} catch {
  await ping("/fail");   // échec
}

PHP

<?php
$token = "<votre-jeton-ping>";
$ping  = "https://ping.steadycron.com/$token";

function ping(string $url): void {
    @file_get_contents($url, false, stream_context_create([
        "http" => ["timeout" => 10, "ignore_errors" => true],
    ]));
}

ping("$ping/start");
$exit = 0;
system("./run-job.sh", $exit);
ping($exit === 0 ? $ping : "$ping/fail");

Ruby

require "net/http"

token = "<votre-jeton-ping>"
ping  = "https://ping.steadycron.com/#{token}"

def hit(url) = Net::HTTP.get_response(URI(url)) rescue nil

hit("#{ping}/start")
if system("./run-job.sh")
  hit(ping)          # succès
else
  hit("#{ping}/fail")
end

Go

package main

import (
	"net/http"
	"os/exec"
	"time"
)

const ping = "https://ping.steadycron.com/<votre-jeton-ping>"

func hit(suffix string) {
	c := &http.Client{Timeout: 10 * time.Second}
	if resp, err := c.Get(ping + suffix); err == nil {
		resp.Body.Close()
	}
}

func main() {
	hit("/start")
	if err := exec.Command("./run-job.sh").Run(); err == nil {
		hit("") // succès
	} else {
		hit("/fail")
	}
}

PowerShell (Windows / Planificateur de tâches)

$token = "<votre-jeton-ping>"
$ping  = "https://ping.steadycron.com/$token"

function Ping($url) { try { Invoke-WebRequest -UseBasicParsing -TimeoutSec 10 $url | Out-Null } catch {} }

Ping "$ping/start"
& ".\run-job.ps1"
if ($LASTEXITCODE -eq 0) { Ping $ping } else { Ping "$ping/fail" }

Healthcheck Docker

HEALTHCHECK --interval=5m --timeout=10s \
  CMD curl -fsS https://ping.steadycron.com/<votre-jeton-ping> || exit 1

Timer systemd

Ajoutez un ExecStartPost / ExecStopPost au service que votre timer exécute :

[Service]
Type=oneshot
ExecStart=/usr/local/bin/run-job.sh
ExecStartPost=/usr/bin/curl -fsS https://ping.steadycron.com/<votre-jeton-ping>

Étapes suivantes