Von UptimeRobot migrieren
Kopieren Sie Ihre UptimeRobot-Monitore mit einem Befehl zu OKStatus, betreiben Sie beide Werkzeuge ein paar Tage parallel und wechseln Sie dann. Ihr UptimeRobot-Konto wird nie verändert.
Was dieses Tutorial macht
Abschnitt betitelt „Was dieses Tutorial macht“Ein Python-Skript liest Ihre Monitore über die UptimeRobot-API und legt sie über die OKStatus-API neu an. Es nutzt nur die Standardbibliothek: Sie müssen nichts installieren.
Bevor Sie beginnen
Abschnitt betitelt „Bevor Sie beginnen“- Ein UptimeRobot-Schlüssel nur zum Lesen: Integrations → API → Read-only API key. Er kann nichts ändern.
- Ein OKStatus-Schlüssel mit Zugriff Voll, im Max-Tarif (Einstellungen → API-Schlüssel). Mit Free oder Pro liefert Ihnen der Probelauf aus Schritt 3 trotzdem die genaue Liste zum manuellen Anlegen.
- Python 3.9 oder neuer.
1. Die Zuordnung
Abschnitt betitelt „1. Die Zuordnung“| UptimeRobot | OKStatus | Detail |
|---|---|---|
| HTTP(s) | HTTP | gleiche URL, gleiche Methode |
| Keyword | HTTP + Schlüsselwort | „not exists“ wird zu keywordInvert |
| Ping | Ping | |
| Port | TCP | HTTP 80, HTTPS 443, FTP 21, SMTP 25, POP3 110, IMAP 143 oder Ihr eigener Port |
| Heartbeat | Heartbeat (push) | eine neue Ping-URL für Ihre Cronjobs; Perioden über einem Tag werden übersprungen |
| Pausiert | Pausiert | der Monitor wird angelegt und dann pausiert |
| Intervall | Intervall | bei Bedarf auf das Minimum Ihres Tarifs angehoben, höchstens ein Tag |
2. Das Skript
Abschnitt betitelt „2. Das Skript“Laden Sie uptimerobot_to_okstatus.py herunter oder kopieren Sie es. Seine Meldungen sind auf Englisch.
#!/usr/bin/env python3"""Copy UptimeRobot monitors to OKStatus.
Reads your monitors with UptimeRobot's API (v2, read-only key is enough) andcreates them in OKStatus with its REST API (Full key, Max plan). Without--apply it only prints what it would create. Your UptimeRobot account isnever changed. Python 3.9+, standard library only.
export UPTIMEROBOT_API_KEY=ur... export OKSTATUS_REGIONS=fr-dc3,de-fra,nl-ams # regions of your plan export OKSTATUS_MIN_INTERVAL=30 # 300 Free, 60 Pro, 30 Max python3 uptimerobot_to_okstatus.py # dry run export OKSTATUS_API_KEY=oks_live_... python3 uptimerobot_to_okstatus.py --apply
Guide: https://okstatus.eu/docs/tutorials/migrate-from-uptimerobot/"""import jsonimport osimport reimport sysimport urllib.errorimport urllib.parseimport urllib.request
UR_API = os.environ.get("UPTIMEROBOT_API_URL", "https://api.uptimerobot.com/v2")OK_API = os.environ.get("OKSTATUS_API_URL", "https://api.okstatus.eu/api/v1")REGIONS = [r.strip() for r in os.environ.get("OKSTATUS_REGIONS", "fr-dc3,de-fra").split(",") if r.strip()]MIN_INTERVAL = int(os.environ.get("OKSTATUS_MIN_INTERVAL", "60"))APPLY = "--apply" in sys.argv
# UptimeRobot v2 codes (uptimerobot.com/api/legacy)PORTS = {1: 80, 2: 443, 3: 21, 4: 25, 5: 110, 6: 143} # port monitor sub_typeMETHODS = {1: "HEAD", 2: "GET", 3: "POST", 4: "PUT", 5: "PATCH", 6: "DELETE", 7: "OPTIONS"}PAUSED = 0 # monitor status
def uptimerobot_monitors(): key = os.environ.get("UPTIMEROBOT_API_KEY") if not key: sys.exit("Set UPTIMEROBOT_API_KEY (Integrations → API → read-only key).") offset = 0 while True: form = {"api_key": key, "format": "json", "offset": offset, "limit": 50, "http_request_details": "true"} req = urllib.request.Request(f"{UR_API}/getMonitors", urllib.parse.urlencode(form).encode()) with urllib.request.urlopen(req, timeout=30) as r: page = json.load(r) if page.get("stat") != "ok": sys.exit(f"UptimeRobot: {page.get('error')}") yield from page.get("monitors", []) offset += 50 if offset >= int(page.get("pagination", {}).get("total", 0)): return
def as_int(value, default=0): try: return int(value) except (TypeError, ValueError): return default
def convert(m): """(body of POST /api/v1/monitors, None) or (None, why it is skipped).""" kind = as_int(m.get("type")) body = { "name": str(m.get("friendly_name") or m.get("url") or "Monitor")[:100], "regions": REGIONS, # OKStatus accepts 30 s to 1 day, and never less than the plan's floor. "interval": min(max(as_int(m.get("interval"), 300), MIN_INTERVAL), 86400), } if kind in (1, 2): # HTTP(s), Keyword body.update(type="http", url=m["url"]) method = METHODS.get(as_int(m.get("http_method"), 2), "GET") if method != "GET": body["httpMethod"] = method if kind == 2: body["keyword"] = m.get("keyword_value") or "" body["keywordInvert"] = as_int(m.get("keyword_type")) == 2 # 2 = "not exists" elif kind == 3: # Ping body.update(type="ping", url=m["url"]) elif kind == 4: # Port sub = as_int(m.get("sub_type")) port = as_int(m.get("port")) if sub == 99 else PORTS.get(sub) if not port: return None, "port monitor without a port" body.update(type="tcp", url=m["url"], port=port) elif kind == 5: # Heartbeat if as_int(m.get("interval")) > 86400: # A shorter period would report the job down between two runs. return None, "heartbeat period over one day, the OKStatus maximum" slug = re.sub(r"[^a-z0-9]+", "-", body["name"].lower()).strip("-") body.update(type="push", url=slug or "heartbeat") else: return None, f"UptimeRobot type {m.get('type')} has no equivalent" return body, None
def okstatus(method, url, body): req = urllib.request.Request(url, json.dumps(body).encode(), method=method, headers={ "Authorization": f"Bearer {os.environ['OKSTATUS_API_KEY']}", "Content-Type": "application/json", }) with urllib.request.urlopen(req, timeout=30) as r: return json.load(r)["data"]
def main(): if APPLY and not os.environ.get("OKSTATUS_API_KEY"): sys.exit("Set OKSTATUS_API_KEY (a Full key, Settings → API Keys) to use --apply.") created = skipped = failed = 0 for m in uptimerobot_monitors(): name = m.get("friendly_name", "?") body, why = convert(m) if body is None: print(f"SKIPPED {name} ({why})") skipped += 1 continue paused = as_int(m.get("status"), -1) == PAUSED if not APPLY: print(f"TO CREATE {body['type']:5} {body['name']} -> {body['url']}" + (" (paused)" if paused else "")) continue try: new = okstatus("POST", f"{OK_API}/monitors", body) if paused: okstatus("PATCH", f"{OK_API}/monitors/{new['id']}", {"status": "paused"}) extra = f" · new ping URL: {new['pushUrl']}" if body["type"] == "push" else "" print(f"CREATED {body['name']}{extra}") created += 1 except urllib.error.HTTPError as e: print(f"FAILED {body['name']}: {e.code} {e.read().decode(errors='replace')[:200]}") failed += 1 if APPLY: print(f"\n{created} created, {skipped} skipped, {failed} failed.") if failed: sys.exit(1) else: print("\nDry run: nothing created. Add --apply to create these monitors.")
if __name__ == "__main__": main()3. Ein Probelauf
Abschnitt betitelt „3. Ein Probelauf“export UPTIMEROBOT_API_KEY=ur…export OKSTATUS_REGIONS=fr-dc3,de-fra,nl-ams # regions of your planexport OKSTATUS_MIN_INTERVAL=30 # 300 on Free, 60 on Pro, 30 on Maxpython3 uptimerobot_to_okstatus.pyTO CREATE http Website -> https://example.comTO CREATE http API health -> https://api.example.com/healthTO CREATE tcp SMTP -> mail.example.comTO CREATE push Nightly backup -> nightly-backupTO CREATE ping Office router -> 203.0.113.10 (paused)
Dry run: nothing created. Add --apply to create these monitors.Ohne --apply wird nichts angelegt. Lesen Sie die Liste, passen Sie die Variablen an und wiederholen Sie es so oft wie nötig.
4. Die Migration
Abschnitt betitelt „4. Die Migration“export OKSTATUS_API_KEY=oks_live_…python3 uptimerobot_to_okstatus.py --applyCREATED WebsiteCREATED API healthCREATED SMTPCREATED Nightly backup · new ping URL: https://backend.okstatus.eu/push/…CREATED Office router
5 created, 0 skipped, 0 failed.5. Nach der Migration
Abschnitt betitelt „5. Nach der Migration“- Legen Sie Ihre Alarmkanäle neu an im Dashboard und verknüpfen Sie sie mit den Monitoren oder einer Gruppe. Das Skript kopiert sie nicht: Sie enthalten Geheimnisse.
- Tauschen Sie die Ping-URL jedes Heartbeats in Ihren Cronjobs aus. Der Aufruf bleibt gleich:
GET,POSTundHEADzählen alle als Ping. Siehe Heartbeat. - Betreiben Sie beide Werkzeuge eine Woche und vergleichen Sie die Alarme. Mit mehreren Regionen alarmiert OKStatus nur, wenn die Mehrheit zustimmt: Rechnen Sie mit weniger vereinzelten Alarmen.
- Legen Sie Ihre Statusseite neu an und richten Sie Ihre Domain (CNAME) auf OKStatus. Siehe Statusseiten.
- Pausieren Sie die UptimeRobot-Monitore und schließen Sie das Konto, wenn Sie bereit sind.
Was nicht migriert wird
Abschnitt betitelt „Was nicht migriert wird“- der Verfügbarkeitsverlauf: OKStatus beginnt am Tag der Migration zu zählen;
- Alarmkanäle, Statusseiten und Wartungsfenster;
- Zugangsdaten, Header und Request-Bodies von HTTP-Monitoren: Fügen Sie sie im Dashboard hinzu;
- Typen ohne Entsprechung (UDP, Drittanbieter-Dienste) und Heartbeats mit einer Periode über einem Tag: Das Skript listet sie als übersprungen (
SKIPPED).