Tuto - vérifier l'externalisation des backups et leur cohérence

Hello,
" Des backups qui backup c’est bien, mais des backups qui se restaure c’est mieux :stuck_out_tongue: "
Je suis très attentif à ceci mais comme je n’ai pas d’autres environnements pour valider une restauration, je duplique les sauvegardes (avec Restic). Gérer par un cron qui envoi un check dans le Plugin de supervision + une alerte visuelle avec une clé blink(1) mk3
A noté que dans votre cas vous risquez d’avoir des faux positifs dans le cas de purge ou de suppression de plug-in ?
it’s my 2 cents

Euh pas tous comprit mdr

Je me posais la question si vous faites un check sur la taille du backup si celui-ci change parce que par exemple vous avez fait du ménage (printemps) dans Jeedom vous serez alerté parce qu’il y aura une différence dans la taille du backup non ?

Oui si je vais modifier le min maxi

Le code génère une alerte seulement si la taille du backup est inférieure ou supérieure à une taille fixée.
Il y a pas de comparaison entre backups.
Et oui, le mieux reste de tester ces backups, mais je ne me vois pas faire un test tous les jours … Donc à défaut, quelques tests et notamment s’assurer que l’externalisation est ok

1 « J'aime »

J’ai modifier le code pour une utilisation avec Discord et il faut rajouter des tags :

// version bloc code
$version = '06/06/2024 19:00';
$scenario->setLog('┌──────────── Logs bloc code - version du ' . $version);

/**
* Class and Function List:
* Function list:
* - csv_to_array()
* Classes list:
*/

function csv_to_array($filename  = '', $delimiter = ',') {
    if (!file_exists($filename) || !is_readable($filename)) return false;

    $header    = array(
        'taille',
        'date',
        'heure',
        'file'
    );
    $data      = array();
    if (($handle    = fopen($filename, 'r')) !== false) {
        while (($row       = fgetcsv($handle, 1000, $delimiter)) !== false) {
            if (!$header) $header    = $row;
            else $data[]           = array_combine($header, $row);
        }
        fclose($handle);
    }
    return $data;
}

// parametres
$tags            = $scenario->getTags(); //récupère la liste des tags
$cmdIdListe      = str_replace('#', '', $tags['#cmdListe#']);
$seuilTailleMax  = $tags['#seuilTailleMax#'];
$seuilTailleMin  = $tags['#seuilTailleMin#'];
$AlerteCentreMsg = $tags['#AlerteCentreMsg#'];
$AlerteNotifJC   = $tags['#AlerteNotifJC#'];
$AlerteNotifDiscord   = $tags['#AlerteNotifDiscord#'];
$colorsDiscord = $tags['#colorsDiscord#'];

$fichierListe    = '/var/www/html/log/cloudsyncpro.#' . $cmdIdListe;

if ($AlerteNotifJC) $cmdNotifJC = cmd::byId(str_replace('#', '', $tags['#cmdNotifJC#']));
if ($AlerteNotifDiscord) $cmdNotifDiscord = cmd::byId(str_replace('#', '', $tags['#cmdNotifDiscord#']));

$scenario->setLog('| Fichier log : ' . $fichierListe);
$scenario->setLog('| Taille min  : ' . $seuilTailleMin . 'Mo');
$scenario->setLog('| Taille max  : ' . $seuilTailleMax . 'Mo');

// mise à jour de la liste
cmd::byId($cmdIdListe)->execCmd();

if (!file_exists($fichierListe) || !is_readable($fichierListe)) {
    $scenario->setLog('| /!\ le fichier ' . $fichierListe . ' n\'existe pas ou n\'est pas lisible');
    if ($AlerteCentreMsg) message::add('Backup', 'Vérification des backups, ERREUR : le fichier ' . $fichierListe . ' n\'existe pas ou n\'est pas lisible');
    if ($AlerteNotifJC) $cmdNotifJC->execCmd($options = array(
        'title'         => 'title=Defaut BACKUP ' . $site,
        'message'       => 'Vérification des backups, ERREUR : le fichier ' . $fichierListe . ' n\'existe pas ou n\'est pas lisible'
    ) , $cache   = 0);
    if ($AlerteNotifDiscord) $cmdNotifDiscord->execCmd($options = array(
        'colors'        => $colorsDiscord,
        'Titre'         => 'Defaut BACKUP ' . $site . ' (Version : ' . $version . ')',
        'description'   => 'Vérification des backups, ERREUR : le fichier ' . $fichierListe . ' n\'existe pas ou n\'est pas lisible'
      
    ) , $cache   = 0);  
}
else {
    // mise à jour de la liste
    cmd::byId($cmdIdListe)->execCmd();

    // Extraction des données du fichier dans un tableau
    $data = csv_to_array($fichierListe, ' ');

    // suppression des lignes vides
    for ($n    = 0;$n < count($data);$n++) {
        if (empty($data[$n][taille])) {
            array_splice($data, $n, 1);
        }
    }

    // recherche des sites de backup concernés
    for ($n = 0;$n < count($data);$n++) {
        $file                 = explode('-', $data[$n][file]);
        $sites[]                      = $file[1];
    }
    $sites                = array_unique($sites);

    foreach ($sites as $site) {
        $nbBackup             = 0;
        $tailleTotale         = 0;
        $tailleMax            = '';
        $tailleMin            = '';
        $backupToday          = 0;
        $tailleFirstBackup	  = 0;
        $tailleLastBackup	  = 0;
        $timestampFirstBackup = '';
        $timestampLastBackup  = '';

        for ($n                    = 0;$n < count($data);$n++) {
            $file    = explode('-', $data[$n][file]);
            if ($site == $file[1]) {
                // $scenario->setLog($site.'  -  '.$file[1]) ;
                $taille  = round($data[$n][taille] / 1024 / 1024);
                $file    = explode('-', $data[$n][file]);
                $jeedom  = $file[1];
                $version = $file[2];

                // $scenario->setLog($jeedom.' version '.$version.' taille '.$taille.'Mo '.date("d/m/y", $date));
                // nb de backup, taille totale et taille des backups
                $nbBackup++;
                $tailleTotale         = $tailleTotale + $taille;
                if ($taille > $tailleMax || empty($tailleMax)) $tailleMax            = $taille;
                if ($taille < $tailleMin || empty($tailleMin)) $tailleMin            = $taille;

                // date des backu^p
                $timestampBackup      = mktime(0, 0, 0, $file[4], $file[5], $file[3]); // timstamp du backup )à 0à:00
                $timestampNow         = mktime(0, 0, 0, date('m') , date('d') , date('Y'));
                if ($timestampBackup == $timestampNow) $backupToday          = 1;
                if ($timestampBackup <= $timestampFirstBackup || empty($timestampFirstBackup)) {
                  $timestampFirstBackup = $timestampBackup;
                  $tailleFirstBackup = $taille ;
                }
                if ($timestampBackup >= $timestampLastBackup || empty($timestampLastBackup)) {
                  $timestampLastBackup  = $timestampBackup;
                  $tailleLastBackup = $taille ;
                }
                  

            }
        }
        $scenario->setLog('| Résumé : ' . $site . ' (Version : ' . $version . ')');
        $scenario->setLog('|     Nb backup presents   : ' . $nbBackup);
        $scenario->setLog('|     1er backup dispo     : ' . date('d/m/Y', $timestampFirstBackup).' ('.$tailleFirstBackup.'Mo)');
        $scenario->setLog('|     dernier backup dispo : ' . date('d/m/Y', $timestampLastBackup).' ('.$tailleLastBackup.'Mo)');
        $scenario->setLog('|     Taille moyenne       : ' . round($tailleTotale / $nbBackup) . 'Mo');

        // gestion des erreurs
        if ($tailleMax >= $seuilTailleMax || $tailleMin <= $seuilTailleMin) {
            $scenario->setLog('| /!\ Pb de taille sur un backup - merci de verifier (taille min : ' . $tailleMin . 'Mb, max :' . $tailleMax . 'Mb)');
            if ($AlerteCentreMsg) message::add('Backup', $site . ' - Pb de taille sur une sauvegarde - merci de verifier (taille min : ' . $tailleMin . 'Mb, max :' . $tailleMax . 'Mb)');
            if ($AlerteNotifJC) $cmdNotifJC->execCmd($options = array(
                'title'         => 'title=Defaut BACKUP ' . $site,
                'message'       => 'Pb de taille sur un backup<br>Taille min : ' . $tailleMin . 'Mb<br>Taille max :' . $tailleMax . 'Mb'
            ) , $cache   = 0);
            if ($AlerteNotifDiscord) $cmdNotifDiscord->execCmd($options = array(
                'colors'        => $colorsDiscord,
                'Titre'         => 'Defaut BACKUP ' . $site . ' (Version : ' . $version . ')',
                'description'   => 'Attention : problème de taille sur un backup' ."\n" .'Taille min : ' . $tailleMin . 'Mb' ."\n" .'Taille max : ' . $tailleMax . 'Mb'
                
            ) , $cache   = 0);
        }
        if ( !$backupToday) {
            $scenario->setLog('| /!\ Pas de backup aujourd\'hui');
            if ($AlerteCentreMsg) message::add('Backup', $site . ' - Pas de backup aujourd\'hui, dernier backup : ' . date('d/m/Y', $timestampLastBackup));
            if ($AlerteNotifJC) $cmdNotifJC->execCmd($options = array(
                'colors'        => $colorsDiscord,
                'Titre'         => 'Defaut BACKUP ' . $site . ' (Version : ' . $version . ')',
                'description'   => 'Pas de backup aujourd\'hui' ."\n" .'Dernier backup : ' . date('d/m/Y', $timestampLastBackup)
              
            ) , $cache   = 0);
            if ($AlerteNotifDiscord) $cmdNotifDiscord->execCmd($options = array(
                'colors'        => $colorsDiscord,
                'Titre'         => 'Defaut BACKUP ' . $site . ' (Version : ' . $version . ')',
                'description'   => 'Pas de backup aujourd\'hui' ."\n" .'Dernier backup : ' . date('d/m/Y', $timestampLastBackup)
              
            ) , $cache   = 0);
        }
    }
}

$scenario->setLog('└───────────────────────────');

Cordialement.

2 « J'aime »

et on peut aussi envoyer un mail en mettant la commande correspondante à la place de celle de JC :wink:

Bravo et merci pour ce partage

1 « J'aime »

Bonjour,

Je pense avoir tout bien fait mais je ne peux pas mettre dans les tag la valeur cmdListe ni cmdNotifJC car ces commandes ne sont pas accessibles dans la liste… alors que tout est ok sur mon jeedom…

Merci

Bonsoir @Emlivyo

Il faut les renseigner à la main. car la modale de choix ne permet de sélectionner que des commandes info.or, ces 2 commandes sont des commandes action.
Le plus simple. tu selectionnes une commande info de l’equipement et manuellement, tu modifies le nom de la commande pour mettre la bonne commande

Norbert

Ok merci mais c’est quoi la « bonne » commande stp?
Car je pensais avoir fait cela justement mais ce n’est pas bon…
Merci

Pour le tag cmsListe, c’est la commande créée dans le point 1.
Pour le tag cmdNotifJC, c’est la commande de notif JC que tu souhaites utiliser.

Norbert

Par exemple tu as ton équipement de sauvegarde

Et ta commande action

Donc ce que tu dois saisir c’est 1 + 2 + 3 sous la forme #[Maison][Google Drive][liste_gdrive]#

Ben justement c’est bien ca que j’ai essayé…

J’ai du faire une erreur, je réessaye ce soir

Merci

bon cela ne veut toujours pas fonctionner malheureusement:

Qui correspond normalement bien à:
image
image

Idem pour l’autre tag avec la commande jeemate…

Et tes logs donnent quoi?

que donne le log cloudsyncpro.#9896 et le log du scenario ?

Bonjour,

Désolé je n’avais pas eu la notif sur mon tel:

0000|2024/07/06 01:00:12 Failed to lsl: directory not found

Merci

Tu vérifies un répertoire qui n’existe pas, vérifies l’écriture de celui ci et attention aux majuscules et autres caractères spéciaux

J’ai rajouté ce code dans mon scenario de backup qui tourne depuis des années et j’avais mis en commentaire la partie backup pour tester le code sans remettre le backup (donc pas de backup depuis 1semaine…)

Je viens de faire 2 scénarios distincts (backup et code) donc je regarderai dans les prochains jours s’il y a toujours des erreurs…

Merci

En fait, j’avais fait une erreur du chemin des sauvegardes donc… il ne trouvait pas…
Maintenant que le chemin est bon, le scénario se lance bien.
A voir dans les prochains jours maintenant que tout est rétabli !

Merci pour votre aide et bon dimanche

2 « J'aime »