Salut,

Je me demande s'il existe une solution, en BASH exclusivement, pour soit monitorer en temps reél un log pour déclencher un script dès que l'expression X arrive soit pour carrément pousser chaque nouvelle ligne de log dans un script.

Pourquoi BASH exclusivement ? Parce que je suis pas assez doué en Python et que mon script qui doit pousser l'info sur IRC est en BASH.

Je pensais bien à un truc du genre cron * * * * * avec grep 'expression' /home/aerya/outils/logs/rclone.log | tail -1mais c'est cracra et pas certain que ça marche non plus.

  • Dryusdan a répondu à ça.
    • Meilleure réponsesélectionnée par Aerya

    Si tu veux du full DIY, tu peux boucler sur la lecture d'un fichier :

    tail -fn 200 /var/log/dmesg | while read line; do 
        if echo $line | grep error > /dev/null 2>&1; then 
            echo "ALERT trop grave sur $line"
        fi
    done

    Qui me donne en resultat :

    ALERT trop grave sur [    8.086611] kernel: floppy: error 10 while reading block 0
    ALERT trop grave sur [    8.199531] kernel: blk_update_request: I/O error, dev fd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
    ALERT trop grave sur [    8.202673] kernel: floppy: error 10 while reading block 0
    ALERT trop grave sur [    8.331456] kernel: blk_update_request: I/O error, dev fd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
    ALERT trop grave sur [    8.335177] kernel: floppy: error 10 while reading block 0

    Je lance un truc basé là-dessus, je verrai dans la soirée ce que ça donne 😉

    Nixstats est une solution de monitoring / supervision (payante, mais honnetement ca vaut le coup) et fonctionne avec un agent écrit en python. Il permet entre autre de remonter tous les logs via syslog, et on peut déclancher des alertes en fonction de regexp dans les logs, c'est une piste 🙂

    Sinon, il y a les classiques, Kibana dans une stack ELK pour remonter les logs et créer de l'alerting dessus.

    Mais faire du live sur un fichier de log avec bash c'est pas tellement fait pour, ça doit exister en Python.

    Ref :

    • Modifié
    • Meilleure réponsesélectionnée par Aerya

    Si tu veux du full DIY, tu peux boucler sur la lecture d'un fichier :

    tail -fn 200 /var/log/dmesg | while read line; do 
        if echo $line | grep error > /dev/null 2>&1; then 
            echo "ALERT trop grave sur $line"
        fi
    done

    Qui me donne en resultat :

    ALERT trop grave sur [    8.086611] kernel: floppy: error 10 while reading block 0
    ALERT trop grave sur [    8.199531] kernel: blk_update_request: I/O error, dev fd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
    ALERT trop grave sur [    8.202673] kernel: floppy: error 10 while reading block 0
    ALERT trop grave sur [    8.331456] kernel: blk_update_request: I/O error, dev fd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
    ALERT trop grave sur [    8.335177] kernel: floppy: error 10 while reading block 0

    @martinbouillaud Effectivement BASH n'est pas fait pour mais je ne souhaite pas utiliser des outils plus lourds (c'est pour checker un log rClone, d'upload sur Google). Je ne vois pas ce que tu as mis après "Ref :" Une vidéo ?

    @xataz Yep merci, c'est ce que j'ai utilisé hier soir guidé par le suggestion de @Dryusdan et ça marche.

    Aerya a renommé le titre en [Solved] Comment monitorer un log en temps réel en BASH ?.

    Bon, je veux aller un peu plus loin mais je me prends le choux pour passer l'echo en variable "$MSG".
    J'ai tenté ces 2 solutions sans succès

    MSG=`tail -F logs.log | while read line; do 
        if echo $line | grep XXX > /dev/null 2>&1; then 
            echo "Coucou $line"
        fi
    done`
    MSG=$(tail -F logs.log | while read line; do 
        if echo $line | grep XXX > /dev/null 2>&1; then 
            echo "Coucou $line"
        fi
    done)

    Pour ce dernier test, ça ne me passe que la 1ère expression de la ligne trouvée

    tail -F logs.log | while read line; do 
        if echo $line | grep XXX > /dev/null 2>&1; then 
            script.sh $line
        fi
    done

      Aerya Pour la variable MSG, ça ne vas pas être possible, car puisque ta commande n'est jamais terminé, il ne peux pas enregistré la variable.

      Pour le 3ème essai, je suppose que dans ton script, tu récupère $1, dans ce cas il faut mettre "$line" entre guillemet.

      Plus c'est simple et logique plus j'ai du mal 😢
      Merci 😉

      hydrog3n a renommé le titre en Comment monitorer un log en temps réel en BASH ?.

      Petit question @xataz pourquoi prendre 200 lignes via le tail ? Les 10 par défaut ne suffisent pas ?

        julienth37 10 lignes sur un log c'est extrêmement petit.
        200 ça fait certes beaucoup mais 10 je te crame ça en moins d'une seconde ^^

        (Bon, et inversement je peux ne pas avoir de log pendant 1 minutes)

          julienth37 la c'était plus pour l'exemple, pour simuler plusieurs hzures/jours de résultat , dans le cas d'une boucle, ne prendre que la dernière serait suffisant, car ça tournera tout le temps

          Dryusdan (si je dit pas d’ânerie) c'est uniquement au lancement de la boucle while que le -n sert, puisque que tail ne quitte pas avec l'option -f (follow), donc je ne vois toujours pas l’intérêt/le pourquoi de prendre spécifiquement un certain nombre de ligne passé en particulier ^^

          J'aurai même tendance à mettre un tail -fn0 pour ne pas risquer de relire des lignes de log précédent déjà prise en compte.
          A l'inverse si on veux rien louper, je ne vois pas d'autre solution que d'avoir une mémoire de l'heure de la dernière ligne de log lue par le script pour reprendre juste après. Ou une solution plus élégante qui implique de passer sur plus qu'un script Bash (typiquement un ETL comme Logstash ou similaire sans allez jusqu'à un empilement complet type ELK).

          Au final je tourne avec ça :

          rclonegrep.sh
          #!/bin/bash
          
          tail -F /home/aerya/outils/logs/rclone.log | while read line; do
              if echo $line | grep Copied > /dev/null 2>&1; then
                  /home/aerya/outils/scripts/rclonetoirc/reportarchivage.sh "$line"
              fi
          done
          Répondre…