LOG auswertung in Shell | Addieren mit awk bei bestimmter Bedingung

G

GreenCream

Grünschnabel
Hallo Leute,

ich bin relativ neu in der Shell und in der Linux-Welt überhaupt.

Jetzt versuche ich gerade ein Script zu schreiben dass mir die Größe eines Backups aus einem Logfile ausliest (um es per snmp abfragen zu können).

Es geht dabei um eine einzige Datei (pro Tag) in der Die Größe und die Art des Backups von ca 30 Rechnern aufgezeichnet wird.

Es gibt für jeden Rechner eine Zeile in der die Größe des Backups steht, und eine Zeile in der Steht was für eine Art von Backup (Full/Incremental) es war. (Ausnahme ist ein Rechner (im Beispiel Rechnerx) für den es nur die Zeile mit der Größe gibt, hier ist es immer ein Full Backup.)

Es kann (an einem Tag) Rechner geben die sowohl ein Full als auch ein Incremental Backup gemacht haben.

So sieht das ganze aus:
Code:
28.10.2008 Linux backupserver1
Rechner1: Bytes written to media:        182744
Rechner4: Bytes written to media:        52070587
Rechner6: Bytes written to media:        66581055
Rechner2: Bytes written to media:        30104
...
Rechner4: Incremental backup finished.
Rechner6: Incremental backup finished.
Rechner2: Incremental backup finished.
Rechner1: Incremental backup finished.
...
28.10.2008 Linux Backupserver
Rechnerx: Bytes written to media:        30104
Rechner4: Bytes written to media:        52070587
Rechner6: Bytes written to media:        66581055
...
Rechner6: Full backup finished.
Rechner2: Full backup finished.
Rechner4: Full backup finished.
...

Das Ziel ist das script mit dem Parameter "Full" oder "Incremental" aufzurufen und die Summe der geschriebenen Bytes zurückzubekommen.

Ich plage mich jetzt schon ein paar Tage dran und habe schon ne ganze Menge ausprobiert, bin nur nie wirklich weitergekommen. (Auser dass ich schon ein bisschen mehr über shell gelernt habe)

Mein letzter Versuch ging in die Richtung die beiden Zeilen die zu einem Rechner gehören in eine Zeile zu schreiben, dann 2 Dateien draus zu machen, und anschließend mit awk beide Dateien einzeln auszuwerten.

Code:
sort $sizefile | sed ':;s/finished./  finised.EOL/;N;T' | sed ':;s/\n/ /;N;T' | sed ':;s/EOL/  \n/g;N;T'  >> tempfile1

grep 'full' tempfile1 > tempfile2
grep 'Incremental' tempfile1 > tempfile3

groese1=$(less tempfile2 | awk '/written/ | $1  {summe += $6} END { printf ("%d",summe)}')

groese2=$(less tempfile3 | awk '/written/ | $1  {summe += $6} END { printf ("%d",summe)}')
Aber funktionieren tut es genauso wenig.

Ich verwende die sh shell, bash oder tcsh würden auch gehen, wenn es damit einfacher wäre. Pearl nur wenn es sich wirklich nicht vermeiden lässt.

Vieleicht habt ihr ja noch eine ganz andere Idee wie ich sowas anfangen könnte.

Gruß
Benjamin


Edit:
Infos zum System:
openSUSE 10.2 (i586)
VERSION = 10.2
Linux version 2.6.18.2-34-default (geeko@buildhost) (gcc version 4.1.2 20061115 (prerelease) (SUSE Linux)) #1 SMP Mon Nov 27 11:46:27 UTC 2006
 
Zuletzt bearbeitet:
Kann nicht das Backupscript geändert werden, damit auch der Typ des Backups in der gleichen Zeile steht wie die anzahlt der kopierten Bytes??
Also:

Code:
Rechner1: Bytes Incremental written to media:        182744  # oder so in der Art

Dann währe das kein Problem!
 
Kann nicht das Backupscript geändert werden, damit auch der Typ des Backups in der gleichen Zeile steht wie die anzahlt der kopierten Bytes??

Die Daten in diesem File Sammel ich ebenfalls per Grep aus tempfiles die das Backup wärend des backups anlegt und auch wieder löscht.
Auf die Erstellung dieser tempfiles habe ich nur wenig Einfluss, und möchte am eigentlichen Backupsystem auch nichts verändern.
 
Hi,

also von awk habe ich keine Ahnung (werde ich auch nie haben ;)), aber wenn du die Dateien eh schon sauber aufgetrennt hast sollte sich das z.B. mit cut machen lassen.
Hier mal ein Beispiel, wobei in written.tmp die Information steht, wieviel bytes geschrieben wurden, und in inc.tmp stehen dann die Rechner fuer die inkrementellen backups.
Im Beispiel wird davon ausgegangen, dass anhand der Doppelpunkte getrennt wird. Siehe "man cut".

Code:
#!/bin/bash

sum=0

while read line; do
    # extrahiere den Computernamen "comp"
    comp=$(echo $line | cut -d":" -f 1)

    # extrahiere die Anzahl der geschriebenen bytes fuer computer "comp"
    bytes=$(grep $comp written.tmp | cut -d":" -f 3)

    # fuege die bytes zur Summe hinzu.
    ((sum += bytes))
done < inc.tmp

echo "Sum: $sum"

Edit: Habe nochmal ein paar comments in den code gepackt.

mfg,
bytepool
 
Zuletzt bearbeitet:
Hi,

mir ist nicht ganz klar, wie das Ergebnis aussehen soll: willst du einfach die Gesamtgrösse aller Backups pro Rechner auflisten? Das ginge mit awk relativ einfach etwa so:

Code:
awk '
        /written/       { size[$1] += $6; seen[$1]++; type[$1] = "Full"; }
        /finished/      { type[$1] = $2; }
        END             { for (comp in seen) { print comp, size[comp], "(", type[comp], ")"; }; }
' <logfile

Wenn du allerdings z.B. die Incrementals pro Rechner aufaddieren, und sowohl Full als auch Incremental Backups separat auflisten willst, müsste man bei der Verarbeitung der "finished"-Zeilen ein bisschen mehr Aufwand betreiben (die bisher gefundenen Daten für den aktuellen Rechner ausgeben und dann auf 0 zurücksetzen etc.), und im END-Abschnitt sicherstellen, dass man auch die Backups noch ausgibt, für die kein "finished"-Eintrag im Log steht ...
 
mir ist nicht ganz klar, wie das Ergebnis aussehen soll: willst du einfach die Gesamtgrösse aller Backups pro Rechner auflisten?

Sorry, hab ich glaube ich wirklich nicht verständlich genug erklärt.

Es sollen 2 Summen ausgegeben werden:
1. Die Größe aller Incremntal Backups auf allen Rechnen an diesem Tag
2. Die Größe aller Full Backups auf allen Rechnen an diesem Tag

Ein Tag = eine Datei

Zur Erklärung:
Es wird in dem script immer nur eine Datei ausgewertet alles andere folgt hinterher. Das ganze wird per snmp aufgerufen und in cacti als "chart" dargestellt. Daran soll mann dann erkennen wie sich das Backup entwickelt.

@bytepool: Dein Ansatz sieht (so wie ich ihn verstanden habe) gut aus. Ich werde im laufe des Tages damit mal rumprobieren.
 
Ich binn leider damit auch nicht weitergekommen,
langsam geht mir die shell-scripterei echt auf die nerven.

Wie sollte das den erst sein wenn mann richtig aufwändiges macht...
 
Ich binn leider damit auch nicht weitergekommen,

Wie weit bist du denn gekommen??
Was funktioniert nicht, was geht schonmal?

langsam geht mir die shell-scripterei echt auf die nerven.
Dann lass es doch einfach......

Wie sollte das denn erst sein wenn mann richtig aufwändiges macht...
Für jedes Problem gibt es ein mehr oder weniger geeignetes Werkzeug, um es zu lösen.
Du nimmst sicherlich auch eine Zange um einen Nagel in die Wand zu hauen?!
 
Hast ja recht,
vermutlich isses sogar alles ganz logisch und einfach; wenn manns erstmal kann *g*

Aber wenn mal wieder nix geht wie es soll fällt halt dir motivation!


Wie weit bist du denn gekommen??
Was funktioniert nicht, was geht schonmal?

Mommentan versuche ich es etwa so:

Code:
sort 03112008 | sed ':;s/finished./  finised.EOL/g;N;T' | sed ':;s/\n/ /;N;T' | sed ':;s/EOL/  \n/g;N;T'  >> tempfile1
#Sortieren, einen String ans Ende jeder Zeile "finished" Zeile, Zeilenumbrüche Raus, String wieder durch Zeilenumbrüche ersetzen.
# Das Einfügen Klappt troz /g nur nur in der ersten Zeile

grep "$1" tempfile1 | awk '/written/ | $1  {summe += $6} END { printf ("%d",summe)}')
#Aufspalten für entweder nur Incremental oder Full | Aufadieren der Anzahl der geschriebenen Bytes (Ich denke Spalte 6) aus dem tempfile2
# Meldet "syntax error near unexpected token `)'"

Ich weiß binn aber nicht sicher ob das überhaupt zum Ziel führt.
 
Hast ja recht,
vermutlich isses sogar alles ganz logisch und einfach; wenn manns erstmal kann *g*

Aber wenn mal wieder nix geht wie es soll fällt halt dir motivation!
Kenn ich. :-)





Zum Problem:

Inhaltlich habe ich mich (noch) nicht damit beschäftigt, aber es liegt ein Syntaxfehler vor.

Code:
grep "$1" tempfile1 | awk '/written/ | $1  {summe += $6} END { printf ("%d",summe)}')

Die runde Klammer am Ende wird nirgendwo geöffnet, oder?
 
Kenn ich. :-)
Die runde Klammer am Ende wird nirgendwo geöffnet, oder?

Richtig, da hab ich wirklich ned aufgepasst, jetzt bekomme ich wieder den Fehler den ich vorher schon hatte:
awk: ^ syntax error
awk liest doch aus der Pipe, oder?
 
Klar, awk kann aus einer Pipe lesen. Aber was willst du mit dem Konstrukt
Code:
/written/ | $1
in deinem awk-Pattern genau filtern? Das sieht mir nämlich nach deinem Syntax error aus :-) ...

Ich hab mal mit awk ein bisschen weitergespielt:
Code:
awk '
        /written/       {
                                seen[$1]++;                     # Computername merken
                                size[$1] += $6;                 # Summe pro Backup/Computer
                        }
        /finished/      {
                                total[$2] += size[$1];          # jetzt ist klar - full oder incremental
                                                                # also entsprechend erfassen, dann
                                size[$1] = 0;                   # zurücksetzen, damit wir nicht doppelt zählen
                        }
        END             {
                                                                # Die Backups, für die keine "finished" lines
                                                                # gefunden wurden, werden als Full gezählt
                                for (comp in seen) {
                                        if (size[comp] > 0) {
                                                total["Full"] += size[comp];
                                        }
                                };

                                print "Total Full Backups: ", total["Full"];
                                print "Total Incrementals: ", total["Incremental"];
                        }
'
Vorteil bei diesem Ansatz ist, dass du dein Logfile in einem Durchlauf verarbeiten kannst, und nicht für jeden Rechner wieder von vorne (grep ...) anfängst.
 
Danke für die Hilfe!

Wow, funktioniert auf Anhieb!

Ich weiß zwar (noch) nicht genau was dein awk-Konstrukt da macht :think:, aber es ist genau das was ich wollte :]

Nachdem es ja jetzt tut wird mir das awk-Manual sicher auch im Detail erklären was da vor sich geht.

Danke an alle
Gruß
Benjamin
 

Ähnliche Themen

rsnapshot und ein Rechteproblem?

Mit awk ein textfile parsen und SQL daraus erzeugen.

E-Mail Empfang, Aliases unter Debian Squeeze

OpenSUSE 12.1: Gnucash startet nicht mehr

Log filtern summieren mit AWK

Zurück
Oben