lundi 19 décembre 2011

Patch multi packet pour NRPE 2.13

Malgré le faible intérêt de la sortie de nrpe 2.13, je vais tout de même le déployer pour la simple et bonne raison que nous allons bientôt migrer notre infrastructure nagios de Solaris à Linux. C'est donc dans ce cadre que j'ai voulu changer de version et surtout réappliquer le patch que j'utilise depuis pas mal de temps permettant de gérer des sorties longues.

Problème, le patch de tonvoon (dont je parle ici) n'est plus utilisable en l'état. Comme de toute façon le code source a très peu été retouché (juste l'ajout d'une fonction dans le démon nrpe), nous allons voir comment faire pour récupérer ce patch et forcer son application.

Tout d'abord, il nous faut récupérer une copie de notre patch sur notre machine :

wget https://dev.icinga.org/attachments/download/113/nrpe_multiline.patch

Passons maintenant à la transformation de notre patch au format Windows (eurk !) :

unix2dos ./nrpe_multiline.patch

Il ne nous reste plus qu'à passer le patch en indiquant la ligne de commande patch --binary -l -p1. Si tout se passe bien, la sortie devrait ressembler à ce qui suit :

nous@roulette:~/nagios/nrpe-2.13$ patch --binary -l -p1 < ../nrpe_multiline.patc
h 
patching file include/common.h
patching file src/check_nrpe.c
patching file src/nrpe.c
Hunk #1 succeeded at 972 (offset -57 lines).
Hunk #2 succeeded at 1190 (offset -57 lines).
Hunk #3 succeeded at 1206 (offset -57 lines).
Hunk #4 succeeded at 1235 (offset -57 lines).

Lançons maintenant la configuration et la compilation. Tout devrait bien se passer.

Nous allons maintenant nous assurer qu'il n'y a pas eu de régression. Tout d'abord créons un fichier nrpe.cfg avec le contenu suivant :

log_facility=daemon
pid_file=./nrpe.pid
server_port=5666
server_address=127.0.0.1
nrpe_user=nagios
nrpe_group=nagios
allowed_hosts=127.0.0.1
dont_blame_nrpe=0
debug=0
command_timeout=60
connection_timeout=300

command[short_output]=echo coucou
command[long_output]=/bin/cat /etc/wgetrc

La première commande affiche un simple coucou et la seconde affiche le contenu du fichier /etc/wgetrc.

Mais trêve de bavardage et lançons séance tenante notre démon :

nous@roulette:~/nagios/nrpe-2.13$ ./src/nrpe -c ./nrpe.cfg -d
nous@roulette:~/nagios/nrpe-2.13$ ps -ef | grep nrpe
nous      9374     1  0 17:04 ?        00:00:00 ./src/nrpe -c ./nrpe.cfg -d
nous      9376  5769  0 17:04 pts/0    00:00:00 grep --color=auto nrpe

Tout semble parfait. Lançons un test de notre première commande :

./src/check_nrpe -H localhost -c short_output
coucou

Ça semble plutôt pas mal. Regardons maintenant la taille de la sortie de notre commande longue et comparons cela au fichier d'origine :

nous@roulette:~/nagios/nrpe-2.13$ ./src/check_nrpe -H localhost -c long_output | wc
    126     797    4496
nous@roulette:~/nagios/nrpe-2.13$ wc /etc/wgetrc
 126  797 4496 /etc/wgetrc

C'est parfait ! Notre NRPE en version 2.13 avec patch sortie longue est prêt à fonctionner !

samedi 26 novembre 2011

Sortie de NRPE 2.13

Il y'a peu de temps, la version 2.13 de NRPE est sortie. Autant dire que je suis assez déçu sur le contenu de cette nouvelle version puisque nous n'avons qu'un seul changement pour définir qui a le droit de se connecter sur l'agent NRPE dans le fichier nrpe.cfg (ainsi que la compilation sous Solaris 10). En gros, auparavant, vous étiez obliger de donner explicitement l'IP de votre serveur nagios pour pouvoir vous connecter. Dorénavant, vous pouvez préciser un réseau avec un masque. Ci-dessous un exemple de fichier nrpe.cfg faisant appel à ce mécanisme :
log_facility=daemon
pid_file=/var/run/nagios/nrpe.pid
server_port=6666
nrpe_user=nagios
nrpe_group=nagios
# allowed_hosts=127.0.0.1
allowed_hosts=192.168.0.0/24

dont_blame_nrpe=0
debug=0
command_timeout=60
connection_timeout=300
command[check_users]=/usr/lib/nagios/plugins/check_users -w 5 -c 10
command[check_load]=/usr/lib/nagios/plugins/check_load -w 15,10,5 -c 30,25,20
command[check_hda1]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /dev/hda1
command[check_zombie_procs]=/usr/lib/nagios/plugins/check_procs -w 5 -c 10 -s Z
command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 150 -c 200 
NB: ce démon tourne sur le port 6666 pour des besoins de test. La commande check_nrpe ci-dessous utilisera l'option -p 6666 pour pouvoir s'y connecter.
On va essayer de se connecter sur notre agent NRPE. Ci-dessous l'adresse de mon poste :
drayan@robert:~/dev/nrpe-2.13$ ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 1c:6f:65:21:7b:c0  
          inet adr:192.168.0.17  Bcast:192.168.0.255  Masque:255.255.255.0
[...]
Lançons un test en tant que localhost (qui devrait nous jeter du fait qu'on se présente avec l'adresse IP 127.0.0.1) :
drayan@robert:~/dev/nrpe-2.13$ ./src/check_nrpe -H localhost -c check_load -p 6666
CHECK_NRPE: Error - Could not complete SSL handshake.
Parfait ! Lançons maintenant la même chose en utilisant notre adresse IP :
drayan@robert:~/dev/nrpe-2.13$ ./src/check_nrpe -H 192.168.0.17 -c check_load -p 6666
OK - Charge moyenne: 0.03, 0.06, 0.09|load1=0.030;15.000;30.000;0; load5=0.060;10.000;25.000;0; load15=0.090;5.000;20.000;0;
Voilà, c'est tout ... Je suis notamment assez déçu que le patch pour gérer les sorties longues (dont j'avais parlé ici il y'a quelque temps) ne fasse pas partie de cette release.

Compilation de NRPE 2.13 sous Ubuntu 11.10


Si comme moi vous voulez compiler votre démon NRPE 2.13 sous Ubuntu oneiric, vous avez dû tomber sur un bien beau message d'erreur :

drayan@robert:~/dev/nrpe-2.12$ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
[...]
checking for type of socket size... size_t
checking for SSL headers... SSL headers found in /usr
checking for SSL libraries... configure: error: Cannot find ssl libraries
drayan@robert:~/dev/nrpe-2.12$

Autant dire qu'avec ça, je suis bien avancé. Après quelque recherche, je tombe sur un bug référencé sur launchpad : https://launchpad.net/ubuntu/oneiric/+source/nagios-nrpe/2.12-4ubuntu3.

Dans le bug, le mainteneur du paquet nous fait part d'un laconique message invitant à rajouter l'option --with-ssl-lib=<multiarch dir>. N'ayant pas trop d'idée de ce que ça pouvait bien vouloir dire, j'ai donc tâtonné avant de tomber sur un configure qui passait. Dans l'espoir de faire gagner du temps à d'autre, je vous fais donc part de cette merveilleuse option (dans le cas d'une machine avec un kernel x86_64) :
drayan@robert:~/dev/nrpe-2.13$ ./configure --with-ssl-lib=/usr/lib/x86_64-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
[...]
checking for SSL headers... SSL headers found in /usr
checking for SSL libraries... SSL libraries found in /usr/lib/x86_64-linux-gnu

*** Generating DH Parameters for SSL/TLS ***
Generating DH parameters, 512 bit long safe prime, generator 2
This is going to take a long time
.+......................[...].....++*++*++*++*++*++*
checking for Kerberos include files... could not find include files
checking for perl... /usr/bin/perl
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating subst
config.status: creating include/config.h


*** Configuration summary for nrpe 2.13 11-11-2011 ***:

 General Options:
 -------------------------
 NRPE port:    5666
 NRPE user:    nagios
 NRPE group:   nagios
 Nagios user:  nagios
 Nagios group: nagios


Review the options above for accuracy.  If they look okay,
type 'make all' to compile the NRPE daemon and client.
Bref, maintenant, je vais pouvoir me battre avec le patch long output pour NRPE.

mercredi 9 novembre 2011

Optimisation de PNP4Nagios avec RRDcached

Suite à l'article sur l'utilisation du démon NPCD, j'ai voulu voir quel pourrait être l'impact de la mise en place du démon RRDCached sur le fonctionnement de PNP4Nagios. Pour se faire, il faut bien comprendre à quoi sert ce fameux démon.

Pour cela, il faut revenir sur le fonctionnement de PNP4Nagios à savoir de prendre un grand nombre de métrique et d'alimenter au fur et à mesure un grand nombre de petit fichier : les fichiers RRD. Au delà d'un certain nombre de service, nous pouvons nous retrouver avec une machine qui fait énormément d'IO et qui du coup n'a plus le temps de mettre à jour certaines métriques (mécanisme de timeout de PNP4Nagios). Nous voyons donc qu'au delà un certain seuil, PNP4Nagios peut retomber sur tous les travers classiques des infrastructures de surveillance : consommer de la puissance CPU et être lent (qui a soufflé le nom de NDO utils ?). Le démon RRDCached prend ici tout son sens. En effet, ce dernier va buffuriser les mises à jours RRD au lieu de les faire unitairement réduisant grandement les IO sur notre serveur nagios.

Pour mieux comprendre, prenons le cas d'un serveur nagios remontant en moyenne 10 métriques par services. Si vous êtes comme moi et que vous avez explosé vos fichiers RRD en n fichiers pour chaque services, vous aurez un fichier par métrique. Si nous scruptons toutes les 5 minutes nos différents services (toujours en moyenne), nous nous retrouvons à mettre à jour 10 fichiers pour chaque test de service nagios. Si on reporte ce chiffre sur 1 heure, nous aurons donc environ 120 écritures sur une heure. Si vous multipliez tout ceci par le nombre de service présent sur vos machines (on va dire 5000), vous vous retrouvez à faire environ 600000 écritures par heure. Si vous ajoutez à cela que votre serveur faire appel à des métriques qui sont plus régulière (toutes les 2 minutes voir toute les minutes), vous pouvez commencer à avoir des problèmes.

RRDCached, en s'intercallant entre les outils RRD et les écritures sur le disque, va regrouper ces dernières et ainsi mieux exploiter les capacités de la machine. Imaginons que ce dernier procéde à une buffurisation des écritures sur 1/2 heure, vous diviserez par 6 vos IOs pour des services scruptant toutes les 5 minutes. Ce chiffre pouvant monter à 30 pour des services remontant des métriques toutes les minutes.

Voyons maintenant comment mettre en oeuvre ce démon.

NB : Par la suite, il est évident que je considérerai que PNP4Nagios sera configuré en mode NPCD (cf mon article sur la configuration de PNP4Nagios en mode NPCD) et surtout qu'il utilisera le module RRDs de perl pour faire ses mise à jour (cf mon article sur le sujet).

Installons tout d'abord notre démon rrdcached (sous Debian ou ubuntu) :
sudo apt-get install rrdcached
Et regardons si ce dernier est bien lancé :
$ /etc/init.d/rrdcached status
rrdcached (1262) is running.
$ ps -fp 1262
UID        PID  PPID  C STIME TTY          TIME CMD
root      1262     1  0 18:46 ?        00:00:00 /usr/bin/rrdcached -l unix:/var/run/rrdcached.sock -j /var/lib/rrdcached/journal
Tout semble aller pour le mieux. Nous allons maintenant configurer le script process_perfdata.pl afin qu'il passe par ce démon pour la mise à jour des fichiers RRD. Pour se faire, nous allons modifier le fichier process_perfdata.cfg et notamment la ligne suivante :
RRD_DAEMON_OPTS = unix:/var/run/rrdcached.sock
Attendons un petit peu et allons consulter l'interface de PNP4Nagios. Cette dernière ne devrait plus nous remonter de statistique sur notre moteur PNP4Nagios. Ce comportement est tout à fait normal étant donné que l'interface PHP de PNP4Nagios n'a aucune connaissance de ce nouveau démon. Ce dernier continue donc de s'appuyer sur les fichiers RRD présent alors que ces derniers ne sont plus mis à jour en temps réel.

Modifions maintenant la configuration de PNP4Nagios (fichier config_local.php qu'il faudra créer s'il n'existe pas) afin de lui préciser le pipe nommé de notre démon de cache :

$conf['RRD_DAEMON_OPTS'] = 'unix:/var/run/rrdcached.sock';
Dorénavant, le graphique se met bien à jour en temps réel. En effet, en précisant au binaire RRDTool que nous avons un démon de cache, ce dernier va simplement dire au démon de vider ses buffers sur les fichiers RRDs que nous sommes en train de consulter afin qu'il nous fasse profiter des dernières valeurs que ce dernier avait emmagasiné.

Vous pourriez vous dire que le fait de vider le cache de notre démon avant de pouvoir consulter nos graphiques est une perte de temps. Effectivement, ce comportement sera peu avantageux pour les fichiers RRDs que nous voudrons consulter. En revanche, il sera avantageux pour les milliers d'autres qui pourront continuer à être buffurisé.

ATTENTION !!! Dorénavant, votre démon RRDcached est un élément vitale de votre infrastructure. Je vous recommande chaudement de le surveiller avec votre moteur nagios sous peine de ne plus avoir de mise à jour si ce dernier devait tomber.

Vous allez me dire que tout ça c'est très bien mais vous voudriez savoir si le jeu en vaut la chandelle. Comme généralement les graphiques parlent plus que les chiffres, voici les résultats des temps de réponse moyen de PNP4Nagios suite à la mise en place de ce merveilleux plugin (ici sur 1 mois) :


Comme vous pouvez le constater, du jour où le démon a été mis en place, j'ai vu une grosse diminution de l'effet yoyo et surtout une baisse assez importante du temps moyen pour les mise à jour de PNP4Nagios (passage de 9 secondes avec pointe à 70 secondes à une moyenne sans pique autour de 5 secondes). Autant vous dire que tout ceci est une très bonne nouvelle et que je vais pouvoir continuer mon travail de big brother !

mardi 20 septembre 2011

Template wlsagent pour PNP4Nagios

Il y a de ça peu de temps, j'ai présenté l'utilisation de wlsagent pour le suivi sous nagios d'instance WebLogic. J'avais également donné quelques exemples de graphique sous PNP4Nagios mais sans donner le template de présentation :



Le template est maintenant disponible à l'adresse suivante : http://docs.pnp4nagios.org/templates/check_wlsagent

Il faut copier-coller ce fichier dans le répertoire template de PNP4Nagios (en principe, quelque chose comme /usr/local/pnp4nagios/share/templates/) et se débrouiller pour que PNP4Nagios arrive à faire le lien entre le plugin de lancement et le template.

Personnellement, comme j'appelle tout au travers de NRPE, j'ai simplement créé un doublon de la commande check_nrpe en l'appelant check_wlsagent :
# 'check_wlsagent' command definition
define command{
  command_name check_wlsagent
  command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$
}
J'appelle ensuite mes surveillances à l'aide de commande de ce genre :
# Application WebLogic à surveiller
define service{
  use generic-service
  host_name remotehost
  service_description Application hyperimportante
check_command check_wlsagent!check_application_hyperimportante
}

mardi 13 septembre 2011

Optimisation du couple nagios/PNP4Nagios

Description de l'installation

J'utilise depuis maintenant plusieurs années un moteur nagios sur notre infra pour avoir un suivi de ce qu'il se passe sur nos serveurs.

Au début, nous avions axé notre déploiement sur la partie serveur d'application Java (à base de WebLogic). Nous avons très rapidement activé l'utilisation du moteur de base de données ndo2db. Par la suite nous avons intégré environ 60 serveurs sous cette surveillance pour un total d'environ 600 services. Les choses sont restés en l'état en raison de la machine que nous utilisions qui était particulièrement lente et pauvre en IO disque (pour les plus curieux, il s'agissait d'un Sunfire V210 avec un bi-processeur Ultrasparc III@1Ghz et 2 Go de mémoire).

Il y'a de ça un an et demi, nous avons échangé notre vieille machine poussive contre une machine Solaris flambant neuve (à base de M5000). De là, j'ai profité pour changer nos outils d'autant que je n'étais pas particulièrement content de ndo2db. C'est à cette occasion que j'ai mis en place la toute dernière version de PNP4Nagios en version 0.6 (que j'avais testé en version béta quelques temps auparavant).

De là, j'ai découvert le super système de template de PNP4nagios (cf cet article) et j'ai commencé à mettre ça en oeuvre sur tous nos éléments vitaux d'infrastructure (apache, oracle, MySQL etc.).

Le mode synchrone de PNP4Nagios étant particulièrement lent, j'ai très vite déployé PNP4Nagios en mode bulk lancé par nagios. Mais, le succès aidant, je suis rapidement passé de 60 à 100 machines puis 200. Comme un SI ne diminue jamais, dernièrement nous sommes arrivé à environ 300 machines pour environ 3000 services. Loin d'être énorme (en tunant la configuration de nagios, on parle de configuration montant à 30000 services et plus), les performances du moteur nagios avaient tout de même tendance à se dégrader comme on peut le voir sur le graphique ci-dessous des temps de latence maximum :


On voit ici des temps de latence maximum qui monté à plus de 60 secondes. Même si c'est loin d'être complètement bloquant, ça indique une réactivité beaucoup moins bonne qu'au début du fonctionnement de la plateforme.

C'est donc à ce moment là que j'ai commencé à regarder les optimisations qu'il était possible de faire et notamment l'utilisation de NPCD. J'ai également mis en place le démon de cache RRD. Pour ce dernier j'essaierai d'en parler dans un autre article.

Mise en place de NPCD

La mise en place de NPCD se fait en deux temps : mise en place du démon puis modification de la commande d'insertion des données de performance dans PNP4Nagios. Ci-dessous un schéma extrait du site de PNP4Nagios expliquant le fonctionnement du démon NPCD :

Pour le lancement du démon NPCD, rien d'extraordinaire, il suffit simplement de lancer la commande suivante :
/usr/local/pnp4nagios/bin/npcd
On peut ensuite vérifier sa présence sur le serveur :
ps -ef | grep npcd
Le démon se lance en s'appuyant sur le fichier /usr/local/pnp4nagios/etc/npcd.cfg. Ce dernier va contenir toutes les informations sur le comportement que devra adopter le démon. Vous pouvez notamment tuner les éléments suivants :
  • Le temps de pause entre deux checks dans le répertoire de spool ;
  • Le nombre max de process perfdata à lancer en parallèle ;
  • La verbosité de la log.
Une fois NPCD, nous allons maintenant pouvoir basculer l'insertion des données en utilisant un répertoire de spool. Pour se faire, nous allons changer les commandes process-service-perfdata-file et process-host-perfdata-file (en principe dans le fichier /usr/local/etc/nagios/template/commands.cfg). Ces dernières ressemblaient aux lignes suivantes :
define command {
       command_name    process-service-perfdata-file
       command_line    /usr/local/pnp4nagios/libexec/process_perfdata.pl --bulk=/usr/local/pnp4nagios/var/service-perfdata
}

define command {
       command_name    process-host-perfdata-file
       command_line    /usr/local/pnp4nagios/libexec/process_perfdata.pl --bulk=/usr/local/pnp4nagios/var/host-perfdata
}
Nous les avons remplacé par les lignes suivantes :
define command {
       command_name    process-service-perfdata-file
       command_line    /bin/mv /usr/local/pnp4nagios/var/service-perfdata /usr/local/pnp4nagios/var/spool/service-perfdata.$TIMET$
}

define command {
       command_name    process-host-perfdata-file
       command_line    /bin/mv /usr/local/pnp4nagios/var/host-perfdata /usr/local/pnp4nagios/var/spool/host-perfdata.$TIMET$
}
Il s'agit simplement de substituer l'appel direct à la commande process_perfdata.pl de PNP4Nagios par un déplacement de fichier dans un répertoire. Pas grand chose me direz-vous mais nous allons vite voir que ce petit changement aura des conséquences très intéressante au niveau de nagios.

Résultat de l'optimisation

Et il se trouve que cette modification a eu un énorme impact sur les performances. Pour preuve un état du temps de latence moyen maximum :

On peut voir que nous avons gagné en stabilité au niveau des temps de réponse max et surtout que ces derniers restent largement en dessous les 5 secondes (sauf exceptionnellement mais rien à voir avec le comportement précédent).

dimanche 11 septembre 2011

Création d'un timelapse

Depuis tout petit, j'ai toujours été intéressé par les étoiles et notamment les superbes images nous faisant découvrir les galaxies, les étoiles mortes, les nébuleuses etc. Paradoxalement, je ne m'étais jamais trop posé la question de faire ces observations par moi même puisque bien d'autre avant moi l'avait fait et - de mon point de vue - l'avait très bien fait.

Mais voilà, par un bel été il y a quelques années, ma mère m'a fait découvrir les anneaux de Saturne directement à l'aide de son petit télescope. C'est à ce moment que j'ai réalisé qu'il serait intéressant de contempler par moi même certain phénomène. Pour toute ces raisons (et pour d'autre comme par exemple la naissance de mon petit dernier), je me suis intéressé dans l'achat d'un appareil photo réflex et les techniques de photographie de type timelapse.

Ah, j'oubliais de vous préciser un truc : je n'utilise que des logiciels libre et ma machine principale héberge un Linux depuis des années. Pour ces raisons, j'essaye de faire partager ma petite expérience sur le sujet avec d'autre. Par la suite, nous utiliserons les logiciels suivant :
  • gphoto : il nous aidera à faire nos prises de vue à espace régulier. Je recommande néanmoins l'utilisation d'un intervalomètre pour éviter de se traîner un portable pendant une séance de photo ;
  • convert : outil de convertion d'image en ligne de commande ;
  • mencoder : outil de création de fichier vidéo.

Prendre des photos à intervalle régulier

Première chose, il faut utiliser un trépied afin que le cadre de vos photos reste identique de bout en bout. Il faut également désactiver l'autofocus de l'appareil ainsi que le stabilisateur d'image si vous en avez un. Fixer maintenant un élément qui vous intéresse et commencez à prendre vos photos à intervalle régulier. Pour se faire vous pouvez soit passer par un intervalomètre soit par le logiciel gphoto. En effet, ce dernier vous permet de prendre des photos directement à l'aide d'un ordinateur. Ci-dessous un exemple de ligne de commande :
gphoto2  --auto-detect --capture-image-and-download -I 1
Ci-dessous une petite explication des options présentes :
  • L'option --auto-detect à pour rôle d'inviter gphoto à utiliser le premier appareil détecté ;
  • L'option --capture-image-and-download invite gphoto à prendre une photo et à la télécharger automatiquement sur le PC ;
  • Enfin, l'option -I 1 indique le temps de pause entre chaque photo.
A la fin de votre séance de photo, vous devriez obtenir quelques centaines d'image que nous allons mettre maintenant bout à bout dans une vidéo.

Création de la vidéo

Nous allons procéder en deux étapes :
  • Retailler les photos ;
  • Assembler les photos dans une vidéo.
Pour la première étape nous allons utiliser l'outil convert de imagemagick. Nous allons également utiliser un petit bout de shell pour lancer cette convertion en boucle :
yannig@portable:~/Images/2011-09/timelapse/resize$ for i in ../*.JPG
do
  echo $i
  convert -resize 1440 $i $(basename $i)
done
L'option -resize 1440 indique à l'outil convert la taille désiré pour le fichier de résultat. Par défaut, la retaille se fait en préservant l'aspect de la photo.

NB : Pour éviter de tout mélanger, j'ai mis le résultat de la conversion dans un sous-répertoire resize.

Passons maintenant à la création de la vidéo à l'aide de mencoder (à lancer dans le répertoire contenant les fichiers retaillés) :
mencoder "mf://*.JPG" -mf fps=15:type=jpg -ovc x264 -x264encopts bitrate=3000 -o video-resultat.flv
Encore une fois, étudions ensemble les options de mencoder :
  • "mf://*.JPG" : donne le patron des fichiers à prendre en compte pour créer la vidéo ;
  • -mf fps=15:type=jpg : donne des informations sur la cadence désirée pour la vidéo ;
  • ovc x264 -x264encopts bitrate=3000 : information sur les paramètres d'encodage de la vidéo ;
  • -o video-resultat.flv : explicite le nom du fichier résultat.

Vidéo de résultat

Ci-dessous un petit exemple de ce que peu donner une vidéo réalisé avec ces outils :



Pour informations, cette vidéo à été réalisé avec 382 photos. Ces dernières ont été assemblées à une cadence de 25 images par secondes. Chaque image a été prise en mode automatique sur un Canon EOS 550D avec un intervalle de 10 secondes entre chaque prise de vue.

En espérant que tout ceci vous inspire !

mercredi 7 septembre 2011

Mise en place de wlsagent

J'ai déjà parlé sur ce blog d'intégrer une surveillance des indicateurs interne de WebLogic sous nagios. Nous allons voir ensemble un nouvel exemple de plugin particulièrement intéressant que j'ai eu l'occasion de déployer : wlsagent.

Installation de l'agent wlsagent

Il nous tout d'abord récupérer une version récente de notre plugin :
yannig@portable:~/wlsagent$ svn checkout http://wlsagent.googlecode.com/svn/trunk/src src
Procédons maintenant à la récupération des librairies nécessaires au fonctionnement de wlsagent :

  • jetty-continuation-7.3.1.v20110307.jar
  • jetty-http-7.3.1.v20110307.jar
  • jetty-io-7.3.1.v20110307.jar
  • jetty-security-7.3.1.v20110307.jar
  • jetty-server-7.3.1.v20110307.jar
  • jetty-servlet-7.3.1.v20110307.jar
  • jetty-util-7.3.1.v20110307.jar
  • servlet-api-2.5.jar
  • wlclient.jar
  • wljmxclient.jar

Tous les jars de type jetty et servlet-api font partie du package jetty que vous pouvez récupérer à l'addresse suivante : http://www.eclipse.org/jetty/downloads.php

Déposons maintenant ces fichiers dans le répertoire lib, à la même hauteur que le répertoire src des fichiers sources de wlsagent. Concernant les fichiers wlclient.jar et wljmxclient.jar, vous les trouverez dans les binaires de WebLogic.

Récupérons ensuite le fichier de build ant suivant :


 name="wlsagent" basedir="." default="build">

     name="src.dir"     value="src"/>
     name="build.dir"   value="build"/>
     name="classes.dir" value="${build.dir}/classes"/>
     name="jar.dir"     value="${build.dir}/jar"/>
     name="lib.dir"     value="lib"/>
     name="main-class"  value="net.wait4it.wlsagent.WlsAgent"/>

     id="classpath">
         dir="${lib.dir}" includes="**/*.jar"/>
    

     name="clean">
         dir="${build.dir}"/>
    

     name="compile">
         dir="${classes.dir}"/>
         srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" includeantruntime="true"/>
    

     name="jar" depends="compile">
         dir="${jar.dir}"/>
         destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
            
                 name="Main-Class" value="${main-class}"/>
            
        
    

     name="build" depends="clean,jar"/>

Lançons ensuite le build avec ant, vous devriez obtenir le fichier wlsagent.jar dans le répertoire build/jar.

Passons maintenant à la création du fichier de démarrage de wlsagent :

#!/bin/bash
JAVA_HOME="/usr/lib/jvm/java-6-openjdk"
CURRENT_PATH=$(dirname $0)
LIB_PATH=${CURRENT_PATH}/lib
CLASSPATH=${CURRENT_PATH}/wlsagent.jar

for jar in $(find ${LIB_PATH} -name '*.jar'); do
  CLASSPATH=${CLASSPATH}:${jar};
done

start()
{
  ${JAVA_HOME}/bin/java -Xmx32m -cp ${CLASSPATH} net.wait4it.wlsagent.WlsAgent "9090" > $CURRENT_PATH/wlsagent.log 2>&1 &  echo $! > $CURRENT_PATH/wlsagent.pid
}

stop()
{
  kill $(< $CURRENT_PATH/wlsagent.pid)
}

case $1 in
  stop) stop ;;
  start) start ;;
  restart) stop ; sleep 1 ; start ;;
  status) ps -fp $(< $CURRENT_PATH/wlsagent.pid) ;;
  *) echo "Expected : start/stop/restart/status" ;;
esac
Il ne nous reste plus qu'à lancer le tout et de vérifier le bon démarrage de l'agent :
yannig@portable:~/wlsagent$ ./wlsagent.sh start
yannig@portable-ots:~/wlsagent$ ps -ef | grep wlsagent | grep -v grep
yannig    3922     1  0 10:45 pts/2    00:00:04 /usr/lib/jvm/java-6-openjdk/bin/java -Xmx32m -cp ./wlsagent.jar:.[...]servlet-api-2.5.jar net.wait4it.wlsagent.WlsAgent 9090
Un coup d'oeil dans la log pour vérifier le bon démarrage de l'agent :
yannig@portable:~/wlsagent$ more wlsagent.log 
2011-09-03 10:45:49.961:INFO::jetty-7.3.1.v20110307
2011-09-03 10:45:50.069:INFO::started o.e.j.s.ServletContextHandler{/wlsagent,null}
2011-09-03 10:45:50.222:INFO::Started SelectChannelConnector@0.0.0.0:9090
Tout est prêt ! Nous allons maintenant pouvoir lancer nos tests de communication.

Utilisation du plugin wlsagent

Avant toute chose il faut créer un utilisateur nagios faisant parti du groupe Monitors dans le domaine WebLogic.

On lance ensuite une requête sur l'agent à l'aide d'un wget :
wget -q -O - "http://localhost:9090/wlsagent/WlsAgent?hostname=$(hostname)&port=7028&username=nagios&password=xxx&jvm=UsedMemory;80;90"
0|AdminServer: status OK|HeapSize=370M;;;0;910 UsedMemory=210M;;;0;910

Ici, pas de problème la communication se passe bien. Il suffit ensuite d'intégrer cette surveillance dans nagios pour obtenir une collecte. Pour se faire, vous pouvez récupérer un script d'invocation à l'emplacement suivant : http://code.google.com/p/wlsagent/wiki/Invocation 

Il vous faudra également un outil de collecte des données de performance comme PNP4Nagios. Ci-dessous un exemple de résultat d'intégration à la suite de 2 semaines de collecte :


Pour info, il est possible de remonter les éléments suivants :
  • Threads sur la JVM ;
  • Nombre de transactions en cours sur la JVM ;
  • Nombre de requête / seconde (throughput) ;
  • État des connexion JDBC ;
  • Nombre de session utilisateur ;
  • Et enfin, l'utilisation des queues JMS.
Activité datasource de l'application
Pour gérer ces surveillances, il est nécessaire de rajouter des options pour préciser les éléments à surveiller dans nagios. Pour plus de détail, se reporter à la page suivante : http://code.google.com/p/wlsagent/

lundi 11 avril 2011

mod_proxy_http Apache et console de gestion du load-balancer

J'ai eu à faire une petite étude entre deux type de load-balancing HTTP sur des serveurs d'application WebLogic et c'est à cette occasion que j'ai découvert une perle : la console apache de load-balancing.

Je vous propose de voir ensemble comment l'activer et ce qu'elle vous apporte.

Par la suite je travaillerai avec une RedHat Enterprise 5.3 mais le principe reste le même pour n'importe quelle distribution.

Activation du module mod_proxy_http


Premier point, il vous faut installer une version récente de apache 2.2 et vérifier que la conf de ce dernier fait bien référence au module mod_proxy_http :

[root@myserver conf]# pwd
/etc/httpd/conf
[root@myserver conf]# grep mod_proxy_http.so httpd.conf
LoadModule proxy_http_module modules/mod_proxy_http.so

Un petit coup de apachectl configtest nous assurera que nous n'avons rien oublié.

Création d'une boucle de charge


Placez-vous ensuite dans le répertoire conf de votre serveur apache et créez-y un nouveau fichier de configuration contenant les lignes suivantes (à adapter suivant vos besoins) :

<Proxy balancer://lb-http>
  BalancerMember http://127.0.0.1:7002
  BalancerMember http://127.0.0.1:7004
</Proxy>

ProxyPass        /sample/ balancer://lb-http/sample/
ProxyPassReverse /sample/ balancer://lb-http/sample/

Ici, les URLs sous le contexte /sample/ seront envoyées systématiquement vers nos deux serveurs d'applications Java hébergeant l'application sample.war.

Un arrêt/relance à l'aide de la commande apachectl restart et voici notre configuration pris en compte.

Activation de la console du load-balancer


Activons maintenant la console du load-balancer en ajoutant les lignes suivantes :

<Location /balancer-manager>
  SetHandler balancer-manager
  Order Deny,Allow
  # Deny from all    <- Decommenter ici pour bloquer les accès
  Allow from all #   <- lister les IPs autorisées en les séparant par des virgules
</Location>

Un arrêt/relance sera bien sûr nécessaire pour en profiter.

Utilisation de la console du load-balancer


Il suffit maintenant de rentrer l'URL de notre serveur apache suivi de /balancer-manager pour obtenir l'écran suivant :


De là, vous pourrez désactiver ou réactiver une instance en cliquant sur l'instance à modifier. L'écran en question est le suivant :


Il vous permettra également de modifier certains paramètres de poids sur vos serveurs HTTP/Java.

Pour finir ...


Le gros avantage de ce mécanisme est que vous pourrez ainsi désactiver une instance à la demande et pouvoir ainsi procéder à une maintenance, une mise à jour etc. en limitant au maximum les perturbations.

Pour les plus curieux, je n'ai pas d'autres conseils que d'aller consulter la documentation apache de ce module disponible à l'adresse suivante : http://httpd.apache.org/docs/current/mod/mod_proxy.html.

mercredi 9 mars 2011

Patch du jour : NRPE et les sorties longues

NRPE est vraiment un compagnon inséparable de nagios : lancer des plugins à distance sur un serveur et récupérer leurs résultats au travers d'une simple commande check_nrpe.

Pour l'illustrer, lançons un démon NRPE avec le fichier de configuration suivant :


log_facility=daemon
pid_file=./nrpe.pid
server_port=5666
server_address=127.0.0.1
nrpe_user=nagios
nrpe_group=nagios
allowed_hosts=127.0.0.1
dont_blame_nrpe=0
debug=0
command_timeout=60
connection_timeout=300

command[short_output]=/bin/cat /tmp/test
command[long_output]=/bin/cat /etc/screenrc


Nous y avons défini deux commandes (short_output et long_output) et nous l'avons fait écouter sur l'adresse localhost. Lançons maintenant notre process :


# ./nrpe -c ./nrpe.cfg -d
# ps -ef | grep nrpe
nagios 11411 1 0 22:39 ? 00:00:00 ./nrpe -c ./nrpe.cfg -d
root 11417 6370 0 22:39 pts/4 00:00:00 grep --color=auto nrpe


Essayons maintenant de récupérer le résultat d'une de nos commandes :


$ ./check_nrpe -H localhost -c short_output
Retour NRPE|Short_output=1


Tout semble fonctionner au mieux mais malheureusement dans le cas d'une sortie trop grande, tout ce qui dépasse 1024 ieme octet est ignoré :


$ ./check_nrpe -H localhost -c long_ouput | wc
34 160 1024


En creusant un peu, cette limitation vient de la définition d'une constante C dans le fichier include/common.h :

#define MAX_PACKETBUFFER_LENGTH 1024


Ici, la solution qui vient immédiatement à l'esprit est de simplement changer cette valeur et relancer la compilation. Une fois la recompilation terminée, nous obtenons un binaire check_nrpe et un binaire nrpe.

En lançant notre nrpe patché, nous avons effectivement le résultat attendu. Petit soucis, si vous avez déjà des agents NRPE et que vous voulez lancer votre commande check_nrpe sur un ancien serveur, vous obtiendrez une belle erreur vous indiquant un soucis de communication :


$ ./check_nrpe -H localhost -c short_output
CHECK_NRPE: Received 0 bytes from daemon. Check the remote server logs for error messages.


Si vous êtes comme moi avec environ 300 agents NRPE déjà existant, vous aurez quelques hésitations à les redéployer tous. Heureusement, tonvoon a écrit un patch assez astucieux à ce sujet il y a déjà quelques temps. Le principe est d'utiliser le champ packet_type pour indiquer un nouveau type RESPONSE_PACKET_WITH_MORE en plus des types RESPONSE_PACKET et QUERY_PACKET. Lorsque le plugin check_nrpe détecte ce type de paquet, au lieu de terminer la communication, le client récupère les packets suivants pour les concaténer jusqu'au maximum de 16ko. Et cerise sur le gateau : le plugin check_nrpe reste compatible avec les anciens clients NRPE !

Vous pouvez donc mettre votre plugin check_nrpe à jour et faire la mise à jour au fil de l'eau pour vos agents NRPE voir - si vous êtes vraiment un gros feignant - ne le faire que là où vous en avez besoin.

Pour appliquer le patch, récupérer une copie de NRPE en version 2.12, patcher là avec le fichier suivant puis lancer le classique configure ; make ; make install. Vous obtiendrez alors vos deux binaires à utiliser.

dimanche 20 février 2011

Exemple d'utilisation du répartiteur de charge Haproxy

Il y a de ça quelques années, j'ai eu l'occasion de travailler sur le répartiteur de charge HAProxy. Le point fort de cet outil est qu'il est très simple à mettre en oeuvre. Nous l'avions à l'époque mis en place pour une boucle de charge avec des serveurs d'applications Java WebLogic.

L'architecture


L'application pour laquelle nous devions mettre en place cette solution était un Webservice hébergé sur des serveurs d'application Weblogic. Il est important de souligner que cette application n'avait pas de notion de session et la persistance s'appuyait sur la librairie hibernate.

Afin de faire face au trafic (supérieur à 300 transactions/secondes), il avait été décidé d'héberger cette application sur 32 d'instances Weblogics réparties sur 4 machines. Nous devions trouver une solution permettant de répartir la charge tout en offrant des possibilités de maintenance de certains noeuds de la boucle de charge. Ceci nous permettait également de faire des évolutions applicatives en pleine journée.

Pourquoi utiliser ce type de répartiteur de charge


Nous disposions de matériel dédié à la répartition de charge (type Alteon) qui ne gère que la répartition de charge au niveau TCP. Cette situation n'était pas satisfaisante puisque nous avions besoin de pouvoir gérer certaines informations au niveau du HTTP (Keepalive et gestion boucle de charge). De plus, les applications venant consulter ce webservice avaient tendance à garder leur connexion HTTP ouverte empêchant la sortie d'instance Weblogic de la boucle de charge.

C'est là où intervient le HAProxy puisque cet outil de répartition de charge comprend le HTTP. Nous pouvions donc nous en servir pour désactiver le Keepalive et garantir qu'à chaque requête, nos clients passe par une nouvelle connexion.

A noter que la désactivation du Keepalive avait un surcoût au niveau CPU : 1 à 2% (sur un V890 équipé de 8 Ultra IV à 1.3 Ghz). Il est important de qualifier ce coût supplémentaire avec des benchs pour ne pas avoir de mauvaise surprise.

Le HAProxy était capable de scrupter une page présente sur le serveur WebLogic lui indiquant s'il doit le prendre en compte où non. Pour cela nous avions créé une page Web (page JSP dans une WAR) nous permettant de débrayer automatiquement une instance via le dépot d'un fichier dans le répertoire properties de nos instances Weblogic.

Création d'une application Web pour gérer la validité d'une instance


Nous allons tout d'abord créer un petit programme java qui va gérer un état d'une page en fonction d'un fichier properties :

package haproxy;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

import javax.servlet.Servlet;
import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HaproxyTestServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if (isAlive()) {
resp.setStatus(HttpServletResponse.SC_OK);
resp.getWriter().print("OK");
return;
} else {
resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,"Service non disponible");
}
}
protected void doHead(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if (isAlive()) {
resp.setStatus(HttpServletResponse.SC_OK);
} else {
resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
}
}
private boolean isAlive() {
URL url = this.getClass().getResource("/haproxy.down");
if (url != null) {
return false;
}
return true;
}
}


Il nous faut maintenant mapper cette applet au niveau de l'application Web en alimentant le fichier web.xml avec le contenu suivant :

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp">
<display-name>TestHaproxy</display-name>
<servlet>
<servlet-name>HaproxyTestServlet</servlet-name>
<display-name>HaproxyTestServlet</display-name>
<servlet-class>haproxy.HaproxyTestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HaproxyTestServlet</servlet-name>
<url-pattern>/HaproxyTestServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>


Reste à la mettre en place et de voir le résultat de son déploiement en consultant l'application en rentrant son URL (http://monserver:monport/haproxy/HaproxyTestServlet). Pour désactiver une instance ? Rien de plus simple : créer un fichier haproxy.down dans le répertoire des properties de l'instance. Remettre une instance dans la boucle ? Simplement en supprimant le fichier haproxy.down

Mise en place de la solution


Il faut d'abord créer un fichier de configuration pour notre HAProxy (haproxy.cfg).

Ce dernier contient l'adresse et le port d'écoute (ici host:8888) ainsi que de nombreux paramètres sur son fonctionnement. Ci-dessous un début de fichier de configuration intéressant :

global
maxconn 4096
daemon
nbproc 2
pidfile /var/run/haproxy-private.pid

listen proxy host:8888
log global
mode http
option httplog
option dontlognull
cookie COOKIEID insert indirect nocache
balance roundrobin


La liste des serveurs dans la boucle de répartition de charge est représenté par la liste de ligne commençant par server.

server inst11 web1:7011 check inter 2000 rise 2 fall 5
server inst21 web2:7021 check inter 2000 rise 2 fall 5
server inst31 web3:7031 check inter 2000 rise 2 fall 5
server inst41 web4:7041 check inter 2000 rise 2 fall 5
[...]
server inst18 web1:7018 check inter 2000 rise 2 fall 5
server inst28 web2:7028 check inter 2000 rise 2 fall 5
server inst38 web3:7038 check inter 2000 rise 2 fall 5
server inst48 web4:7048 check inter 2000 rise 2 fall 5

Indiquons également l'emplacement de notre page de test ainsi que nos paramètres de répartition de charge :

monitor-uri /haproxy/HaproxyTestServlet
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000


Enfin, dans le cas où vous voudriez désactiver le Keepalive HTTP, rajoutez les lignes suivantes :

reqidel ^Connection: # disable keep-alive
reqadd Connection:\ close
rspidel ^Connection:
rspadd Connection:\ close


Il ne nous reste plus qu'à lancer le démon haproxy à l'aide de la commande suivante :
haproxy -D -f haproxy.cfg


Conclusion


Dans cet article, nous n'avons vu qu'une toute petite partie des capacités de ce répartiteur de charge. Son auteur (Willy Tarreau) a également inclu des fonctionnalités très intéressantes comme :
- la gestion d'IPV6 (v1.2)
- la gestion des cookies applicatifs pour garder le contexte d'un client vers un seul serveur (v1.2)
- la reconfiguration à chaud (v1.2)
- la répartition de charge avec poids (v1.2)
- la page de diagnostique (v1.2)
- la gestion des contenus statiques/dynamiques (v1.3)

Pour en savoir plus : http://haproxy.1wt.eu/#desc