Un rapport par défaut dans Trac

Dans Trac, lorsque l’on clique sur “Voir les tickets”, on arrive sur la liste des différents rapports disponibles.

Pour des questions pratiques, je préférais arriver directement sur la page du rapport des tickets actifs. On peut donc modifier les liens du menu horizontal pour y arriver! Modifiez donc le fichier trac.ini comme ceci:

[mainnav]
tickets.href = /report/1

Ainsi, ce sera le rapport d’ID 1 qui sera ouvert.

C: Régler le problème des defunct process

Lorsque vous développez une application, il est parfois très intéressant d’utiliser des threads ou plusieurs processus pour exécuter plusieurs tâches simultanément. Nous allons ici voir un problème qui arrive lors que l’on utilise plusieurs processus, via un fork(). En effet, en C, la fonction fork permet de créer un nouveau processus, qui devient fils du processus appelant le fork.

Processus zombies (defunct)

Par défaut, lorsque le processus père s’arrête, tous les processus fils s’arrête. À l’inverse, lorsqu’un processus fils s’arrête – via un exit(0); par exemple -, sa mémoire est libérée, il devient un processus zombie (seul le bloc de contrôle reste présent) et le processus père continue de fonctionner.

Ainsi, l’on peut voir de nombreuses lignes marquées par un defunct lorsque l’on liste les processus avec un ps:

root      9175  0.0  0.0 136380  1100 ?        Sl   Jun30   0:00 /[...]/relay
root      9629  0.0  0.0      0     0 ?        Z    Jun23   0:00 [relay] <defunct>
root      9853  0.0  0.0      0     0 ?        Z    Jun30   0:00 [relay] <defunct>
root      9884  0.0  0.0      0     0 ?        Z    Jun30   0:00 [relay] <defunct>

C’est parce que le processus père n’écoutes pas le signal SIGCHLD, qui est envoyé par le fils lors de son extinction. Ainsi, en écoutant le signal, le père peut libérer son bloc de contrôle. En C, c’est la fonction waitpid qui nous sera utile.

Une ligne à ajouter

Il n’y a qu’une seule ligne (ainsi qu’un #include) à ajouter à votre code C pour que les processus zombies soient “ramassés” par votre processus père. De temps en temps – l’idéal étant la boucle principale s’il y a -, exécutée cette ligne ci:

while (waitpid(WAIT_ANY, NULL, WNOHANG) != 0);

Les arguments sont les suivants:

  • WAIT_ANY est la constante permettant de dire que l’on souhaite attendre n’importe quel des processus fils de ce processus. À la place, nous aurions pu mettre le pid d’un processus particulier.
  • NULL permet de ne pas récupérer d’informations de statut du processus.
  • WNOHANG est une option permettant d’exécuter waitpid en mode non-bloquant.

N’oubliez pas d’inclure l’en-tête des fonctions et constantes ainsi:

#include <sys/wait.h>

Ainsi, il ne restera plus de processus zombie, ou defunct.

Varnish en reverse-proxy: le problème des adresses locales

Si vous utilisez nginx ou Apache derrière Varnish, vous aurez remarqué que l’adresse IP du client récupérée est l’adresse locale (ou bien l’adresse du serveur hébergeant Varnish). Cela est le cas parce-que c’est Varnish qui créé la connexion TCP à nginx/apache, et non le client directement. Pour cela, nous allons tout simplement installer un module sur votre serveur Web, pour qui va utiliser une en-tête (X-Forwarded-For) pour connaitre l’IP du client.

Pour nginx

Il nous faut nginx compilé avec le module Real-IP (--with-http_realip_module), ce qui est le cas par défaut dans les paquets CentOS et Debian. Dans le fichier de configuration /etc/nginx/nginx.conf, dans la catégorie http {...}, ajoutez ça:

    set_real_ip_from 127.0.0.1;
    real_ip_header X-Forwarded-For;

Redémarrez le serveur nginx, et c’est bon.

Pour Apache

Pour Apache, il faut installer le module RPAF2. Je vous invite à lire l’article très intéressant de wiki.tyk.nu.

Monitoring nginx avec Zabbix

En complément de l’article sur le monitoring de PostgreSQL avec Zabbix, voici un nouvel article pour monitorer un serveur Nginx grâce à l’agent Zabbix.

Pour cela, nous avons besoin d’avoir ZTC (Zabbix Template Collection) d’installé: voyez le premier chapitre de l’article précédent sur ZTC.

Configuration d’Nginx

Pour pouvoir récupérer des statistiques sur le serveur Nginx, vous devez l’avoir compilé avec le module HTTPStubStatus, c’est-à-dire avec l’option --with-http_stub_status_module.

Ensuite, il y a uniquement à configurer l’accès aux statuts depuis l’hôte local de Nginx. Si vous n’avez pas créé d’hôte local pour Nginx, il vous suffit d’en créer un.
Ensuite, ajoutez ces quelques lignes de configuration suivantes dans votre server local:

    location /server-status {
        stub_status on;
        access_log off;
    }

Elle permettent de dire qu’à l’adresse http://localhost/server-status, Nginx doit confier la réponse HTTP au module HTTPStubStatus, qui fournira des statistiques sur le serveur qui seront récupérées par l’agent.

N’oubliez pas de recharger la configuration du serveur HTTP:

# /etc/init.d/nginx reload

Vous pouvez vérifier la configuration depuis votre serveur grâce à wget:

$ wget http://localhost/server-status

Si le code réponse est bien 200, la configuration est correct.

Configuration de l’agent Zabbix

Avec la même configuration de l’agent Zabbix décrit dans l’article sur PostgreSQL, nous allons activer le template pour Nginx:

# cd /etc/zabbix-agent.d/enabled
# ln -s ../available/pgsql.conf pgsql.conf

Maintenant, nous allons modifier la configuration de l’agent ZTC pour Nginx, à savoir le fichier /etc/ztc/nginx.conf. Remplacez les lignes suivantes:

host=localhost
port=80

L’agent ZTC est maintenant configuré, nous allons le tester:

$ /opt/ztc/bin/nginx.py requests

Vous devriez avoir comme retour un nombre supérieur à zéro. Si c’est le cas, tout fonctionne !

Importation dans le serveur Zabbix

Pour finir, importez le modèle Nginx de ZTC (vous trouverez tous les modèles dans le dépôt ZTC), que vous pouvez télécharger ici:

Maintenant, configurez le(s) hôte(s) que vous avez configuré(s) comme ayant le modèle Template_app_nginx. Vous aurez ainsi les statistiques Nginx!

Installer Zabbix 1.8.x avec PostgreSQL sur CentOS 5

Zabbix est une application de monitoring. Elle permet de surveiller votre parc de serveurs, d’applications et de sites Web. Elle se compose d’un serveur ainsi que d’agents (facultatifs, mais qui permettent de récupérer plus d’informations locales que SNMP) sur chacune des machines à monitorer.

Nous allons voir comment installer le serveur Zabbix ainsi que son front-end Web écrit en PHP, sous CentOS 5.

Installation du serveur Zabbix

Installation des dépendances

Avant tout, nous allons installer les dépendances de Zabbix, à savoir les librairies zlib, curl, openssl, net-snmp et openIPMI, pour pouvoir utiliser au maximum les fonctionnalités de Zabbix. Nous allons également installer un système de gestion de base de données, pour stocker toutes les données: PostgreSQL.

# yum install zlib-devel glibc-devel curl-devel gcc automake libidn-devel openssl-devel net-snmp-devel rpm-devel OpenIPMI-devel postgresql84-devel

Nous allons maintenant initialiser la nouvelle base de données PostgreSQL:

# /etc/init.d/postgresql initdb

Important: si vous avez déjà une base de données PostgreSQL sur votre serveur, n’initialisez pas la base! Vous pouvez également voir comment installer PostgreSQL 8.x sous Debian.

Installation du serveur

Maintenant, nous allons télécharger les sources de Zabbix pour l’installer. Vous trouverez les archives des sources sur la page de téléchargement du site Web de Zabbix.

$ wget http://sourceforge.net/projects/zabbix/files/ZABBIX%20Latest%20Stable/1.8.4/zabbix-1.8.4.tar.gz/download -O zabbix.tar.gz
$ tar -xzf zabbix.tar.gz
$ cd zabbix-*

Maintenant, nous allons commencer le processus de compilation en utilisant le programme ./configure avec nos options:

$ ./configure --enable-server --with-pgsql --with-net-snmp --with-libcurl --with-openipmi --enable-agent --enable-ipv6

Si toutes les dépendances sont satisfaites, vous devriez avoir ce message:

Enable server: yes
Server details:
With database: PostgreSQL
WEB Monitoring via: cURL
Native Jabber: no
SNMP: net-snmp
IPMI: openipmi
SSH: no

[...]
Enable agent: yes
Agent details:
Linker flags: -rdynamic
Libraries: -lm -lresolv

LDAP support: no
IPv6 support: yes

Ensuite, il nous reste à compiler Zabbix:

# make

À ce moment, vous pouvez installer Zabbix sur votre système comme ceci:

# make install

Note: Vous pouvez également créer un paquet de Zabbix avec cette configuration grâce au programme checkinstall.

Continue reading

Installation de PHP 5.3 avec Nginx en Fast-CGI sous CentOS

Nous allons installer Nginx et PHP 5.3 configurés pour communiquer en Fast-CGI sous CentOS (testé sous CentOS 5.5). L’avantage de Nginx est qu’il est beaucoup plus rapide qu’Apache, et très complet malgré tout. Dans l’ordre, nous allons installer les paquets pour Nginx et PHP, puis nous allons configurer la liaison Fast-CGI entre les deux.

Installation des dépôts EPEL

Avant tout, pour pouvoir avoir les dépôts EPEL et IUS, dans lequel il y a Nginx et PHP 5.3, nous allons installer deux paquets qui ajoutent ces dépôts:

# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm
# rpm -Uvh http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/ius-release-1.0-6.ius.el5.noarch.rpm

Installation de nginx

L’installation de nginx est très rapide grâce à yum, il vous suffit de lancer cette commande:

# yum install nginx

Installation de PHP 5.3

L’installation de PHP 5.3 se fait grâce aux paquets php53*, que nous pouvons également installer grâce à yum.

# yum install php53 php53u-pecl-apc php53u-gd php53u-mbstring php53u-devel php53u-snmp php53u-cli php53u-pdo

Note: vous pouvez installer d’autres paquets pour le support de MySQL – php53u-mysql -, ou de PostgreSQL – php53u-pgsql ou php53u-pgsql84 -. Listez les paquets pour PHP 5.3 grâce à la commande yum list | grep php53.

Continue reading

Optimiser l’affichage de pages avec Google Adsense

Les pages Web contenant des publicités Google Adsense sont nettement plus lentes à charger que les pages qui n’en contiennent pas: c’est à cause de la méthode de chargement des publicités et de leur place dans la page. En général, les publicités se trouvent dans l’en-tête et/ou dans le menu vertical, elles sont donc chargées avant le corps de page.

Le problème

Le code fourni par Google pour afficher ses publicités est le suivant (avec des variables différentes):

<script type="text/javascript">
google_ad_client = "ca-pub-7282418192222825";
/* Nom de la bannière */
google_ad_slot = "4287714958";
google_ad_width = 468;
google_ad_height = 60;
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>

Or, lors du chargement d’un fichier JavaScript, le moteur de rendu du navigateur est arrêté et le chargement de tous les éléments autres est suspendu. Par conséquent, le navigateur doit attendre que la page externe finisse de charger avant même de continuer à charger les autres éléments internes de la page Web. Ainsi, la page est nettement plus longue à charger et le ressenti utilisateur est plus mauvais…
Continue reading

SVN: Créer des liens entre les dépôts avec svn:externals

Il est possible que dans certains projets, vous ayez besoin d’une librairie, d’une autre projet ou d’un dossier précis d’un autre projet, que vous l’ayez développer ou pas. Seulement, vous ce dont vous avez besoin est voué à être mis à jour régulièrement et que vous voulez profiter de manière automatique de ces mises à jour, il y a une solution avec SVN: svn:externals.

Comme nous le montre le “livre de SVN”, svn:externals est une propriété associée à un dossier parent, qui permet de déclarer un dossier fils comme un contenu externe. Ainsi, vous pouvez configurer la propriété sur votre dossier /project1/trunk/includes/ pour que le dossier fils lib1 contienne /project-lib1/trunk par exemple.

Ainsi, à chaque mise à jour (svn update) de votre project1, votre client SVN ira voir à l’adresse associée pour le dossier trunk/includes/lib1 pour vérifier qu’aucune nouvelle révision n’éxiste.

Note: Vous pouvez très bien lors de la création de la propriété svn:externals spécifier une révision précise du dépôt externe, mais je ne voit pas vraiment l’intérêt dans le sens où, dans ce cas là, un svn copy ou un simple copier/coller suffit.
Continue reading

PHP-Gettext-Edit: Gérez vos traductions Gettext simplement!

PHP-Gettext-Edit est une application PHP qui permet de gérer très simplement les différentes traduction d’un site Internet par exemple, plus généralement d’une application (qu’elle soit écrite en PHP, C, Java, JavaScript…) utilisant des fichiers de traduction Gettext.

En utilisant PHP-Gettext-Edit, vous pouvez en quelques clics analyser votre code, faire les traductions et compiler les fichiers de traductions! PHP-Gettext-Edit vous permet de:

  • Analyser un code source pour en générer un modèle de traduction, contenant toutes les chaines de caractère à traduire
  • Créer des fichiers de traduction à partir de modèles
  • Éditer directement depuis votre navigateur un fichier de traduction
  • Compiler en .mo ou en JSON un fichier de traduction
  • Contrôler la validité
    • Des modèles par rapport au code source
    • Des fichiers de traductions par rapport à leurs modèles
    • Des fichiers compilés par rapport à leurs fichiers de traduction
    • Des langues entre-elles par rapports aux fichiers qu’elles contiennent
  • Éffectuer les opérations précédentes de manière collective

Rendez-vous sur le site du projet, www.php-gettext-edit.net »

PostgreSQL: Utiliser le principe du type “varlena”

PostgreSQL utilise depuis Postgres le type varlena, qui signifie variable length array en anglais, soit tableau à taille variable en français. Ce type permet de stocker des données à taille variable dans la base de données. Le principe est très simple: stocker en mémoire une ou plusieurs données de façon contiguë. De plus, il ne doit pas y avoir de pointeur dans le type.

La structure “de base” de varlena est définie dans le fichier src/include/c.h, line 401 pour PostgreSQL 8.4 par:

struct varlena
{
	char	vl_len_[4];
	char	vl_dat[1];
};

Note: le premier tableau de 4 caractères peu très bien est remplacé par un int32, ça revient au même: 4 octets.

Ce type représente le principe: un champ vl_dat, qui contiendra la donnée et d’autres champs qui ne doivent pas être des pointeurs, mais des entiers le plus souvent (ici un tableau de 4 caractères), qui contiennent des informations sur cette donnée. Cela permet à PostgreSQL de pouvoir stocker sur le disque et en mémoire toutes les données en une fois, pouvant ainsi les déplacer comme bon lui semble.

Attention: la propriété qui contient les données doit être la dernière propriété de la structure.

Tout type de donnée un peu complexe doit utiliser ce principe lorsqu’il stocke des données de taille variable en base afin d’assurer une intégrité aux données stockées. Nous allons voir, à l’aide de la librairie parse_url pour PostgreSQL, comment créer un type de données stockant de nombreuses données de taille variable dans une seule et même donnée, dans le but d’être utilisé comme type de colonne dans une table par exemple.

Continue reading