Recherche chaine de caractère dans log et lancement action

Bonjour,

certains ont-ils dejà essayé de faire une recherche de chaine de caractère dans un fichier de log et en focntion du resultat, lancer une action.
la recherche doit se faire sur les nouvelles lignes du fichier (depuis le dernier lancement) et doit gerer le fait que le fichier de log repart à 0 (suppression des logs)

Norbert

Salut,

Tu as un exemple de cas d’usage ?
Tu veux obligatoirement faire ça via jeedom ou via linux (avec si besoin d’un renvoi d’état vers jeedom) serait suffisant ?

Plutôt via.jeedom, scénario bloc code PHP si possible

Ca doit être faisable en stockant dans une variable un « témoin » de la dernière lecture du fichier pour savoir où reprendre.
Mais ça dépend aussi de la volumétrie du fichier, si c’est vraiment très lourd, pas sur que ce soir une bonne idée de faire comme ça.

Bref je maintiens ma question initiale, tu as un exemple de cas d’usage ? :wink:

Oui, un message d’erreur dans les logs pour relance du démon

Pourquoi ne pas faire un scénario avec cron qui va juste checker ton daemon et le relancer ?

Bonsoir à tous,

Pour ceux que ca interesse, un petit template de scenario qui permet de faire une recherche dans les fichiers de log Jeedom (ou sur n’importe quel fichier du serveur).

Il doit être lancé régulièrement et ne fait une recherche QUE SUR LES NOUVELLES LIGNES DU FICHIERS par rapport au dernier lancement (idée d’@aurel, la dernière position de lecture est stockée dans une variable)

Il prend en entrée les chemin, nom de fichier et chaine à rechercher et permet d’exécuter n’importe quelle action/notification/commande jeedom en sortie

(Le code PHP a été réalisé en grande partie avec chatGPT)

Voilà, c’est assez basique mais ca me manquait, je partage donc.

Le template (à renommer en supprimant le .txt ) :
recherche log.json.txt (16,4 Ko)

Norbert

4 « J'aime »

Salut @ngrataloup

Très bonne idée → Merci pour le partage :+1:

@+

1 « J'aime »

MERCI beaucoup pour le partage de ce script …

:clap: :clap: :clap:

Je profite du message de pascals qui a refait monté le topic pour fournir le contenu du bloc code corrigé (qui ne fonctionnait pas chez moi) :

// Detection d'une chaine dans un fichier de log
// version bloc code
$version = '26/06/2024 14:00' ;
$scenario->setLog('┌──────────── Logs bloc code - version du '.$version);

// Récupérer les tags Jeedom d'entrée
$tags = $scenario->getTags(); //récupère la liste des tags
$filename = $tags['#fichier#'];
$path = $tags['#chemin#'];
$searchString = $tags['#chaine#'];

function checkNewLines($filename, $path , $searchString, $scenario) {
  
    // Construire le chemin complet du fichier
    $filePath = rtrim($path, '/') . '/' . $filename;
  	
  	$scenario->setLog('File path : '.$filePath);
  
    // Nom de la variable Jeedom pour stocker la dernière position
    $variableName = 'last_position_' . str_replace('/', '_', $filename);
    $scenario->setLog('$variableName : '.$variableName);
    

    // Vérifier l'existence du fichier
    if (!file_exists($filePath)) {
        $scenario->setLog('| Le fichier '.$filePath.' n\'existe pas');
        return -1; // Indiquer que le fichier n'existe pas
    }

    // Récupérer la dernière position de la variable Jeedom
    $lastPosition = $scenario->getData($variableName);
    if ($lastPosition === '' || $lastPosition === null) {
		$lastPosition = 0;
  	}
  	$scenario->setLog('$variableName : '.$lastPosition);
  
    // Ouvrir le fichier pour lecture
    $file = fopen($filePath, 'r');
    if (!$file) {
        $scenario->setLog('| Impossible d\'ouvrir le fichier '.$filePath);
        return -1; // Indiquer que le fichier ne peut pas être ouvert
    }

    // Obtenir la taille actuelle du fichier
    $fileSize = filesize($filePath);

    // Vérifier si la dernière position est supérieure à la taille actuelle du fichier (fichier réinitialisé)
    if ($lastPosition > $fileSize) {
        $lastPosition = 0; // Réinitialiser la dernière position
    }
    $scenario->setLog('| derniere position : '.$lastPosition.', Taille actuelle : '.$fileSize);
    
  // Se déplacer à la dernière position
    fseek($file, $lastPosition);

    // Lire les nouvelles lignes et vérifier la présence de la chaîne de recherche
    $found = false;
    while (($line = fgets($file)) !== false) {
        if (strpos($line, $searchString) !== false) {
            $found = true;
            break;
        }
    }

    // Obtenir la position actuelle
    // $currentPosition = ftell($file);

    // Sauvegarder la position actuelle dans la variable Jeedom
    $scenario->setData($variableName, $fileSize);

    // Fermer le fichier
    fclose($file);

    // Log du résultat
    if ($found) {
        $scenario->setLog('| La chaîne '.$searchString.' a été trouvée dans les nouvelles lignes du fichier '.$filePath);
        return 1; // Chaîne trouvée
    } else {
        $scenario->setLog('| La chaîne '.$searchString.' n\'a pas été trouvée dans les nouvelles lignes du fichier '.$filePath);
        return 0; // Chaîne non trouvée
    }
}

// Appeler la fonction checkNewLines
$result = checkNewLines($filename, $path , $searchString,$scenario);

// Définir un tag Jeedom avec le résultat
$tags = array('result' => $result);
$scenario->setTags($tags);

EDIT : pour les curieux, il s’agissait de la ligne $lastPosition = $scenario->getData($variableName, ‹ 0 ›); qui ne fonctionnait pas. La fonction getData() ne prends pas de deuxième argument (censé celui par défaut), et en plus la fonction plus loin fseek() attends un int, et pas une string.
Le correctif :

    $lastPosition = $scenario->getData($variableName);
    if ($lastPosition === '' || $lastPosition === null) {
		$lastPosition = 0;
  	}
1 « J'aime »