#!/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=<FILE>) {
      # 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#
                    <table class="nowrap">
                    <tr><td colspan="2" class="sehrklein"><span class="§heute§"><a href="$linkpath/$file">$file</a></span></td></tr>
                    <tr><td class="klein">Start</td><td class="rrahmen">$start</td></tr>
                    <tr><td class="klein">Dauer ges.</td><td class="rrahmen">$dauer</td></tr>
                    <tr><td class="klein">Dauer cp</td><td class="rrahmen">$cpdauer</td></tr>
                    <tr><td class="klein">Dauer rm altes B.</td><td class="rrahmen">$alteloeschendauer</td></tr>
                    <tr><td class="klein">Dauer rsync:</td><td class="rrahmen">$rsyncdauer</td></tr>
                    <tr><td class="klein">Dateien ges.</td><td class="rrahmen">$nofiles</td></tr>
                    <tr><td class="klein">Dateien transf.</td><td class="rrahmen">$nofilestrans</td></tr>
                    <tr><td class="klein">Dateimenge ges.</td><td class="rrahmen">$totalsize GB</td></tr>
                    <tr><td class="klein">Dateimenge transf.</td><td class="rrahmen">$totalsizetrans GB</td></tr>
                    <tr><td class="klein">rsync-Dateiliste</td><td class="rrahmen">$filelistsize MB</td></tr>
                    <tr><td class="klein"><span class="$bg">(rsync-)Fehler</span></td><td class="rrahmen"><span class="$bg">$rsyncerrors</span></td></tr>
                    </table>
                          #;
   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 <<HTML;
             <!DOCTYPE  HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
             <html>
             <head>
                <TITLE>Auswertung Sicherungslogs</TITLE>
                <META NAME="author" CONTENT="Michael Schaarwaechter">
                <META NAME="copyright" CONTENT="Michael Schaarwaechter">
                <META CONTENT="text/html; charset=iso-8859-1" HTTP-EQUIV="Content-Type">
                <style type="text/css"> <!--
                   body {
                         font-family:Helvetica,Arial,sans-serif;
                         font-size:medium;
                         background-color:#FFFFFF;
                        }
                   h1 {
                         font-size:x-large;
                        }
                   h2 {
                         font-size:large;
                        }
                   h3 {  font-size:larger;
                        }
                   th { white-space:nowrap;
                      }
                   .klein {
                         font-size:75%;
                        }
                   .sehrklein {
                         font-size:60%;
                        }
                   .rechts {
                         text-align: right;
                        }
                   .links {
                         text-align: left;
                        }
                   .center {
                         width: 50%; 
                         margin-left: auto; 
                         margin-right: auto;
                        }
                   .nowrap {
                          white-space:nowrap;
                        }
                   .rot {
                         color:red;
                        }
                   .gruen {
                         color:green;
                        }
                   .nix {}
                   .bggelb {
                         background: yellow;
                        }
                   .bggruen {
                         background: #B3E6C2;
                        }
                   .bgrot {
                         background: red;
                        }
                   .bghellblau {
                         background: #ECF2F9;
                        }
                   .servername {
                         background: #ECF2F9;
                         color:green;
                         font-style:italic;
                        }
                   .bgorange {
                         background: #FFE600;
                        }
                   .bggrau {
                         background: #DADADA;
                        }
                   .rahmen { 
                         border-width:1px;
                         border-style:solid;
                         border-color:#6699CC;
                        }
                   .rrahmen {
                         text-align: right;
                         border-width:1px;
                         border-style:solid;
                         border-color:#6699CC;
                         font-size:75%;
                        }
                   .ru {
                         border-bottom-width:1px;
                         border-bottom-style:solid;
                         border-bottom-color:#6699CC;
                         border-right-width:1px;
                         border-right-style:solid;
                         border-right-color:#6699CC;
                         font-size:75%;
                        }
                    .k {
                         font-size:85%;
                        }
                 --> </style>
                  
             </head>
             <body>
<h1>Der Backupserver</h1>
<pre>
Verfuegbarer Plattenplatz auf lxbackup:
HTML
open(PIPE,"df -h|");
while (<PIPE>) {print}
close PIPE;
print <<HTML;
</pre>
<p>
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. 
<pre>
root\@lxbackup> rsync -avz -e "ssh -i /root/.ssh/rsync-key" QUELLE ZIEL
</pre>
In dem folgenden Beispiel soll die index.html auf dem Webserver restauriert werden:
<pre>
root\@lxbackup> rsync -avz -e "ssh -i /root/.ssh/rsync-key" /export/backup/lx1/srv/www/htdocs/index.html lx1:/srv/www/htdocs
</pre>
Achtung: Dieser Befehl &uuml;berschreibt die Datei auf dem Webserver <b>sofort</b>! <br>
Anstelle der Datei kann auch ein Verzeichnis bzw Wildcard (*) angegeben werden.  Bitte sehr genau darauf achten, <br>was wohin</b>
geschrieben wird - ich sags nochmal: Enter nach dem obigen Befehl und er f&auml;ngt sofort an!
</p>
<h1>Ergebnis der Sicherungen</h1>
<p>
Ber&uuml;cksichtigt werden alle Sicherungen, die innerhalb der letzten Woche gelaufen sind.
In der letzten Zeile <span class="bgrot">rot</span> markiert sind Sicherungen mit Abbr&uuml;chen/Problemen - in diesem Fall Log ansehen,
auch wenn eine Null in <span class="bgrot">rot</span> gezeigt wird! Die Zahl z&auml;hlt nur die Fehler, die beim rsync-Lauf
aufgetreten sind, wenn z.B. ein Befehl, der vor dem rsync ausgef&uuml;hrt werden soll, gescheitert ist, startet rsync
aber gar nicht erst.<br>
<span class="bggelb">Gelb</span> markiert sind die jeweils letzten Sicherungen.<br>
<span class="bggelb">Stand: $jetzt</span>
</p>

<table>
<tr><th>&nbsp;</th>
HTML
foreach $dow(@dows) {
   print qq#<th class="servername">$dow</th>#;
}
print qq#</tr>#;


foreach $srv(sort keys %data) {
   print qq#<tr><td class="servername">$srv</td>#;
   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#<td class="rahmen"><span class="klein">#,$data{$srv}{$dow},qq#</span></td>#;
      } else {
         print qq#<td>&nbsp;</td>#;
      }
   }
}
