PHP-Klasse ahLogger aktualisiert

Samstag, 15. Oktober, 2022

Ich habe mal diese Loggerklasse geschrieben, um in einer PHP-Anwendung Dinge während eines Client-Requests zu debuggen. Ich zeichne Meldungen auf, die mit einem Status (OK, Info, Warnung oder Fehler) versehen werden. Auch kann man übergabe-Parameter und sonstige Variablen dort reinblasen.
Eine Rendering Funktion zeichnet eine Tabelle mit allen Meldungen ans untere Ende der Webseite. Alles kein Hexenwerk.

Wenn man schon Meldungen einsammelt, dann wird auch ein Zeitstempel getrackt. Und wenn man Zeitstempel hat, dann kann man die Zeitdauer von einzelnen Aktionen messen und tracken: wie lange läuft eine Datenbank-Abfrage, ein Exec oder eine andere Aktion - das bekommt man gratis dazu: in einer Spalte der Ausgabetabelle wird das Delta zur letzten aufgezeichneten Meldung ausgegeben.

Ein Div rechts oben zeigt die Verarbeitunsdauer des Requests am Server an und kennzeichnet farblich, ob es eine Warnung oder einen Fehler gab. Man kann von hier auch direkt zu den Einträgen mit Warnung oder Fehler springen.

Mit überschaubarem Aufwand entstand ein hilfreiches Werkzeug zum Debuggen, Messen und Bottlenecks finden.

So wird es gemacht:

Nach dem Initialisieren wird mt der Methode add() beliebig oft je eine Meldung erfasst.

$oLog = new logger();

// Beispiel 1: hilfreiche Daten sichtbar machen
$oLog->add("INFO: all GET params: <pre>" . print_r($_GET,1) . "</pre>");
$oLog->add("INFO: all POST params: <pre>" . print_r($_POST,1) . "</pre>");

// Beispiel 2: Zeiten messen geht implizit - durch Schreiben einer neuen Logmeldung
$oLog->add("start db request");
$sSql='select id, label, description from mytable;';
// ... make your query
$oLog->add("sql query finished: " . $sSql);

Eine render() Methode gibt am Ende das Ergebnis aus.

// die Ausgabe ... aber natürlich nicht für jeden Seitenbesucher
if ($bDebugIsEnabled){
    echo $oLog->render();
}

Was ist neu?

  • Wenn ich bereits Zeiten mitschreibe, ist das Auslesen des Speicherverbrauchs fast ein Nobrainer. So sieht man, wo wärend der Aktionen eines Seitenaufrufs der Speicherverbrauch wie wächst.
  • Balken visualisiern nun den Speichrverbrauch und die gemessenen Zeiten.
  • Emoji Icons machen die Ausgabe etwas locker.

So sieht es aus:

2022-10-15-ahlogger-html-ouput.png

weiterführende Links:

  1. Docs: ahLogger
  2. Github: Sourccode

Neues Feature beim IML-Backup: Hooks

Donnerstag, 13. Oktober, 2022

Nachdem vor 2 Wochen das Prune und Verify separat ausführbar und konfigurierbar wurden, gibt es nun ein weiteres Feature: Hooks.

Das Backup läuft wie folgt ab

  • Initialisierung
  • Start der Backups der lokalen Datenbanken (z.B. Mysql, Sqlite)
  • Backup der definierten lokalen Verzeichnisse
  • Prune (Ausdünnen und Löschen alter Backup-Daten)
  • Verify

Die Hooks dienen zum Starten von eigenen Skripten … vor dem Start des Backups und danach sowie auch an mehreren Punkten während des Backups.

Es gibt initial diese Verzeichnisse, die du Skripte ablegen kannst, um sie zu definierten Zeitpunkten zu starten:

> tree -d hooks/
hooks/
|-- 10-before-backup
|   `-- always
|-- 12-before-db-service
|   `-- always
|-- 14-before-db-dump (UNUSED)
|   `-- always
|-- 16-after-db-dump (UNUSED)
|   |-- always
|   |-- on-error
|   `-- on-ok
|-- 18-after-db-service
|   |-- always
|   |-- on-error
|   `-- on-ok
|-- 20-before-transfer
|   `-- always
|-- 22-before-folder-transfer
|   `-- always
|-- 24-after-folder-transfer
|   |-- always
|   |-- on-error
|   `-- on-ok
|-- 26-after-prune
|   |-- always
|   |-- on-error
|   `-- on-ok
|-- 28-after-verify
|   |-- always
|   |-- on-error
|   `-- on-ok
`-- 30-post-backup
    |-- always
    |-- on-error
    `-- on-ok

34 directories

Als am ehesten einleuchtende Beispiele:

  • Vor dem Start des Backups kann man Sachen lokal synchronisieren, die ebenfalls ins Backup einfliessen sollen.
  • Nach dem Backup kann man beispielsweise Notifikationen ins Monitoring oder per E-mail auslösen.

Bei “nach einer Aktion” zu startenden Hooks kann man jeweils getrennte Sets von Skripten starten, sobald eine Aktion OK war … oder aber fehlerhaft … oder aber auch immer (unabhängig vom Status).

Und wie ist es implementiert? Schauen wir mal auf die Bash-Interna.

Es gibt zu den definierten Zeitpunkten im Skript einen Aufruf einer Hook-Funktion - mit dem Hook-Verzeichnis als Namen als Parameter 1 und für “nach einer Aktion” zu startende Hooks den Exitcode als optionalen 2. Parameter. Als willkürliches Beispiel:

_j_runHooks "24-after-folder-transfer" "$myrc"

Die Hookfunktion ruft bei Exitcode 0 die Skripte im “on-ok” Untrverzeichnis - und bei Exitcode > 0 jene vom “on-error”. Anschliessend (oder bei Aufruf ohne einen Exitcode) werden vom jeweiligen Hook die Skripte im Unterverzeichnis “always” verarbeitet.
Die Ausführung der Skripte erfolgt in alphabetischer Reihenfolge - mit der Benamung kann man also die Abfolge der Abarbeitung mehrerer Skripte beeinflussen.

Die Hookfunktion sieht so aus (genaugenommen erschreckend einfach):

...
# ------------------------------------------------------------
# execute hook skripts in a given directory in alphabetic order
# param  string   name of hook directory
# param  string   optional: integer of existcode or "" for non-on-result hook
# ------------------------------------------------------------
function _j_runHooks(){
  local _hookbase="$1"
  local _exitcode="$2"
  local _hookdir="$( dirname $0 )/hooks/$_hookbase"

  if [ -z "$_exitcode" ]; then
    _hookdir="$_hookdir/always"
  elif [ "$_exitcode" = "0" ]; then
    _hookdir="$_hookdir/on-ok"
  else
    _hookdir="$_hookdir/on-error"
  fi
  for hookscript in $( ls -1a "$_hookdir" | grep -v "^." | sort )
  do
    if [ -x "$_hookdir/$hookscript" ]; then
      h3 "HOOK: start $_hookdir/$hookscript ..."
      $_hookdir/$hookscript
    else
      h3 "HOOK: SKIP $_hookdir/$hookscript (not executable) ..."
    fi
  done

  # if an exitcode was given as param then run hooks without exitcode 
  # (in subdir "always")
  if [ -n "$_exitcode" ]; then
    _j_runHooks "$_hookbase"
  fi

  echo
}
...

weiterführende Links:

  1. IML OS Docs - IML Backup: Hooks (en)
  2. IML OS Docs - IML Backup: Startseite (en)

Neue grep Version warnt “warning: stray before white space”

Montag, 10. Oktober, 2022

Ich spiele immer fleissig Updates ein.
Plötzlich überraschen mich meine Shellskripte mit der Ausgabe

grep: warning: stray  before white space

Die Ursache ist schnell gefunden … eine neue Grep Version 3.8 ist aufgespielt worden, die sich offensichtlich anders verhält.

> grep --version
grep (GNU grep) 3.8
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Mike Haertel and others; see
<https://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.

Ich hielt es bisher immer so: Sonderzeichen MUSS man im Regex maskieren … und beliebige normale Zeichen KANN man immer mit Backslash maskieren und es schadet auch nicht. Letzteres ist nun offensichtlich anders.

> echo "   OK" | grep "\ \ "
grep: warning: stray  before white space
grep: warning: stray  before white space
   OK

Zur Abschaltung der Warnung entferne ich im Regex den einem Space vorangestellte Backslash:

> echo "   OK" | grep "  "
   OK

Yep.
Soweit so gut … alles gut … dachte ich.

Es kamen in anderen Skripten aber auch Meldungen der Art

grep: warning: stray  before -

Also die Suche nach einem Minus muss nun auch nicht mehr mit Backslash maskiert werden? Einmal schnell testen:

> echo "------" | grep "\-\-\-"
grep: warning: stray  before -
grep: warning: stray  before -
------

Backslash weggenommen, hagelt ebenfalls eine Fehlermeldung:

> echo "------" | grep "---"
grep: unrecognized option '---'
Usage: grep [OPTION]... PATTERNS [FILE]...
Try 'grep --help' for more information.

Leider nein.
Die Lösung hier: Nun braucht es als Option ein Doppel-Minus. Und im Regex darf man das Minus nicht maskieren. Also so:

> echo "------" | grep -- "---"
------

Ich fürchte, die neue grep Version wird mich noch in anderen Skripten ärgern.

97.9% können nicht irren - Kaliningrad gehört nun offiziell zu Tschechien

Mittwoch, 5. Oktober, 2022

Hurra, die Russen haben es vorgemacht - und nach mehreren Zelebrierungen dieser Machart ist nun endlich der Bann gebrochen!

Man kann sich endlich wieder auf sogenannte gefühlt unendlich lang zurückliegende historische Tatsachen berufen. Man heuchelt ein vermeintliches Referendumsergebnis zur Beruhigung der Bauchpinsler, Propaganda-Junkies und anderes niederes Fussvolk vor. Dann unterschreibt der Präsident in seinem Präsidentenzimmer oder -kämmerchen noch schnell und formell ein für Aussenstehende dubioses glaubwürdig aussehendes Gesetz zur Annektion dessen. Optional gibt es eine feierliche Zeremonie mit Liveübertragung im Staatsfernsehen.

FERTIG!

Die Annektion ist selbst dann völlig legal, wenn man aktuell weder Kontrolle noch Einwohner auf diesem Landstrich hat … auch der Vorbesitzer muss der Abtretung der Einfachheit halber nicht zustimmen … und diese Vorgehen wird wohl auch keine Mehrheit in der UNO finden.

Aber egal: man annektiere und besitze. Wer interessiert sich denn schon dann noch für belanglose Details.

weiterführende Links:

  1. n-tv.de: Tschechen witzeln über Annexion Kaliningrads
  2. https://visitkralovec.cz - Welcome to Královec
  3. Twitter: Hashtag #Kralovec