# IPlogger 🐧 mit MySQL/MariaDB-Unterstützung (iplogger-db.sh)

<p class="callout info">**IPlogger, Debian (+Derivate)  
*Wiki-Stand: 12.05.2026*  
*Script-Stand: 12.05.2026*** [***Download***](https://wiki.mariobeh.de/link/61#bkmrk-script-download)</p>

# IPLogger DB – IP- und Verfügbarkeitsüberwachung

## Überblick

Der `iplogger-db.sh` ist ein datenbankgestützter IP-Logger zur dauerhaften Überwachung der eigenen Internetverbindung und der öffentlichen WAN-IP-Adresse.  
Das Script wurde dafür entwickelt, langfristig und nachvollziehbar festzuhalten:

- welche öffentliche IP-Adresse zu welchem Zeitpunkt aktiv war
- ob eine Internetverbindung vorhanden war
- ob lediglich die IP-Ermittlung fehlgeschlagen ist
- welche Prüfdienste funktioniert oder versagt haben
- wie lange einzelne IPs aktiv waren
- wann Provider oder Verbindungen ausgefallen sind

Der Fokus liegt nicht auf einer simplen „Wie ist meine IP“-Abfrage, sondern auf einer historisch nachvollziehbaren Langzeitaufzeichnung mit Auswertung und Zeiträumen.

Das System arbeitet vollständig datenbankbasiert und speichert jede einzelne Messung dauerhaft ab.

---

# Ziel des Systems

Der Logger beantwortet unter anderem folgende Fragen:

- Welche öffentliche IP war am 12.03.2024 um 14:00 Uhr aktiv?
- Wie lange blieb eine bestimmte IP bestehen?
- Wann erfolgte ein DSL-/WAN-Reconnect?
- War die Leitung tatsächlich offline oder nur ein Prüfdienst gestört?
- Welche Provider lieferten fehlerhafte Antworten?
- Welche DNS-/Connectivity-Ziele waren erreichbar?
- Wie oft kam es zu Unterbrechungen?
- Wie stabil arbeitet die Internetanbindung?

Gerade bei:

- DSL-Zwangstrennungen
- CGNAT-/Providerwechseln
- VPN-/Tunnelproblemen
- Routingfehlern
- sporadischen Ausfällen
- Providerstörungen

liefert die Historie eine klare technische Nachvollziehbarkeit.

---

# Architektur

Das System besteht aus mehreren Komponenten:

<div class="TyagGW_tableContainer" id="bkmrk-komponente-aufgabe-p"><div class="group TyagGW_tableWrapper flex flex-col-reverse w-fit" tabindex="-1"><table class="w-fit min-w-(--thread-content-width)" data-end="2016" data-start="1673"><thead data-end="1697" data-start="1673"><tr data-end="1697" data-start="1673"><th class="last:pe-10" data-col-size="sm" data-end="1686" data-start="1673">Komponente</th><th class="last:pe-10" data-col-size="md" data-end="1697" data-start="1686">Aufgabe</th></tr></thead><tbody data-end="2016" data-start="1708"><tr data-end="1755" data-start="1708"><td data-col-size="sm" data-end="1722" data-start="1708">`providers`</td><td data-col-size="md" data-end="1755" data-start="1722">Öffentliche IP-Abfragedienste</td></tr><tr data-end="1831" data-start="1756"><td data-col-size="sm" data-end="1780" data-start="1756">`connectivity_checks`</td><td data-col-size="md" data-end="1831" data-start="1780">Prüft, ob Internet grundsätzlich erreichbar ist</td></tr><tr data-end="1873" data-start="1832"><td data-col-size="sm" data-end="1842" data-start="1832">`state`</td><td data-col-size="md" data-end="1873" data-start="1842">Speichert Rotationszustände</td></tr><tr data-end="1914" data-start="1874"><td data-col-size="sm" data-end="1884" data-start="1874">`iplog`</td><td data-col-size="md" data-end="1914" data-start="1884">Historische Hauptdatenbank</td></tr><tr data-end="1963" data-start="1915"><td data-col-size="sm" data-end="1929" data-start="1915">`summary_*`</td><td data-col-size="md" data-end="1963" data-start="1929">Auswertung und Zusammenfassung</td></tr><tr data-end="2016" data-start="1964"><td data-col-size="sm" data-end="1982" data-start="1964">PDF-/CSV-Export</td><td data-col-size="md" data-end="2016" data-start="1982">Archivierung und Dokumentation</td></tr></tbody></table>

</div></div>---

# Grundlogik

Der Ablauf einer Messung sieht vereinfacht so aus:

```
1. Connectivity prüfen
2. Wenn Internet vorhanden:
3. Öffentliche IP ermitteln
4. Ergebnis speichern
5. Statistiken aktualisieren
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--3"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--4"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Wichtig dabei:

Das Script unterscheidet sauber zwischen:

<div class="TyagGW_tableContainer" id="bkmrk-zustand-bedeutung-of"><div class="group TyagGW_tableWrapper flex flex-col-reverse w-fit" tabindex="-1"><table class="w-fit min-w-(--thread-content-width)" data-end="2564" data-start="2291"><thead data-end="2314" data-start="2291"><tr data-end="2314" data-start="2291"><th class="last:pe-10" data-col-size="sm" data-end="2301" data-start="2291">Zustand</th><th class="last:pe-10" data-col-size="md" data-end="2314" data-start="2301">Bedeutung</th></tr></thead><tbody data-end="2564" data-start="2325"><tr data-end="2365" data-start="2325"><td data-col-size="sm" data-end="2337" data-start="2325">`OFFLINE`</td><td data-col-size="md" data-end="2365" data-start="2337">Keine Internetverbindung</td></tr><tr data-end="2432" data-start="2366"><td data-col-size="sm" data-end="2383" data-start="2366">`CHECK_FAILED`</td><td data-col-size="md" data-end="2432" data-start="2383">Internet vorhanden, aber IP nicht ermittelbar</td></tr><tr data-end="2468" data-start="2433"><td data-col-size="sm" data-end="2440" data-start="2433">`OK`</td><td data-col-size="md" data-end="2468" data-start="2440">IP erfolgreich ermittelt</td></tr><tr data-end="2529" data-start="2469"><td data-col-size="sm" data-end="2490" data-start="2469">`INVALID_RESPONSE`</td><td data-col-size="md" data-end="2529" data-start="2490">Provider lieferte ungültige Antwort</td></tr><tr data-end="2564" data-start="2530"><td data-col-size="sm" data-end="2541" data-start="2530">`NO_RUN`</td><td data-col-size="md" data-end="2564" data-start="2541">Reservierter Status</td></tr></tbody></table>

</div></div>Dadurch wird verhindert, dass ein einfacher Fehler eines einzelnen IP-Dienstes fälschlich als Internetausfall interpretiert wird.

---

# Initialisierung

## <span role="text">Einstiegspunkt: `init`</span>

```
./iplogger-db.sh init
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--6"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class=""><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--7"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Dieser Befehl erstellt die komplette Datenbankstruktur.

Dabei werden automatisch angelegt:

- Tabellen
- Standardprovider
- Connectivity-Ziele
- Rotationsstatus

---

# Datenbanktabellen

Es muss vorab ein Benutzer und eine Datenbank erstellt sein. Die init-Datenbankinitialisierung erstellt dann die Tabellen.

## providers

Enthält alle IP-Ermittlungsdienste.

Standardmäßig:

- icanhazip.com
- ifconfig.me
- api.ipify.org
- checkip.amazonaws.com

Gespeichert werden zusätzlich:

- Erfolgszähler
- Fehlerzähler
- letzter Erfolg
- letzter Fehler
- Timeoutwerte

Beispiel:

<div class="TyagGW_tableContainer" id="bkmrk-name-url-icanhazip.c"><div class="group TyagGW_tableWrapper flex flex-col-reverse w-fit" tabindex="-1"><table class="w-fit min-w-(--thread-content-width)" data-end="3380" data-start="3272"><thead data-end="3286" data-start="3272"><tr data-end="3286" data-start="3272"><th class="last:pe-10" data-col-size="sm" data-end="3279" data-start="3272">Name</th><th class="last:pe-10" data-col-size="sm" data-end="3286" data-start="3279">URL</th></tr></thead><tbody data-end="3380" data-start="3297"><tr data-end="3338" data-start="3297"><td data-col-size="sm" data-end="3313" data-start="3297">icanhazip.com</td><td data-col-size="sm" data-end="3338" data-start="3313">[https://icanhazip.com<span aria-hidden="true" class="ms-0.5 inline-block align-middle leading-none"><svg aria-hidden="true" class="block h-[0.75em] w-[0.75em] stroke-current stroke-[0.75]" data-rtl-flip="" height="20" width="20" xmlns="http://www.w3.org/2000/svg"></svg></span>](https://icanhazip.com)</td></tr><tr data-end="3380" data-start="3339"><td data-col-size="sm" data-end="3355" data-start="3339">api.ipify.org</td><td data-col-size="sm" data-end="3380" data-start="3355">[https://api.ipify.org<span aria-hidden="true" class="ms-0.5 inline-block align-middle leading-none"><svg aria-hidden="true" class="block h-[0.75em] w-[0.75em] stroke-current stroke-[0.75]" data-rtl-flip="" height="20" width="20" xmlns="http://www.w3.org/2000/svg"></svg></span>](https://api.ipify.org)</td></tr></tbody></table>

</div></div>---

## connectivity\_checks

Prüft die generelle Internetverfügbarkeit.

Standardmäßig:

- Google DNS (`8.8.8.8`)
- Quad9 (`9.9.9.9`)
- Cloudflare (`1.1.1.1`)

Die Prüfung erfolgt per Ping.

---

## state

Speichert interne Rotationsinformationen.

Dadurch wird nicht immer derselbe Provider zuerst verwendet.

Beispiele:

<div class="TyagGW_tableContainer" id="bkmrk-name-wert-next_provi"><div class="group TyagGW_tableWrapper flex flex-col-reverse w-fit" tabindex="-1"><table class="w-fit min-w-(--thread-content-width)" data-end="3828" data-start="3743"><thead data-end="3758" data-start="3743"><tr data-end="3758" data-start="3743"><th class="last:pe-10" data-col-size="sm" data-end="3750" data-start="3743">Name</th><th class="last:pe-10" data-col-size="sm" data-end="3758" data-start="3750">Wert</th></tr></thead><tbody data-end="3828" data-start="3769"><tr data-end="3796" data-start="3769"><td data-col-size="sm" data-end="3791" data-start="3769">next\_provider\_index</td><td data-col-size="sm" data-end="3796" data-start="3791">2</td></tr><tr data-end="3828" data-start="3797"><td data-col-size="sm" data-end="3823" data-start="3797">next\_connectivity\_index</td><td data-col-size="sm" data-end="3828" data-start="3823">1</td></tr></tbody></table>

</div></div>---

## iplog

Die zentrale Historientabelle.

Hier wird jede Messung dauerhaft gespeichert.

Gespeichert werden unter anderem:

- Messzeitpunkt
- öffentliche IP
- Status
- verwendeter Provider
- Anzahl Versuche
- Fehlermeldungen
- Rohantworten
- Connectivity-Status

---

# Rotationssystem

## Warum Rotation?

Würde immer derselbe Provider zuerst verwendet werden:

- wäre dieser stärker belastet
- Fehler würden schwerer auffallen
- andere Provider würden kaum genutzt

Deshalb arbeitet das System rotierend.

---

## Beispiel

### Durchlauf 1

```
1. icanhazip.com
2. ifconfig.me
3. ipify
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--14"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--15"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>### Durchlauf 2

```
1. ifconfig.me
2. ipify
3. icanhazip.com
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--16"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--17"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>### Durchlauf 3

```
1. ipify
2. icanhazip.com
3. ifconfig.me
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--18"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--19"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Dadurch verteilt sich die Last gleichmäßig.

---

# Connectivity-Prüfung

## <span role="text">Einstiegspunkt: `check` oder `run`</span>

```
./iplogger-db.sh check
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--21"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class=""><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--22"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>oder:

```
./iplogger-db.sh run
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--23"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class=""><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--24"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Beides startet dieselbe Messlogik.

---

## Ablauf der Connectivity-Prüfung

Vor der eigentlichen IP-Ermittlung wird geprüft:

- besteht überhaupt Internet?
- ist Routing vorhanden?
- funktionieren externe Ziele?

Dazu werden mehrere bekannte Ziele angepingt.

Erst wenn mindestens eines erreichbar ist, wird die IP-Abfrage gestartet.

---

# Provider-Prüfung

Nach erfolgreicher Connectivity-Prüfung:

```
curl -> Provider -> Antwort validieren
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--27"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--28"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Dabei wird geprüft:

- ist die Antwort leer?
- ist die Antwort eine gültige IPv4?
- ist die Antwort eine gültige IPv6?

Nur dann gilt der Durchlauf als erfolgreich.

---

# Beispielabläufe

## Erfolgreicher Lauf

```
Connectivity OK
Provider erreichbar
IP gültig
→ Status OK
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--30"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--31"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Gespeichert wird beispielsweise:

```
2026-05-12 22:00:00
IP: 93.192.117.44
Status: OK
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--32"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--33"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>---

## Internet vorhanden, aber Provider kaputt

```
Connectivity OK
Provider liefert Müll
→ CHECK_FAILED
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--35"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--36"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Beispiel:

```
Provider https://api.example liefert:
ERROR 500
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--37"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--38"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Das Internet funktioniert trotzdem.

---

## Komplett offline

```
Google DNS nicht erreichbar
Cloudflare nicht erreichbar
Quad9 nicht erreichbar
→ OFFLINE
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--40"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--41"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>---

# Summary-System

Das eigentliche Kernstück ist die Verlaufsanalyse.

Einzelne Messungen werden zu Zeiträumen zusammengefasst.

---

# <span role="text">Einstiegspunkt: `summary`</span>

## Tabellenansicht

```
./iplogger-db.sh summary tabelle
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--44"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class=""><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--45"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Beispiel:

```
BEGIN_AT           END_AT             IP               SAMPLES OFFLINE FAILS
2026-05-01 10:00  2026-05-03 02:00   93.192.117.44         91       0     0
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--46"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--47"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>---

## Textansicht

```
./iplogger-db.sh summary text
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--49"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class=""><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--50"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Beispiel:

```
01.05.2026 10:00 Uhr - 03.05.2026 02:00 Uhr:
IP 93.192.117.44 (91x online)
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--51"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--52"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>---

# Wie die Periodenerkennung funktioniert

Die Funktion `summary_rows()` analysiert die komplette Historie.

Sobald sich die IP ändert:

```
alte Periode schließen
neue Periode beginnen
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--54"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--55"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Zusätzlich werden innerhalb der Periode gezählt:

- Offline-Ereignisse
- Fehler
- erfolgreiche Samples

---

# Detailmodus

## Einstiegspunkt

```
./iplogger-db.sh summary export pdf details
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--57"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class=""><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--58"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Der Detailmodus erzeugt eine vollständige Zeitauflistung aller erfolgreichen Messungen innerhalb einer Periode.

---

## Beispiel

```
16.02.2020 05:00 Uhr - 16.02.2020 11:00 Uhr:
IP 93.192.117.44 (24x online)

- 16.02.2020 05:00 06:00 07:00 08:00
- 16.02.2020 09:00 10:00 11:00
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--60"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--61"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Oder bei Tageswechsel:

```
07.02.2021 04:00 05:00 06:00
08.02.2021 00:00 01:00 02:00
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--62"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--63"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Dadurch werden lange Zeiträume kompakt lesbar dargestellt.

---

# PDF-Export

## Einstiegspunkt

```
./iplogger-db.sh summary export pdf
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--65"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class=""><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--66"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>oder:

```
./iplogger-db.sh summary export pdf details
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--67"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class=""><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--68"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Der Export erzeugt automatisch:

- TXT-Zwischendatei
- PDF-Datei
- Überschrift
- Datum
- Seitenzahlen

Verwendet werden bevorzugt:

- `enscript`
- `ps2pdf`

Alternativ:

- `pandoc`

---

# CSV-Export

## Einstiegspunkt

```
./iplogger-db.sh summary export csv
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--70"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class=""><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--71"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Exportiert die zusammengefassten Perioden in maschinenlesbarer Form.

Beispiel:

```
begin_at;end_at;ip;samples;offline;fails
2026-05-01 10:00;2026-05-03 02:00;93.192.117.44;91;0;0
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--72"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class=""><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--73"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>---

# Historischer CSV-Import

## Einstiegspunkt

```
./iplogger-db.sh import ipdb.csv ";"
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--75"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class=""><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--76"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Der CSV-Import dient primär zur Übernahme historischer Daten aus der ersten Generation des IPLoggers.

Dabei werden ältere Aufzeichnungen in die neue Datenbankstruktur übernommen.

Unterstützt werden:

- erfolgreiche IPs
- Offline-Einträge
- Fehlerzustände

---

# Typische Einsatzszenarien

## WAN-Reconnects nachvollziehen

```
IP 1:
01:00 - 12:00

IP 2:
12:05 - aktuell
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--78"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--79"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>→ DSL-Zwangstrennung klar sichtbar.

---

## Providerprobleme erkennen

```
15x CHECK_FAILED
aber keine OFFLINE-Zustände
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--81"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class="pe-11 pt-3"><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--82"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>→ Internet vorhanden, aber IP-Dienst gestört.

---

## VPN-/Tunnelprobleme analysieren

Wenn:

- Connectivity vorhanden
- aber bestimmte Ziele nicht erreichbar

kann nachvollzogen werden:

- wann Routingprobleme begannen
- wie lange sie bestanden
- ob WAN-Wechsel beteiligt waren

---

# Besonderheiten

## IPv4 und IPv6

Das System akzeptiert beide Varianten automatisch.

---

## Zeitbasierte Rotation

Provider und Connectivity-Checks werden nicht statisch verwendet.

Das verhindert:

- Single-Point-Abhängigkeiten
- einseitige Last
- verfälschte Statistiken

---

## Dauerhafte Historie

Die Datenbank arbeitet append-only.

Neue Einträge werden ausschließlich ergänzt.

Dadurch bleibt die komplette Historie nachvollziehbar erhalten.

---

# Beispiel für Cronjob

```bash
0 * * * * /srv/scripte/iplogger-db.sh check >/dev/null 2>&1
```

<div class="relative w-full mt-4 mb-1" id="bkmrk--88"><div class=""><div class="relative"><div class="h-full min-h-0 min-w-0"><div class="h-full min-h-0 min-w-0"><div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"><div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback"><div class="relative"><div class=""><div class="relative z-0 flex max-w-full"><div class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr" id="bkmrk--89"><div class="cm-scroller">  
</div></div></div></div></div></div></div></div></div><div class=""><div class="">  
</div></div></div></div></div>Dadurch erfolgt stündlich eine neue Messung.

---

# Fazit

`iplogger-db.sh` ist kein einfacher „Wie ist meine IP“-Checker, sondern ein vollständiges Langzeit-Überwachungs- und Auswertungssystem für:

- öffentliche WAN-IPs
- Internetverfügbarkeit
- Providerstabilität
- Fehleranalysen
- historische Zeiträume
- dokumentierbare Verbindungsverläufe

Besonders wertvoll wird das System durch:

- die periodische Zusammenfassung
- die saubere Statusunterscheidung
- die rotierenden Prüfmechanismen
- die nachvollziehbare Langzeithistorie
- die Exportfunktionen für Archivierung und Dokumentation

### **💾 Download**

Das **Programm** kann hier in immer der neuesten Version heruntergeladen werden:

##### **[IPlogger Script](https://public.mariobeh.de/scripts/iplogger-db.sh)** (via mariobeh.de)