Forum Programmation.shell Plomberie unixienne

Posté par . Licence CC by-sa
3
27
fév.
2017

Bonjour,

Je cherche à alimenter une base RRD avec la sortie de la commande vmstat (sous Linux). J’ai créé ma base RRD et je peux l’alimenter manuellement, je n’ai pas de problème de ce côté là.

La commande suivante me sort un enregistrement avec lequel je devrais pouvoir alimenter ma base, toutes les secondes. J’utilise le caractère nul comme séparateur, ce n’est probablement pas une nécessité dans mon cas (donnée RRD…) mais j’ai de toute façon le même comportement en utilisant \n

vmstat -n 1 | awk '{ if (NR>3) { printf "%s", strftime("%s"); for (i=1; i<18; i++) { printf ":%i", $i; } ; printf "\000"; fflush(); } }'

Voici ce que sort la commande, en pipant dans cat -v pour qu’on voit le séparateur (^@) :

$ vmstat -n 1 | awk '{ if (NR>3) { printf "%s", strftime("%s"); for (i=1; i<18; i++) { printf ":%i", $i; } ; printf "\000"; fflush(); } }' |cat -v
1488221041:0:0:0:5445776:80776:999008:0:0:0:0:201:210:1:1:98:0:0^@1488221042:0:0:0:5444504:80776:999008:0:0:0:0:2268:4388:3:1:96:1:0^@1488221043:0:0:0:5444504:80776:999008:0:0:0:0:157:156:1:0:99:0:0^@1488221044:0:0:0:5444380:80776:999008:0:0:0:0:223:245:0:1:99:0:0^@1488221045:0:0:0:5444496:80776:999008:0:0:0:0:198:240:1:0:99:0:0^@1488221046:0:0:0:5444504:80780:999008:0:0:0:4:215:225:1:1:98:1:0^@^C

La commande tourne indéfiniment, ici je l’ai arrêté en faisant Ctrl+C

Je veux maintenant mettre à jour ma base RRD. La commande de mise à jour est la suivante (ici je reprends une des mesures de l’exemple plus haut) :

rrdupdate fichier.rrd '1488221041:0:0:0:5445776:80776:999008:0:0:0:0:201:210:1:1:98:0:0'

Je m’oriente donc vers l’utilisation de xargs sur la première commande pour exécuter un rrdupdate (ie: rrdtool update) sur chacune des mesures.

Et c’est là que j’ai un problème, c’est comme si xargs ne voyait rien :

$ vmstat -n 1 | awk '{ if (NR>3) { printf "%s", strftime("%s"); for (i=1; i<18; i++) { printf ":%i", $i; } ; printf "\000"; fflush(); } }' |xargs -0

n’affiche rien. J’ai essayé d’ajouter printf "%s\n" mais c’est pareil…

Pourtant si je prends un exemple plus simple d’utilisation de xargs j’en déduis que ça devrait bien m’afficher les lignes que vmstat me crache :

$ printf "78787\0001421454\00026455\000" |xargs -0 printf "%s\n"
78787
1421454
26455
$ printf "78787\0001421454\00026455\000" |xargs -0
78787 1421454 26455

Je passe vraisemblablement à côté de quelque chose…

Comment vous y prendriez-vous ?

  • # re: Plomberie unixienne

    Posté par . Évalué à 6.

    Bonjour,

    Ajoutez l'option -n 1 à xargs pour que la commande soit invoquée pour chaque paramètre. Sans cela, la commande ne sera pas invoquée avant que le buffer de la ligne de commande de soit rempli (2M chez moi).

  • # Du coup je poste mon bousin

    Posté par . Évalué à 6.

    #!/usr/bin/env bash
    
    PERIOD=1
    RRD_TPL='vmstat_rrd'
    RRD_DB='vmstat.rrd'
    
    test -f "${RRD_DB}" || rrdtool create "${RRD_DB}" --start $(date +%s) -s ${PERIOD} $(tr '\n' ' ' < "${RRD_TPL}")
    
    vmstat -n ${PERIOD} \
      | awk '{ if (NR>3) { printf "%s", strftime("%s"); for (i=1; i<18; i++) { printf ":%i", $i; } print "\000"; fflush(); } }' \
      | xargs -0 -n 1 rrdupdate ${RRD_DB} &

    Le fichier vmstat_rrd contient la définition de la base RRD :

    DS:r:GAUGE:60:0:32768
    DS:b:GAUGE:60:0:32768
    DS:swapd:GAUGE:60:0:1073741824
    DS:free:GAUGE:60:0:1073741824
    DS:buff:GAUGE:60:0:1073741824
    DS:cache:GAUGE:60:0:1073741824
    DS:si:GAUGE:60:0:1073741824
    DS:so:GAUGE:60:0:1073741824
    DS:bi:GAUGE:60:0:1073741824
    DS:bo:GAUGE:60:0:1073741824
    DS:in:GAUGE:60:0:1073741824
    DS:cs:GAUGE:60:0:1073741824
    DS:us:GAUGE:60:0:100
    DS:sy:GAUGE:60:0:100
    DS:id:GAUGE:60:0:100
    DS:wa:GAUGE:60:0:100
    DS:st:GAUGE:60:0:100
    RRA:AVERAGE:0.5:1:60
    RRA:AVERAGE:0.5:1m:60
    RRA:AVERAGE:0.5:1h:24
    RRA:AVERAGE:0.5:24h:7
    RRA:AVERAGE:0.5:7d:520
    

    La base se remplit au fur et à mesure (toute les secondes).

    On peut facilement faire un graphique, défini dans un fichier vmstat_rrdgraph :

    DEF:id=vmstat.rrd:id:AVERAGE
    DEF:us=vmstat.rrd:us:AVERAGE
    DEF:sy=vmstat.rrd:sy:AVERAGE
    DEF:wa=vmstat.rrd:wa:AVERAGE
    DEF:st=vmstat.rrd:st:AVERAGE
    CDEF:usage=100,id,-
    LINE1:usage#0000FF:Total
    LINE2:us#DD0044:User
    LINE3:sy#DD4400:System
    LINE4:wa#00DE40:Wait
    LINE5:st#40DE00:Stolen
    

    Pour grapher la dernière heure :

    $ rrdtool graph vmstat.png -w800 -h600 -t "CPU Usage" --start end-1h --end now $(tr '\n' ' ' < vmstat_rrdgraph)
    

    Exemple

  • # la reponse est dans la question

    Posté par . Évalué à 1.

    La commande tourne indéfiniment, ici je l’ai arrêté en faisant Ctrl+C

    donc la commande qu'on appelera A ne s'arrete jamais sauf en faisant Ctrl+C

    Je m’oriente donc vers l’utilisation de xargs sur la première commande pour exécuter un rrdupdate (ie: rrdtool update) sur chacune des mesures.
    Et c’est là que j’ai un problème, c’est comme si xargs ne voyait rien :

    et la commande A | xarg ne fait rien ?

    peut-etre simplement parce que le buffer avant le pipe n'est pas flushé (flush à la fin ou au ctrl+c)

    • [^] # Re: la reponse est dans la question

      Posté par . Évalué à 2.

      donc la commande qu'on appelera A ne s'arrete jamais sauf en faisant Ctrl+C

      Si tu veux vraiment chipoter on peut aussi l’arrêter avec SIGTERM ou SIGKILL ;)

      peut-etre simplement parce que le buffer avant le pipe n'est pas flushé (flush à la fin ou au ctrl+c)

      Non, c’était bien le fait qu’il manque l’option -n 1 à xargs qui posait problème.

      Pour preuve, je n’avais pas de problème en pipant dans cat au lieu de xargs

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.