Ereignisprotokoll der FRITZ!Box auf Linux-Server sichern

@Peter: ich habe das lsof aus dem freetz genommen. Zur Zeit würde ich auch sagen, dass das 'inotifywait' nicht das tut, was man davon erwartet. Ich habe noch einmal ein
Code:
inotifywait -e access,modify,attrib,open,close /var/.ar7events
gestartet und diverse neue Einträge im Logfile mittels des WebIF produziert... keine Reaktion. Bei einem 'addevent' über die shell, wird dann aber sofort das 'open' auf die Datei .ar7events detektiert.
Vermutlich muss ich dann doch einmal mit dem ' inotifyd' der BB versuchen, aber dazu muss ich mich damit erst wieder aus einander setzen...
Ich muss mich jetzt auch erst mal um etwas anderes kümmern, evtl. heute Abend weiter.
 
Eine bessere Lösung wäre, im neu abgerufenen Log nach dem letzten Eintrag des alten Logs zu suchen, mit eine Sekunde Toleranz im Zeitstempel, und dann die im abgerufenen Log davor stehenden, also neu dazugekommenen Einträge an das alte Log anzuhängen. Dann verliert man nur noch Einträge, wenn innerhalb von zwei Sekunden dieselbe Meldung mehrfach geloggt wird und ein Abruf genau zwischen zwei solche Einträge fällt. Außerdem werden alte Einträge nicht neu geschrieben, was nicht nur die Zeitstempel stabil hält, sondern auch Log-Überwachungstools weniger irritiert. Aber das wird mir mit bash-Skripting zu unhandlich, dafür würde ich dann zu Perl greifen.
Das hat sich nun doch als mit bash gar nicht so schwierig herausgestellt. (@PeterPawn: danke für den Tipp, das Datum per date(1) zu parsen.) Hier der relevante Abschnitt meines Cron-Jobs:

Code:
PASSWORD=GeHeim
LOGFILE=/path/to/fritz.log
FETCHCMD=/path/to/fritz-syslog.sh
FUZZ=2

if [ -s ${LOGFILE} ]
then
        # retrieve last line of existing logfile and extract timestamp
        LASTLINE="$(tail -n 1 ${LOGFILE})"
        LASTTIME=$(date -d "20${LASTLINE:6:2}-${LASTLINE:3:2}-${LASTLINE:0:2} ${LASTLINE:9:8}" +%s)
        MINTIME=$((${LASTTIME} - ${FUZZ}))
        MAXTIME=$((${LASTTIME} + ${FUZZ}))
else
        MINTIME=0
        MAXTIME=0
fi

# fetch and process log
${FETCHCMD} -p ${PASSWORD} | while read NEWLINE
do
        # skip empty lines
        [ "${NEWLINE}" == "" ] && continue
        # extract timestamp
        NEWTIME=$(date -d "20${NEWLINE:6:2}-${NEWLINE:3:2}-${NEWLINE:0:2} ${NEWLINE:9:8}" +%s)
        # stop at lines significantly older than last line already stored
        if [ ${NEWTIME} -lt ${MINTIME} ]; then break; fi
        # stop at last line already stored
        if [ ${NEWTIME} -gt ${MINTIME} -a ${NEWTIME} -lt ${MAXTIME} -a "${NEWLINE:18}" == "${LASTLINE:18}" ]
        then
                break
        fi
        # append to log in reverse order
        echo ${NEWLINE}
done | tac >> "${LOGFILE}"

Offen ist noch der Punkt:
Wenn Du das als cron-Job laufen lassen willst, solltest Du Dir einen Mechanismus zum Cachen der SID überlegen. Ansonsten müllst Du Dir nur selbst das Log mit "Anmeldung von"-Einträgen zu.
Der spannende Punkt dabei ist, zuverlässig zu erkennen, wenn die Box die gecachete SID nicht akzeptiert und ich eine neue anfordern muss.

Ansonsten beobachte ich gespannt Eure Diskussion zu /var/.ar7events - vielleicht schwenke ich eines Tages noch darauf um.
 
Zuletzt bearbeitet von einem Moderator:
@tgs-bonn:
Ich habe eine bash-basierte Lösung für das Login in eine FRITZ!Box u.a. in dem zu diesem Thema gehörenden Archiv hinterlegt (und es hat seinen Grund, warum ich das nicht einfach hier anhänge) - allerdings könnte das für Deine Zwecke etwas überdimensioniert sein und ich habe null Bock, das großartig zu kommentieren/dokumentieren - konkrete (Nach-)Fragen aber natürlich ausgenommen.

Zumindest findest Du dort eine (im Moment m.W. immer noch funktionierende) Lösung zur Erkennung der Gültigkeit einer SID - meinetwegen kannst Du das auch direkt weiterverwenden. Dort kann man die FRITZ!Box-Credentials (bzw. auch die SID) in einer temporären Datei speichern lassen (damit sie die Pause zwischen zwei Skriptläufen überdauern kann); dann mußt Du nur dafür sorgen, daß kein Unberechtigter diese Datei auslesen kann.

EDIT:
Ich bin gerade mal über eine ältere Version von mir gestolpert, die ich auf einer DOCSIS-Box bei einem Kunden mal verwendet habe, weil dort das Rooten der Box nicht erwünscht war.
Code:
# !/bin/bash
BOX="192.168.178.1"
USER="abcd"
PASSWORD="xyz"
SYSLOGFILE="/var/log/fb6360"
SYSLOGTAG="fb6360"

WGET="/usr/bin/wget"
ICONV="/usr/bin/iconv"
MD5SUM="/usr/bin/md5sum"
GREP="/usr/bin/grep"
SED="/usr/bin/sed"
MKTEMP="/usr/bin/mktemp"
SLEEP="/usr/bin/sleep"
LOGGER="/usr/bin/logger"

Login()
{
        local tf sid url req_body challenge resp md5pwd
        tf=$($MKTEMP)
        url="http://$BOX/login_sid.lua"
        if [ -n "$1" ]; then
                url="$url?sid=$1"
        fi
        $WGET -O $tf -q "$url" >/dev/null
        sid=$($SED -e 's|.*<sid>\(.*\)</sid>.*|\1|I' $tf)
        if [ "SID=$sid" == "SID=0000000000000000" ]; then
                challenge=$($SED -e 's|.*<challenge>\(.*\)</challenge>.*|\1|I' $tf)
                resp="$challenge-$PASSWORD"
                md5pwd=$(echo -n "$resp" | $ICONV --from-code=UTF-8 --to-code=UTF-16LE | $MD5SUM | $SED -e 's/ .*//')
                req_body="response=$challenge-$md5pwd&username=$USER"
                $WGET -O $tf -q --post-data="$req_body" "http://$BOX/login_sid.lua" >/dev/null
                sid=$($SED -e 's|.*<sid>\(.*\)</sid>.*|\1|I' $tf)
                if [ "SID=$sid" == "SID=0000000000000000" ]; then
                        echo "Login failed."
                        exit 1
                else
                        rm $tf
                        echo $sid
                        exit 0
                fi
        else
                rm $tf
                echo $sid
                exit 0
        fi
}

sid="0000000000000000"
tf=$($MKTEMP)
jsf=$($MKTEMP)

while true; do
        sid=$(Login $sid)
        if [ "$?" -eq 0 ]; then
                rm $tf
                $WGET -O $tf -q "http://$BOX/query.lua?sid=$sid&mq_log=logger:status/log_separate/list(time,msg,ref,type)" 2>&1 >/dev/null
                if [ "$?" -eq 0 ]; then
# an dieser Stelle käme jetzt parseJSON.sh (irgendwo vorher in diesem Thread) aus $tf nach $jsf und dann das Wegschreiben der Daten an den Zielort - hier war das eine sqlite3-Datenbank.
                fi
        fi
        $SLEEP 300s
done
Vielleicht kriegst Du ja da schon eine Idee, wie Du die SID prüfen kannst.
 
Zuletzt bearbeitet:
@tgs-bonn:
Ich habe eine bash-basierte Lösung für das Login in eine FRITZ!Box u.a. in dem zu diesem Thema gehörenden Archiv hinterlegt
Ich bin noch relativ neu hier im Forum. Wo finde ich denn das zu diesem Thema gehörende Archiv?

Zumindest findest Du dort eine (im Moment m.W. immer noch funktionierende) Lösung zur Erkennung der Gültigkeit einer SID - meinetwegen kannst Du das auch direkt weiterverwenden. Dort kann man die FRITZ!Box-Credentials (bzw. auch die SID) in einer temporären Datei speichern lassen (damit sie die Pause zwischen zwei Skriptläufen überdauern kann); dann mußt Du nur dafür sorgen, daß kein Unberechtigter diese Datei auslesen kann.
Schon klar. Das Problem habe ich ja jetzt auch schon mit dem Klartextpasswort, dass ich irgendwo hinterlegen muss.

Ich bin gerade mal über eine ältere Version von mir gestolpert, die ich auf einer DOCSIS-Box bei einem Kunden mal verwendet habe, weil dort das Rooten der Box nicht erwünscht war.
Ah, eine spezielle URL login_sid.lua zum Prüfen der SID.

Ich werde mal ein bisschen experimentieren. Die gelegentlich auftretenden Log-Meldungen:
Code:
Anmeldung an der FRITZ!Box Benutzeroberfläche von IP-Adresse 192.168.59.116 gescheitert (ungültige Sitzungskennung). Zur Sicherheit werden alle noch gültigen Sitzungen zur IP-Adresse 192.168.59.116 beendet.
verheißen einen Weg, nicht für jeden Test eine Stunde warten zu müssen, bis die SID abgelaufen ist.
 
Wo finde ich denn das zu diesem Thema gehörende Archiv?
Das ist in dem Thread verlinkt.

nicht für jeden Test eine Stunde warten zu müssen, bis die SID abgelaufen ist.
Eine Abmeldung erzielt denselben Effekt, auszulösen durch den Aufruf der LoginHome-Seite (home.lua) mit dem Parameter "logout=1".
Bzw. die Seite "login_sid.lua" mit "logout=1" funktioniert auch ... es führen viele Wege zum Ziel und das muß ja nicht immer Rom sein.
 
Zuletzt bearbeitet:
Die Schnittstelle /login_sid.lua ist für Zwecke wie diesen wirklich sehr viel schöner als /login.lua. Vielen Dank für den Tipp.

Ich habe jetzt mein Skript um eine Option "-s <sidfile>" ergänzt, die das SID-Caching realisiert:
  • Wenn in der Datei eine SID steht, wird versucht, diese für die Verbindung zu verwenden.
  • Wenn sie nicht existiert oder die darin stehende SID nicht funktioniert, wird eine Anmeldung mit Passwort versucht.
  • Bei Erfolg wird die aktuelle SID in die Datei geschrieben.

Die neue Version hängt an Beitrag #1. Kommentare und Verbesserungsvorschläge immer willkommen.
 
@KingTutt:
Ich habe mich noch etwas genauer damit befaßt, unter welchen Umständen es keine Benachrichtigungen seitens des Kernels gibt ... wenn ich raten müßte, würde ich sagen, daß dort seitens der AVM-Komponenten die .ar7events als "memory mapped file" behandelt wird und dafür gibt es keine Events, offenbar weder ein open beim mmap noch ein close bei munmap oder ein write beim Aufruf von msync. Daß es kein "read"-Event gibt, ist ja noch nachvollziehbar.

Ob man damit jetzt den Ansatz mit dem inotifywait komplett negiert, muß jeder für sich entscheiden. Es gibt genug Stellen in der Firmware, wo ganz normal mit "eventadd" protokolliert wird und dann kommt das Event ja an. Vielleicht ist es sogar sicherer, zwei unabhängige "writer tasks" zu betreiben ... einmal eine auf der Basis von inotify (die kriegt Änderungen durch eventadd unmittelbar mit) und parallel noch ein Polling (dabei muß man natürlich mit einer Semaphore sicherstellen, daß nicht beide parallel dieselbe Nachricht wegsichern wollen, das macht ja wenig Sinn), das man bei Test der Nachrichtennummer ja auch problemlos 12x pro Minute laufen lassen kann. Dabei muß man dann halt aufpassen, daß nicht der eigene "testvalue"-Aufruf inotify-Events erzeugt.

Selbst ein kleines C-Programm (wenn das wirklich mmap ist, was AVM da verwendet), das seinerseits 1x pro Sekunde den Wert an Offset 8 abfragt und bei Änderung irgendeine Aktion auslöst, wäre "straight forward".

EDIT: Was ich noch schreiben wollte (vielleicht interessiert es ja jemanden) ... die Funktionen zur Verarbeitung des Eventlogs befinden sich auch alle in der libboxlib.so (dort eben u.a. auch die Mapping-Funktionen und die Behandlung von "SharedRingBuffer"-Objekten in C++) und haben (so sagt es jedenfalls die Zeichenkettenanalyse der Lib) alle den Präfix "AR7Events_" für die Behandlung des Logs und "Event_Add" für das Hinzufügen eines neuen Eintrags. Synchronisiert wird der Zugriff offenbar mit den Funktionen "AR7Events_Lock" und "AR7Events_Unlock", damit da nicht zwei Prozesse gleichzeitig versuchen zu schreiben.

Wenn man das also für Freetz umsetzen wollte oder für irgendeine andere Lösung, die parallel sowohl das AVM-Eventlog als auch direkt einen Syslog-Eintrag schreibt, dann kann man auch die Event_Add-Funktion(en) (die ohnehin am Ende alle in einer einzelnen Funktion münden und nur wegen der Behandlung unterschiedlicher Parameter wie 9 verschiedene Funktionen aussehen) der libboxlib.so mit einer Wrapper-Funktion ersetzen, die parallel zum Schreiben in den Ringbuffer (durch Aufruf der AVM-Funktion) auch noch einen Zyklus aus openlog, syslog, closelog ablaufen läßt.

Es gibt eben viele Wege, man muß sich nur den eigenen suchen ...
 
Zuletzt bearbeitet:
@PeterPawn
Ich habe mich noch etwas genauer damit befaßt, unter welchen Umständen es keine Benachrichtigungen seitens des Kernels gibt ... wenn ich raten müßte, würde ich sagen, daß dort seitens der AVM-Komponenten die .ar7events als "memory mapped file" behandelt wird und dafür gibt es keine Events, offenbar weder ein open beim mmap noch ein close bei munmap oder ein write beim Aufruf von msync. Daß es kein "read"-Event gibt, ist ja noch nachvollziehbar.

Ob man damit jetzt den Ansatz mit dem inotifywait komplett negiert, muß jeder für sich entscheiden. Es gibt genug Stellen in der Firmware, wo ganz normal mit "eventadd" protokolliert wird und dann kommt das Event ja an.
Das mit dem inotifywait wäre eine super Sache, wenn es denn zuverlässig funktionieren würde. Da zeigt sich mal wieder der Unterschied zwischen der Theorie und der "nüchternen" Praxis.

Es bestätigt mein Motto, erst mal was ans Laufen zu bekommen, optimieren kann man immer noch. Wenn das ganze als "memory mapped file" behandelt wird hilft mir auch er inotifyd in der BB als Applet nix... und wenn ich sowieso ein Polling machen muss, dann helfen mir die 2 Stellen wo das inotifywait derzeit funktioniert (Beim Booten und vor einem Reboot) auch nicht viel.
Für mich als Non-Bash-Expert macht es ein einfaches Script wieder kompliziert wenn ich erst noch mit Semaphoren handeln muss oder parallele Threads behandeln muss...
Die ursprüngliche Idee, eine einfache Lösung zu haben, um das Ereignislog der Fritz!Box zu sichern, wird dann so aufwändig, dass das nicht mehr lohnt. Sicherlich gibt es da schöne Dinge, die man umsetzen könnte, aber das ist mir dann doch zu aufwändig.

Wenn ich Deiner weiteren Analyse der libboxlib.so folge, scheint es ja auch keinen einfachen Weg (ohne selbst am Source Hand an zu legen) zu geben, das ganze ohne Polling in den Griff zu bekommen :confused:

Ich habe jetzt erst mal die ersten zwei Zeilen mit dem inotifywait und der Rückgabe Überprüfung raus genommen und am Ende der Schleife wieder ein Sleep eingebaut, so dass ich quasi Deine Lösung als klassisches Polling habe.
 
@KingTutt:
Solange Du mit der Auswertung der Nachrichtennummer schnell und sicher erkennen kannst, ob neue Nachrichten vorliegen oder nicht, war der Aufwand ja doch nicht umsonst.

Ansonsten müßte man immer noch das Datum von Einträgen parsen (mit dem bekannten Rundungsfehler) oder auf die Zeilenanzahl in der Ausgabe von "eventsdump" achten (was beim Rollover dann ohnehin falsch wird).

Also funktioniert zwar inotifywait bei der Art des Zugriffs durch die AVM-Komponenten nicht richtig (ist mir nie vorher aufgefallen, wahrscheinlich weil ich selbst zuviele "eventadd"-Kommandos verwendet habe bzw. das ja nie selbst mit "eventsdump" ausgewertet habe) - aber ein wenig Optimierung sollte da schon erfolgreich praktiziert worden sein.

EDIT: Das mit dem "Optimieren kann man immer noch ..." kenne ich auch, ich habe immer noch Q&D-Skriptcode aus den letzten 10 Jahren an einigen Stellen am Laufen.
 
@PeterPawn
Der Aufwand war sicherlich nicht umsonst, Dank Deiner Hilfe ist das mit den Zielstempeln auf jeden Fall viel besser gelöst! Die Idee mit dem inotifywait fand ich auch sehr charmant, leider macht AVM da einen Strich durch die Rechnung. Ob die Auswertung mit "eventsdump" oder direkt aus der .ar7event passiert ist ja egal, entscheidend ist ja ein Weg, mitzubekommen, wann wieder etwas neues vorhanden ist. Wenn man natürlich selbst genug mit "eventadd" erzeugt, bekommt man "den Rest" quasi als Bonbon mitgeliefert :)
Vielleicht macht sich ja irgend wann man jemand die Mühe, Deinen Vorschlag aus #47 in freetz mit einzubauen (glaub ich allerdings nicht), ich würde es nutzen ;)
 
Mit einer kleinen Erweiterung der sed-Regexe funktioniert das Skript auch mit der Laborversion 113.06.35-31050.
Neue Version 0.4 ist an Beitrag #1 hochgeladen.
 
Ich habe die Möglichkeit hinzugefügt das Log auf der Box zu löschen
Code:
#!/bin/bash
# auslesen des Systemereignisprotokolls einer FRITZ!Box
# Aufruf:
# fritz-syslog.sh [ -a <addr> ] [ -u <username> ] [ -p <password> ] [ -j | -r ] [ -o <outfile> ]
# Optionen:
# -a <addr> Adresse der FRITZ!Box (Default: fritz.box)
# -u <username> Benutzername für die Anmeldung (Default: leer)
# -p <password> Passwort für die Anmeldung (Default: leer)
# -s <file> SID-Cachedatei (Default: keine)
# -o <file> Ausgabedatei (Default: Standardausgabe)
# -j    Ausgabeformat JSON (Default: Text)
# -r    Ausgabeformat HTML (Default: Text)
# -d Löscht das Protokoll auf der FRITZ!Box
#
# inspiriert durch http://www.administrator.de/contentid/214598
# und viele Anregungen von Peter Pawn @ IP Phone Forum
# Free Open Source Software released under GPLv2
# see http://www.gnu.org/licenses/gpl-2.0
# Author: Tilman Schmidt <[email protected]>
# Release: 0.4 2015-08-14

# default values
FBUSER=""
FBPASS=""
SIDFILE=
FBURL="https://fritz.box"
OUTFILE="/dev/stdout"
OUTFMT=text

PATH=/bin:/usr/bin

while [ $# -gt 0 ]
do
  case "$1" in
  -a) shift ; FBURL="http://$1" ;;
  -d) shift ; DELETE=1 ;;
  -u) shift ; FBUSER=$1 ;;
  -p) shift ; FBPASS=$1 ;;
  -j) shift ; OUTFMT=json ;;
  -r) shift ; OUTFMT=raw ;;
  -o) shift ; OUTFILE=$1 ;;
  -s) shift ; SIDFILE=$1 ;;
  -h) echo "Usage: $0 { -a <addr> } { -u <username> } { -p <password> } { -j | -r } { -o <outfile> } { -s <sidfile> }" ; exit 0 ;;
  -*) echo "unknown option $1" ; exit 1 ;;
  *) echo "extra argument $1" ; exit 1 ;;
  esac
  shift
done

# Authentifizierung
if [ -r "${SIDFILE}" ]
then _SID=$(cat "${SIDFILE}")
fi
_REPLY=$(curl -k -s ${FBURL}/login_sid.lua?sid=${_SID})
_SID=$(expr "${_REPLY}" : ".*<SID>\([0-9a-fA-F]*\)</SID>")
_CHALLENGE=$(expr "${_REPLY}" : ".*<Challenge>\([0-9a-fA-F]*\)</Challenge>")
if [ -z "${_SID}" -o -z "${_CHALLENGE}" ]
then
  echo "Could not get authentication challenge from ${FBURL}"
  exit 1
fi
if [ "${_SID}" == "0000000000000000" ]
then
  _MD5=$(echo -n "${_CHALLENGE}-${FBPASS}" | iconv -f ISO8859-1 -t UTF-16LE | md5sum -b)
  _REPLY=$(curl -k -s -d "response=${_CHALLENGE}-${_MD5:0:32}" -d "username=${FBUSER}" ${FBURL}/login_sid.lua)
  _SID=$(expr "${_REPLY}" : ".*<SID>\([0-9a-fA-F]*\)</SID>")
fi
if [ -z "${_SID}" -o "${_SID}" == "0000000000000000" ]
then
  echo "Could not authenticate to ${FBURL}"
  exit 1
fi
if [ -n "${SIDFILE}" ]
then echo "${_SID}" > "${SIDFILE}"
fi


# Syslog auslesen, gewünschtes Format extrahieren
curl -k -s -G "${FBURL}/system/syslog.lua" -d 'tab=aus' -d 'stylemode=print' -d 'sid='${_SID} |
case "$OUTFMT" in
"text") sed -e '1,/^<table .*class="zebra.*">/d' -e '/^<\/table>/,$d' -e 's/^<tr><td[^>]*>//' -e 's/<\/td><td[^>]*>/ /g' -e 's/<\/td><\/tr>$//' -e 's/<span[^>]*>//g' -e 's/<\/span>//g' -e 's/<a [^>]*>//' -e 's/<\/a>//' ;;
"json") sed -e '1,/^<pre>/d' -e '/^<\/pre>/,$d' ;;
*) cat ;; # useless use of cat
esac > ${OUTFILE}

# Log auf der Box löschen
if [ -n "${DELETE}" ]
then curl -k -s "${FBURL}/system/syslog.lua?sid=${_SID}" -d 'delete=1' -d 'sid='${_SID}   > /dev/null
fi
 
Moins


Nice.

Getestet auf Raspberry Pi mit OSMC/KODI über SSH in einer tmux Konsole.

Mit Parameter -a macht es allerdings einen HTTP Zugriff. :(
Ich hab darüber versucht den (geänderten) HTTPS Port anzugeben.
Da kam dann der Quatsch bei raus: "http://https://fritz.box:12345"
...einzig mit -a fritz.box hats dann geklappt.

Schlage vor als Standardwert "http://fritz.box" zu wählen und -a mit "https://" zu Präfixen.

Ach ja, Parameter -d wird (noch) nicht mit -h angezeigt. ;)
 
Zuletzt bearbeitet:
Falls irgendjemand die Anmerkung zu /sbin/eventctrl in diesem Beitrag gelesen haben sollte ... diesen Aufruf hat AVM spätestens in der Version 113.06.36-31410 vom 24.09.2015 dann bereits entsorgt (nachdem er jahrelang vorhanden war).

Da ich das auch nicht regelmäßig kontrolliere (um diesen Unterschied zu erkennen, muß man ja auch noch die var.tar aus der jeweiligen Firmware entpacken und vergleichen und mein eigener Aufruf kommt (bzw. kam) ja mit dem yourfritz-Modscript dann wieder rein), ist es mir auch erst heute aufgefallen, als ich mal versucht habe, eine nachnutzbare Modifikation für "modfs" zu bauen, die das Eventlog vor dem Neustart in der wrapper-Partition sichert und ich nach dem üblichen "Aufhänger" greifen wollte, mein Skript jedoch partout nicht aufgerufen wurde.

Es ist zwar kein großes Kunststück, da wieder etwas passendes in die /var/post_install einzubauen (bzw. das gleich in die /etc/inittab als weiteren Aufruf integrieren, das spart die Änderung am tar-File und auf NAND-Modellen klappt das auch, weil die /var/post_install selbst beim Firmware-Update noch bis zum Ende kommt) ... aber wer sich auf NOR-Modellen mit neuer Firmware auf die von mir im früheren Beitrag gezeigten Zeilen verläßt, der schaut in die Röhre.
 
6.80 not supported

Mit dem Update auf FRITZ!OS 06.80 ist nun eingetreten, was PeterPawn von Anfang an prophezeit hat: /system/syslog.lua funktioniert nicht mehr. Es liefert nur noch leeren Output. Das als Alternative empfohlene Interface /query.lua funktioniert noch. Nun ist also JSON-Parsing angesagt. Leider funktioniert das in #4 gepostete Skript bei mir nicht. Es liefert seinerseits nur leeren Output. Hat jemand einen Tipp, wie ich das Skript zum Laufen oder das JSON-Format auf anderem Wege in einfache Textform mit einer Meldung pro Zeile konvertiert kriege? Ansonsten könnte es etwas dauern, bis ich eine Version des Skripts zusammenhabe, das mit der neuen FRITZ!OS-Version funktioniert.
 
Ja, zum "parseJSON" hätte ich noch einiges schreiben müssen ... es geht schon damit los, daß die äußeren geschweiften Klammern um so ein JSON-Objekt erst mal entfernt werden müßten und auch "Arrays in Arrays" nicht so richtig gut verdaut werden.

Aber solange man das Format strikt vorhersagen kann, wie es bei der Abfrage von "logger:status/log" ja der Fall ist (wenn man "mq" verwendet im Variablennamen), solange kann man das ja auch mit ganz simplen Kommandos für den "sed" zerlegen.

Das Splitten in Zeilen ist schnell gemacht, wenn man "],[" in "\n" ändert und das Entfernen von '{"mq_log":[' am Beginn und der letzten schließenden eckigen Klammer ist ja nur eine Pflichtübung.

Dann hat man schon mal die einzelnen Zeilen nach dem "Strickmuster":
Code:
["13.02.17 06:57:02 Internetverbindung IPv6 wurde getrennt, Präfix nicht mehr gültig.","28","2"],
und da kann man sich nun auch noch überlegen, was man mit den eckigen Klammern außen herum und ggf. der Nachrichtennummer und der Kategorie noch veranstalten will.

Im einfachsten Fall schneidet man alles außerhalb der ersten Anführungszeichen einfach weg und hat den reinen Text als zeilenweise Datei vorliegen. Da muß man (wenn es nur um dieses Protokoll geht) gar keinen riesigen Aufwand betreiben und die "echte" Struktur der JSON-Daten einlesen, solange man die nicht in dieser Form irgendwie weiterverarbeiten will.

Eine Möglichkeit wären folgende (Shell-)Komnandos:
Code:
SID=<my_sid>
wget -q -O - http://fritz.box/query.lua?sid=$SID\&mq_log=logger:status/log | \ <=== Daten abrufen
sed -e "s/{//;s/}//" -e "s/\"mq_log\":\[\[//" -e "s/\]\]//" -e "s/\],\[/\n/g" | \  <=== Beginn und Ende entfernen, zeilenweise Ausgabe
sed -e "s/,\"[0-9]*\",\"[0-9]*\"\$//" | \ <=== die letzten beiden numerischen Felder jeder Zeile entfernen
sed -e "s/^\"//;s/\"\$//" <=== hier noch die letzten Anführungszeichen vorne und hinten entfernen
Wenn man will, kann man jetzt noch Datum und Uhrzeit abtrennen, usw., usf. - der Phantasie sind wie üblich keine Grenzen gesetzt. Es muß also kein JSON-Parser sein.
 
6.80 supported

So schnell kann's gehen:
Wie auf Bestellung fand ich gerade beim Durchblättern der c't 4/2017 (ja, ich bin mal wieder ein Heft im Rückstand ...) den Artikel "JSON in der Shell verarbeiten" und das Programm jq.
Heruntergeladen, getestet - läuft prima.
Eine neue Version von fritz-syslog.sh habe ich gerade hochgeladen.

@PeterPawn: Trotzdem vielen Dank für die schnelle Antwort. Wäre mir nicht zufällig dieser Artikel in die Hände gefallen, hätte ich es sicher so gemacht.
@marcohald: Deine Option -d ist damit leider wieder raus.
 
Cronjob

Danke für das tolle Skript. Dann möchte ich meine Simple-Lösung die ich auf einem Linux Server als Cronjob laufen habe auch mal beitragen. Folgender Code erzeugt eine Log Datei, die die immer neusten Einträge immer am Anfang enthält und (für mich unnötige) Eintrage gleich mit ausfiltert:

Code:
{ cat /var/log/fb.log & /opt/scripts/fritz-syslog.sh; } | grep -v -i powerline | sort -u | sort -r -t. -n -k 3 -k2 -k1 > /var/log/fb.log

Leider liefert meine 7362SL 6.80 immer noch Zeitstempel die von Aufruf zu Aufruf gerne mal um 1 Sekunde variieren.
 
Zuletzt bearbeitet:
Gibt es eine Möglichkeit Ereigniss "SMS empfangen von..." mit Tasker auslesen zu können?
MfG
Heimatkanal
 
Hallo Heimatkanal,
ich verstehe leider die Frage nicht.
Auf meiner Fritzbox und meinem Linux-Server habe ich weder Tasker noch Ereignisse "SMS empfangen".
LG tgs-bonn
 

Statistik des Forums

Themen
246,347
Beiträge
2,250,587
Mitglieder
374,001
Neuestes Mitglied
curious2315
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.