#!/usr/bin/perl -w # # Siehe http://www.schaarwaechter.de/rsyncbackup.html # Version 1.0 10/05 # Version 1.1 11/06 Kleine Bugs # use Date::Calc qw(:all); use Data::Dumper; our $logpath="/root/backup/logs"; our $output="/srv/www/htdocs/backup/analyse.html"; our $linkpath="/sicherungslogs"; our @dows=qw(Monday Tuesday Wednesday Thursday Friday Saturday Sunday); our %data; our %youngest; opendir(DIR,$logpath) or die "Could not open $logpath: $!\n"; while (my $file=readdir(DIR)) { my $startzeit=""; my $endezeit=""; my $startcp=""; my $endecp=""; my $rsyncstart=""; my $rsyncende=""; my $rsyncfailed=""; my $beforebackupfailed=""; my $alteloeschenstart=""; my $alteloeschenende=""; my $nofiles=""; my $nofilestrans=""; my $totalsize=0; my $totalsizetrans=0; my $filelistsize=0; my @rsyncerrors; next if ($file=~m/^\.{1,2}/); next if (not $file=~m/^backup_(.*)-(.*?)\.log$/); my $server=$1; my $dow=$2; open(FILE,"$logpath/$file") or die "Could not open $logpath/$file: $!\n"; while (my $z=) { # 051005_191501 Start backup.sh if ($z=~m/^(.{13}) Start backup.sh/i) {$startzeit="20".$1} if ($z=~m/^(.{13}) Ende backup.sh/i) {$endezeit="20".$1} if ($z=~m/^(.{13}) sichere letztes Backup/i) {$startcp="20".$1} if ($z=~m/^(.{13}) letztes Backup von .*? gesichert/i) {$endecp="20".$1} if ($z=~m/^(.{13}) rsyncstart von/i) {$rsyncstart="20".$1} if ($z=~m/^(.{13}) rsync von .*? beendet/i) {$rsyncende="20".$1} if ($z=~m/^(.{13}) rsync .*? gescheitert/i) {$rsyncfailed="20".$1} if ($z=~m/^(.{13}) BEFOREBACKUP Ende: .*? gescheitert!/i) {$beforebackupfailed="20".$1} if ($z=~m/^(.{13}) loesche aelteste Sicherung von /i) {$alteloeschenstart="20".$1} if ($z=~m/^(.{13}) aelteste Sicherung .*? geloescht/i) {$alteloeschenende="20".$1} if ($z=~m/^Number of files: (\d*)/i) {$nofiles=$1} if ($z=~m/^Number of files transferred: (\d*)/i) {$nofilestrans=$1} if ($z=~m/^Total file size: (\d*)/i) {$totalsize=$1} if ($z=~m/^Total transferred file size: (\d*)/i) {$totalsizetrans=$1} if ($z=~m/^File list size: (\d*)/i) {$filelistsize=$1} if ($z=~m/^(rsync error: .*?)$/i) {push(@rsyncerrors,$1)} if ($z=~m/^(rsync: .*?)$/i) {push(@rsyncerrors,$1)} } close FILE; next if (not $startzeit); next if (not ($endezeit or $rsyncfailed or $beforebackupfailed)); $startzeit=~m/^(....)(..)(..)_(..)(..)(..)/; my @start=($1,$2,$3,$4,$5,$6); my @jetzt=&Today_and_Now(); next if(&Delta_Days($start[0],$start[1],$start[2],$jetzt[0],$jetzt[1],$jetzt[2]) > 7); my @ende; if ($endezeit) { $endezeit=~m/(....)(..)(..)_(..)(..)(..)/; @ende=($1,$2,$3,$4,$5,$6); } elsif ($rsyncfailed) { $rsyncfailed=~m/(....)(..)(..)_(..)(..)(..)/; @ende=($1,$2,$3,$4,$5,$6); } else { $beforebackupfailed=~m/(....)(..)(..)_(..)(..)(..)/; @ende=($1,$2,$3,$4,$5,$6); } $startcp=~m/(....)(..)(..)_(..)(..)(..)/; my @cpstart=($1,$2,$3,$4,$5,$6); $endecp=~m/(....)(..)(..)_(..)(..)(..)/; my @cpende=($1,$2,$3,$4,$5,$6); $rsyncstart=~m/(....)(..)(..)_(..)(..)(..)/; my @rsyncstart=($1,$2,$3,$4,$5,$6); my $alteloeschendauer=""; if ($alteloeschenstart) { $alteloeschenstart=~m/(....)(..)(..)_(..)(..)(..)/; my @alteloeschenstart=($1,$2,$3,$4,$5,$6); $alteloeschenende=~m/(....)(..)(..)_(..)(..)(..)/; my @alteloeschenende=($1,$2,$3,$4,$5,$6); my @alteloeschendauer=&Delta_DHMS(@alteloeschenstart,@alteloeschenende); $alteloeschendauer="$alteloeschendauer[2]m $alteloeschendauer[3]s"; $alteloeschendauer="$alteloeschendauer[1]h ".$alteloeschendauer if ($alteloeschendauer[1]); $alteloeschendauer="$alteloeschendauer[0] d, ".$alteloeschendauer if ($alteloeschendauer[0]); } my @rsyncende; if (not $rsyncfailed) { $rsyncende=~m/(....)(..)(..)_(..)(..)(..)/; @rsyncende=($1,$2,$3,$4,$5,$6); } else { $rsyncfailed=~m/(....)(..)(..)_(..)(..)(..)/; @rsyncende=($1,$2,$3,$4,$5,$6); } my @dauer=&Delta_DHMS(@start,@ende); my $dauer="$dauer[2]m $dauer[3]s"; $dauer="$dauer[1]h ".$dauer if ($dauer[1]); $dauer="$dauer[0] d, ".$dauer if ($dauer[0]); my $start="$start[3]:$start[4]"; my @cpdauer=&Delta_DHMS(@cpstart,@cpende); my $cpdauer="$cpdauer[2]m $cpdauer[3]s"; $cpdauer="$cpdauer[1]h ".$cpdauer if ($cpdauer[1]); $cpdauer="$cpdauer[0] d, ".$cpdauer if ($cpdauer[0]); my @rsyncdauer=&Delta_DHMS(@rsyncstart,@rsyncende); my $rsyncdauer="$rsyncdauer[2]m $rsyncdauer[3]s"; $rsyncdauer="$rsyncdauer[1]h ".$rsyncdauer if ($rsyncdauer[1]); $rsyncdauer="$rsyncdauer[0] d, ".$rsyncdauer if ($rsyncdauer[0]); my $rsyncerrors=scalar(@rsyncerrors); $totalsize=int( ($totalsize/1024/1024/1024) *100) / 100; $totalsizetrans=int( ($totalsizetrans/1024/1024/1024) *100) / 100; $filelistsize=int( ($filelistsize/1024/1024) *100) / 100; my $bg="nix"; $bg="bgrot" if ($rsyncerrors or $beforebackupfailed); $data{$server}{$dow}=qq#
$file
Start$start
Dauer ges.$dauer
Dauer cp$cpdauer
Dauer rm altes B.$alteloeschendauer
Dauer rsync:$rsyncdauer
Dateien ges.$nofiles
Dateien transf.$nofilestrans
Dateimenge ges.$totalsize GB
Dateimenge transf.$totalsizetrans GB
rsync-Dateiliste$filelistsize MB
(rsync-)Fehler$rsyncerrors
#; if (not defined($youngest{$server."remember"}) or $youngest{$server."remember"} lt $startzeit) { $youngest{$server}=$dow; $youngest{$server."remember"}=$startzeit; } } closedir(DIR); my @jetzt=&Today_and_Now(); my $jetzt="$jetzt[2].$jetzt[1].$jetzt[0], $jetzt[3]:$jetzt[4]:$jetzt[5]"; print < Auswertung Sicherungslogs

Der Backupserver

Verfuegbarer Plattenplatz auf lxbackup:
HTML
open(PIPE,"df -h|");
while () {print}
close PIPE;
print <

Das Restore von Daten, sollte es einmal notwendig sein, kann zur Zeit nur per Kommandozeile geschehen. Dazu muss jemand mit root-Rechten auf lxbackup die entsprechende Datei/Verzeichnis aus /export/backup/servername (aktuelle Sicherungen) bzw. /export/generationen/servername (Generationensicherungen) finden und dann den folgenden Befehl verwenden.

root\@lxbackup> rsync -avz -e "ssh -i /root/.ssh/rsync-key" QUELLE ZIEL
In dem folgenden Beispiel soll die index.html auf dem Webserver restauriert werden:
root\@lxbackup> rsync -avz -e "ssh -i /root/.ssh/rsync-key" /export/backup/lx1/srv/www/htdocs/index.html lx1:/srv/www/htdocs
Achtung: Dieser Befehl überschreibt die Datei auf dem Webserver sofort!
Anstelle der Datei kann auch ein Verzeichnis bzw Wildcard (*) angegeben werden. Bitte sehr genau darauf achten,
was wohin geschrieben wird - ich sags nochmal: Enter nach dem obigen Befehl und er fängt sofort an!

Ergebnis der Sicherungen

Berücksichtigt werden alle Sicherungen, die innerhalb der letzten Woche gelaufen sind. In der letzten Zeile rot markiert sind Sicherungen mit Abbrüchen/Problemen - in diesem Fall Log ansehen, auch wenn eine Null in rot gezeigt wird! Die Zahl zählt nur die Fehler, die beim rsync-Lauf aufgetreten sind, wenn z.B. ein Befehl, der vor dem rsync ausgeführt werden soll, gescheitert ist, startet rsync aber gar nicht erst.
Gelb markiert sind die jeweils letzten Sicherungen.
Stand: $jetzt

HTML foreach $dow(@dows) { print qq##; } print qq##; foreach $srv(sort keys %data) { print qq##; foreach $dow(@dows) { if (defined $data{$srv}{$dow}) { if ($youngest{$srv} eq $dow) { $data{$srv}{$dow}=~s/§heute§/bggelb/sg; } else { $data{$srv}{$dow}=~s/§heute§/nix/sg; } print qq##; } else { print qq##; } } }
 $dow
$srv#,$data{$srv}{$dow},qq#