Journal Nagios va-t-il quitter le C pour le Python?

Posté par  (site web personnel) .
Étiquettes : aucune
23
10
déc.
2009
Bonjour cher journal,

Je t'écris pour te signaler que dernièrement j'ai fait une proposition étonnante sur la mailing list de développement de Nagios. Je propose ni plus ni moins que de changer l'implémentation en C du cœur de Nagios par une nouvelle faite en Python qui est plus rapide et plus modulaire. Le changement d'implémentation ne change rien pour les utilisateurs qui peuvent toujours utiliser leur même fichier de configuration Nagios.

Pour rappel Nagios est un logiciel de supervision, considéré encore comme le maître en la matière dans le monde open source, même si ses concurrents comme Zabbix ou Zenoss commencent à le rattraper.

Le contexte de la nouvelle implémentation
Ceux qui ont suivi un peu l'histoire de Nagios ces derniers temps savent que ses évolutions ont été très limitées.Même après un Fork peu suivi, le projet n'a pas repris un nouveau souffle. C'est pour cette raison qu'il y a quelques mois j'ai commencé à coder un proof of concept pour de nouveaux modes de fonctionnement de Nagios comme le découpage des rôles en processus séparés ou bien la mise en place d'un pool de processus pour le lancement des sondes. Ce projet au nom de Shinken a rapidement évolué et s'est révélé, à ma grande surprise, bien plus rapide que Nagios lui même.

Les intérêts de la nouvelle implémentation
La partie architecture globale de l'application est également très innovante par rapport à Nagios. Ce dernier est monolithique : il lit la configuration, ordonnance les vérifications, les lance lui même
ainsi que les notifications. Ce mécanisme est suffisant pour une majorité des cas amis bien insuffisant pour les grands environnements.

En effet, Nagios est capable de lancer environs 10000checks en 5 minutes avec une configuration standard et 30000 avec des paramètres de tuning. Ce sont de bonnes performances, mais insuffisantes lorsque le nombre d'hôtes supervisés devient importants. Shinken arrive à monter à plus de 150000checks en 5 minutes en supprimant les goulots d'étranglements liés à la conception même du démon Nagios actuel qui repose sur la lecture de fichiers plats.

Lorsque les performances viennent à manquer, dans Nagios une solution consiste à utiliser plusieurs instances de Nagios travaillant ensembles, mais de nombreuses limitations subsistent quant à la gestion de la configuration et son envoi vers les différents Nagios et la difficile gestion de la haute disponibilité des Nagios. De plus, chaque Nagios gère ses propres notifications et données de performances ce qui complexifie grandement l'administration de la solution. Des solutions comme Centreon aident à la gestion de la configuration mais ne résolvent pas les problèmes de hautes disponibilités.

La solution de Shinken consiste à séparer les rôles de Nagios dans différents démons qui peuvent fonctionner sur des serveurs distincts, ces derniers pouvant se multiplier si le besoin de performances ou de haute disponibilité se fait ressentir et le tout avec très peu de changement dans la configuration !

L'un des autres avantages de la nouvelle architecture apportée par Shinken est d'avoir un seul point d'administration et de configuration : l'administrateur a une seule configuration à créer et gérer, elle sera découpée automatiquement par l'outil pour coller aux nombres d'ordonnanceurs disponibles. Il en est de même pour lancer des commandes externes : il suffit de la lancer à un endroit, et le démon va se charger de la redistribuer à qui il faut.

La proposition sur la mailing list
Les idées issues de ce proof of concept ayant déjà été rejetées offlist par les core développeurs ce Nagios car trop complexe à intégrer au cœur écrit en C, j'ai décidé de proposer de changer l'implémentation actuelle qui montre ses limites par une nouvelle basée sur son proof of concept bien plus performante et modulaire. Il est en effet plus simple d'améliorer son proof of concept pour lui rajouter les dernières fonctionnalités de Nagios qu'il ne gère pas, que d'apporter ses améliorations dans l'ancien code.

Pour l'instant les réponses à cette proposition sont partagées. Les core développeurs n'ont toujours pas pris positions sur une éventuelle inclusion dans la branche de développement.

Et toi mon cher journal, quel est ton avis?

Source : http://www.nagios-fr.org/2009/12/shinken-nagios-core-killler
  • # URLs

    Posté par  . Évalué à 7.

    Ce serait sympa d'avoir un lien vers le message où tu fais ta proposition, et le(s) fils de discussion afférent(s).
    Cela prouve en tout cas qu'un langage haut niveau comme Python permet de se concentrer sur les améliorations conceptuelles et peut in fine faire gagner de la vitesse, plutôt qu'en perdre.
    • [^] # Re: URLs

      Posté par  (site web personnel) . Évalué à 6.

      Honte à moi. J'ai complètement zappé le lien :

      https://sourceforge.net/mailarchive/message.php?msg_name=6f8(...)
      • [^] # Re: URLs

        Posté par  . Évalué à 6.

        J'adore la réponse suivante :

        « Personally if I'm to consider rewriting nagios in interpreted language I'd wait for Perl6 to come out, it'd be taken a lot better by nagios users. »

        Perl 6, hum hum :-)
        • [^] # Re: URLs

          Posté par  (site web personnel) . Évalué à 1.

          J'ai préféré ne pas répondre à cet email là, le lâché de troll aussi tôt dans une discussion, ce n'est pas bon :)

          D'ailleurs pour pouvez remarquer dans un des derniers emails l'apparition d'un sondage et sur une possibilité de choix originale qui je suis sûr à bien aidé à réveillé le débat :)
          • [^] # Re: URLs

            Posté par  (site web personnel) . Évalué à 1.

            J'ai toujours cru que nagios était un mélange de C et de perl. J'ai du me tromper.

            Si on regardait justement du coté de perl, le framework POE n'est-il pas proche de ce que tu as fait avec python ?

            http://poe.perl.org/
            • [^] # Re: URLs

              Posté par  . Évalué à 4.

              Il me semble que ce sont les plugins qui sont souvent en Perl (mais qui peuvent être en n'importe quoi).
  • # Belle initiative

    Posté par  . Évalué à 5.

    Je trouve l'initiative intéressante.

    Revoir l'implémentation de fond pour améliorer les performances et l'administration, c'est comme ça qu'on rend un produit prêt pour l'exploitation/supervision de gros environnements et qu'on assure son avenir.

    A la première lecture ce qui surprend, c'est de voir qu'un langage de plus haut niveau comme python, lorsqu'il est bien implémenté s'avère plus efficace qu'un langage de plus bas niveau mais avec une architecture vieillissante.

    Cela montre bien que les choix techniques fait à un instant T dans un contexte C, ne sont pas forcément pertinent dans un temps T + 1 et avec un contexte "C + 1".

    Maintenant pour satisfaire ma curiosité, j'aimerais savoir pourquoi le choix du langage s'est fait sur python, est-ce que par goût de l'auteur ou bien à la suite d'une sélection rigoureuse et exhaustive ?
    • [^] # Re: Belle initiative

      Posté par  . Évalué à 10.

      Moi ce qui m'étonne c'est qu'en 2009 des gens s'étonnent encore que les choix architecturaux, algorithmiques et de structure de données ont plus d'impact que les optimisations de code.

      La duplication de donnée, les indirections pourries et mal pensées, le code pas extensible, pas modularisable ou externalisable, ne pas pouvoir séparer les traitements, les abstractions chiottiques etc. ça coute beaucoup beaucoup plus cher en perf à terme... Après si tu appliques les même design/algorithme/structure de données avec un langage plus performant, ça ira plus vite, mais ça risque de couter un peu plus cher à faire ou un peu plus longtemps à stabiliser.

      Bref rien de nouveau sous le soleil depuis le début de l'informatique !
    • [^] # Re: Belle initiative

      Posté par  (site web personnel) . Évalué à 6.

      Merci.

      Le choix est 80% sur mon goût pour le Python, 20% pour ses qualités intrinsèques.

      Les capacités dynamiques de Python comme le rajout de propriétés d'un objet à chaud ou bien le fait de pouvoir vérifier qu'il a bien une propriété particulière est très pratique dans le contexte de Nagios (la configuration utilise des principes d'héritages d'objet, donc ça colle parfaitement aux capacités du langage).
      Si tu rajoutes un module Python comme Pyro pour les objets distribués d'un très grande qualité, le fait que le langage a très bonne publicité et que je me retrouve dans le "zen de python" (les grands principes du langage), le choix était fait.

      Il me semble que Erlang aurait pu être utilisé car l'architecture est très distribuée, mais j'ai préféré parier sur un compromis plus reconnu et avec une plus grande communauté.
      • [^] # Re: Belle initiative

        Posté par  . Évalué à -10.

        Plus sérieusement, j'ai un peu de mal à comprendre cet engouement pour Pyton : C'est moche, verbeux, on passe son temps à déclarer des trucs inutiles (le pire : se trainer le self dans chaque déclaration de méthode d'un objet), et ça n'apporte rien. Une bonne façon de rendre les gens fous est de leur demander de répéter sans cesse la même chose. Et de ce côté python est pas mal je trouve.
        • [^] # Re: Belle initiative

          Posté par  . Évalué à 8.

          Visiblement, les gens qui font du python n'ont aucun problème, Toi qui n'en fait pas, par contre, tu viens nous faire un caca nerveux parce que quelqu'un a imaginé porter un programme que tu n'utilises peut-être même pas, en python. Tu devrais consulter.
          • [^] # Re: Belle initiative

            Posté par  . Évalué à 3.

            Visiblement, les gens qui font du python n'ont aucun problème,
            Ce serait quand même un signe de déficience mentale avancé que de faire du python tout en ayant des problèmes avec oython. Pour ma part, j'en ai fait, et j'ai arrêté parce qu'on passe son temps à déclarer des choses inutiles (je n'aime pas l'implicite de Perl qui pousse à écrire des progs crades, mais le tout explicite de python est un peu trop dans l'autre extrême).

            En voulant "gommer" les défauts de Perl, Python est allé trop loin.
            • [^] # Re: Belle initiative

              Posté par  . Évalué à 2.

              En voulant "gommer" les défauts de Perl, Python est allé trop loin.

              Je pense que Python et ses concepteurs n'en ont rien à battre de Perl :)
              Tu penses peut-être à Ruby...
            • [^] # Re: Belle initiative

              Posté par  (site web personnel) . Évalué à 2.

              je ne vois pas trop de quoi tu parles quand tu dis « déclarer des choses inutiles ». Python est un langage qui donne un code justement très court et très expressif. Tu as dû pratiquer ou lire du Python dégueulasse, alors. Quant au « Explicit is better than Implicit » du Zen of Python, c'est juste un conseil, pas un truc intrinsèque du langage.
        • [^] # Re: Belle initiative

          Posté par  (site web personnel) . Évalué à 5.

          Tu as de la chance, y'a plein d'autres langages, dont sûrement un qui te plaira - et qui pour d'autres raisons ne plaira pas à d'autres personnes.
          Sinon, pour le côté verbeux, les self et tout ça, voir "The Zen of Python". A-priori tu n'es pas sur le même "zen" que les adeptes du serpent.

          "The Zen of Python" (PEP 20): http://www.python.org/dev/peps/pep-0020/

          Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN

          • [^] # Re: Belle initiative

            Posté par  . Évalué à 3.

            Ou plus simplement: "import this" dans un interpreteur python :)
  • # Tant qu'à utiliser un langage efficace ....

    Posté par  . Évalué à -10.

    ... autant utiliser ruby
    • [^] # Youpi

      Posté par  . Évalué à 10.

      C'est vraiment très intéressant ce que tu dis, tu devrais en parler à /dev/null.
      • [^] # Re: Youpi

        Posté par  . Évalué à -6.

        Bah, si on peut plus troller tranquillement sans se faire moinsser, c'est plus drôle ....
        • [^] # Re: Youpi

          Posté par  . Évalué à 3.

          Tu peux troller (après tout, on est sur DLFP ici...), mais le tout c'est de le faire en finesse.

          Ou alors version troll de combat urticant (genre plus c'est gros plus ça passe).

          Mais visiblement tu as manqué d'ironie et/ou d'ambition... la prochaine fois peut-être ?
          • [^] # Re: Youpi

            Posté par  . Évalué à 3.

            Exercice difficile que le troll : quand on trolle trop en finesse ça ne passe pas, et quand on y va trop brutalement ça ne passe pas non plus. Il faut savoir doser. Je ferai mieux la prochaine fois :)
  • # questions (réutilisations, multiplexage, compatibilité)

    Posté par  . Évalué à 5.

    Merci beaucoup,
    c'est un joli projet et j'espère que les autres devs seront receptifs.
    J'ai quelques questions.

    - Est-ce que les composants sont réutilisables sortis de l'ensemble?
    par ex. peut-on réutiliser le parsing de conf pour faire autre chose? est-ce qu'ils ont une api "publique" ou seulement interne? (par ex. pour attaquer directement les scheduler et leur demander où ils en sont, changer leurs priorités, etc).

    - En parlant de montée en charge ("scalability")...
    comme le fait remarquer quelqu'un en réponse sur la m-l, l'essentiel de la durée d'execution d'un plugin type semble être passé à attendre (attente pour pouvoir écrire sur une socket, attente d'une réponse...) (plus le temps du exec() et envois du retour à nagios, bien sûr).

    J'ai l'impression que l'execution des plugins en tant que commandes externes impose une limite au nombres de tests/seconde possibles : outre la surcharge de l'execution externe, en lancer un trop grand nombre simultanément (et même s'ils ne font pour ainsi dire rien d'autre qu'attendre, et quand bien même l'architecture à mutiple poller + NDX permettrai d'en lancer 10000 à la fois) signifirait saturer le/les système de processus sleeping.

    Est-ce que des plugins très couramment utilisés comme check_tcp, check_http, et check_smtp pourraient être re-implementés en interne, et executés simultanément par multiplexage asynchrone et evenementiel de sockets ? par ex. en les regroupants quand c'est possible sur un seul (ou, disons, une poignée de) processus gerant x "checks classiques sur tcp ou udp ou raw (icmp)" et multiplexant via epoll()/kqueue() etc à la façon nginx/haproxy. Il existe plusieurs libs python pour faire ce genre de choses (twisted, mais il ne supporte pas IPv6, PyEvents, libevent-python...).

    Le modèle des multiples pollers de shinken semble permettre ceci, au sens où avoir un couple de poller spécialisés/dédié aux checks de bases reposants sur tcp ne devrait pas empecher l'execution d'autres plugins en parralele (?).

    - Quel est le niveau de compatibilité visé avec un nagios3 ?
    seulement compatible au sens de pouvoir réutilise l'ancienne conf et certains plugins à condition d'y adjoindre des confs spécifiques à shinken ? générer un status.dat ? etc
    • [^] # Re: questions (réutilisations, multiplexage, compatibilité)

      Posté par  (site web personnel) . Évalué à 1.

      - La plupart sont très liés à Nagios, à part le poller/reactionner qui peut être utilisé pour lancer n'importe quoi en fait le tant que ce qui nous intéresse est un code retour et l'output. L'API est basique et basée sur du Pyro, mais on pourrait imaginer de placer la dépendance à un service comme optionnelle si d'autres veulent utiliser autre chose.

      -Oui, un plugin ça attend. C'est pour ça qu'il faut en lancer plein. Mais même s'ils attendent 80% de leur temps, ils travaillent un jour tout de même :) Donc tu as tout de même une limite sur le nombre que tu peux lancer en parallèle. Ce nombre est complexe a déterminer suivant le tyype de sonde (certains sont très lent, d'autres non), ce qui complexifie le nombre que tu va autoriser à être en parallèle. J'essais justement de déterminer le niveau de "charge" du poller pour qu'il soit au max, mais pas plus.

      On pourrait intégrer les plugins les plus courants dans le code du poller, suivant ce qu'il devrait lancer il utiliserait tel code natif python plutôt que de faire un exec(). Je n'ia pas encore trouvé de méthode facile çà utiliser pour l'utilisateur (il "décrit" le plugin à utilsier dans la conf de sa commande? On se base sur une reconnaissance de la commande en expression régulière?)

      Le fait de dédier des pollers je ne suis pas sûr, car un poller pourrait avoir plusieurs types de workers (c'est eux qui on un nombre de process lancés en parallèles), donc le mix pourrait se faire là, sans trop de chanboulement.

      Pour la compatibilité avec les plugins, c'est totale, pas la moindre inquiétude là dessus. La force de Nagios réside dans ses plugins, pas l'ordonnanceur. Pour la conf, Shinken vise pour l'instant du 90% de compatibiltié. Si il est inclu dans la branche officielle de Nagios, je viserais le 100% forcément, même si de nombreuses options sont inutiles.
      • [^] # Re: questions (réutilisations, multiplexage, compatibilité)

        Posté par  . Évalué à 2.

        - La plupart sont très liés à Nagios, [...]

        C'est en fait dans ce cadre (toujours pour du Nagios) que je posais ma question ; à savoir : la possibilité de réutiliser un composant pour faire quelque chose d'autres (mais toujours relatif à nagios/shinken). Par ex. re-utiliser le parseur de conf, indépendamment du reste, pour faire un petit outil cli qui valide un changement, ou qui génère un hostexinfo.cfg automatiquement, ou qui fait un diagramme de gantt à partir des timeperiod, ce genre de choses quoi... Depuis j'ai regardé ton code et j'ai ma réponse (qui est: oui, c'est super modulaire, kewl :).

        - [...] Donc tu as tout de même une limite sur le nombre que tu peux lancer en parallèle. Ce nombre est complexe a déterminer suivant le tyype de sonde [...]

        C'est là que le multiplexage et le modèle évènementiel rendent service, justement. Il n'y a rien à déterminer à l'avance, le parallélisme est mis en œuvre par le noyau.

        On peux donner autant de socket qu'on veut à un seul processus (même des centaines de milliers, si on utilise quelque chose de plus scalable que select(2), cf. haproxy par ex.), et ce processus travaille dès que l'une d'elles a des données dispos à lire. Au plus fort de la charge, le processus passe tout son temps (il utilise un cœur de cpu à plein) à faire les vrais traitements des données utiles en transit, aussi vite qu'il peut. Lorsqu'il n'y a rien à lire ou écrire, le processus dort. Dans tout les cas, et quelque soit le nombre de sockets dont il est responsable, le processus ne consomme que les ressources (ram et cpu) nécessaires au vrais traitements qu'il doit faire.

        Un exemple : c'est pour ces raisons (une mainloop événementielle coté lighttpd et nginx vs. des pools de workers, threads ou forks, un pour chaque requète simultanée coté apache) que nginx et lighttpd ne sont pas affectés par le récent "slowloris", alors qu'apache s'écroule

        Pour les mêmes raisons, lorsque plusieurs hôtes ne répondent pas aux requêtes, les plugins classique mais parallélisés vont sans doute occuper des ressources (x poller en attente + x * le plugin lui-même) jusqu'aux timeouts, et donc ralentir les autres traitements (si on essaie de maintenir un nombre constant/max de checks en cours) ou mettre le serveur de monitoring à genoux (si on ne limite pas), au moment ou justement on a besoin de monitoring précis et réactif parce qu'il y a des soucis sur le réseau.

        De même, un processus dédié peut certainement gérer sans charge aucune quelques milliers de raw sockets pour envoyer/recevoir des pings en natif (sans "popen('/bin/ping'...)", mais il faut que le processus soit root ou la capabilty CAP_NET_RAW...) et avoir un résultat de check_host_alive à la seconde près sur un large parc. Dans le genre de http://gitorious.org/poe-component-client-ping .

        Des docs pythoniques sur le sujet:
        http://squirl.nightmare.com/medusa/async_sockets.html
        http://docs.python.org/library/asyncore.html
        http://docs.python.org/library/asynchat.html


        - Je n'ia pas encore trouvé de méthode facile çà utiliser pour l'utilisateur (il "décrit" le plugin à utilsier dans la conf de sa commande? On se base sur une reconnaissance de la commande en expression régulière?)

        C'est vrais, je ne vois pas non plus de moyen élégant pour substituer l'exécution des plugins connus/réimplémentés par une version ad hoc...
        - Soit, comme tu dit, faire la substitution lorsqu'on reconnait un nom de plugin en arg d'une check_command... mais le parsing, berk
        - Soit de façon déclarative (eg. "check_command check_tcp_shinken"). Moindre suprise, mais divergence avec une conf nagios brute.
        - Soit de façon déclarative, dans un fichier de conf distinct et propre à shinken (genre shinken-specific.cfg), surchargeant la définition des plugins classiques. La aussi, ca fait une nouvelle divergence avec la conf nagios brute.
        - Soit en fournissant un exécutable effectif (/usr/bin/check_tcp), qui au lieu d'effectuer le check lui-même, se contente de donner l'ordre de le faire au poller en charge des sockets, et retourne un code "maison" (qui signifierai : je n'ai pas le résultat, attends que le poller te le donne) (et/ou effectuerai le check lui même si et seulement si il n'a pas réussi à déléguer le check à un poller). Mais on ne s'affranchit alors pas de la surcharge inutile des fork()/exec()/popen() & reap, et puis c'est tarabiscoté ;)

        Rien de totalement naturel et clean, effectivement.

        - Le fait de dédier des pollers je ne suis pas sûr, car un poller pourrait avoir plusieurs types de workers

        Effectivement, j'avais cru que les pollers se chargeaient de lancer les actions (pas vu le worker.py).

        Désolé d'amener la discussion sur ces petits détails ; shinken semble déjà un super progrès par rapport à l'architecture de nagios :). La possibilité de faire tourner plein de checks classiques légers (tcp, http, udp, icmp) a intervalles très fréquents sans saturer le serveur de monitoring est peut-être un besoin plus perso qu'autre chose (mon serveur de monitoring fait tourner plein de trucs gourmands en plus de nagios, j'ai très peu de checks lourds en perl ou autre, et j'aimerai être avertis des problèmes plus vite qu'actuellement ...).
        • [^] # Re: questions (réutilisations, multiplexage, compatibilité)

          Posté par  (site web personnel) . Évalué à 1.

          En fait jusqu'à il ya une bonne grosse semaine, un poller était constitué de N workers qui sont un Poll de process pour Poller. Chacun lançait un et un seul check à la fois. Il "pollait" (oui ça fait beaucoup de poll ;) ) régulièrement la sonde lancée pour voir si elle était en vie.
          Le problème c'est que Python ça consomme un peu de RAM (non non, c'est vrai). Donc pour avoir 200 sondes en parallèles, il fallait 200 workers de 10Mo chacun. Ca commence à faire mal.

          C'est pourquoi j'ai diminué le nombre de worker, mais chacun peu lancer un certain nombre de sondes (par défaut 256, mais c'est configurable et surtotu limité par la limite sur le nombre de fichiers ouverts en même temps sur ton système). Il lance puis va poller régulièrement de la même manière chaque sonde. C'est un peu ce que tu proposes justement :)


          Pour le bypass du exec, je pense que le "moins pire" serait de déterminer au niveau du scheduler quel "plugin" utiliser suivant la tête (regexp) de la commande (ou bien si c'est direct dans le check_command, mais bon...). Il place l'info dans le check à effectuer, et le poller le fait gentiment. Si pas d'info de plugin, il exec().

          Ici le "plugin" est une sorte d'addon pour les daemons en gros. Pour l'instant seul celui qui récolte les informations en utilise, mais à terme d'autres vont en avoir :)
  • # Vachement gore

    Posté par  (site web personnel) . Évalué à 2.

    J'ai relu plusieurs fois les documentations (mail, wiki, ...), je suis toujours pas certain d'avoir bien tout compris.

    Mais j'ai quand même remarqué un truc bien dommage : garder les fichiers de configurations originaux. Tant qu'à réécrire nagios, autant attaquer le problème à la racine. Je suis totalement d'accord que de garder la rétro-compatibilité est intéressant pour rendre les migrations moins douloureuses, mais dans ce cas je penses que c'est une erreur.
    Les fichiers de configurations deviennent, à mon goût, ingérable rapidement (avec peu de hosts, services, ...), revoir ce point aurait été intéressant. Ces fichiers restes des fichiers qui contiennent énormément d'information et de garder des fichiers plats rend l'accès à cette information difficile. L'utilisation d'une base de donnée pour ça aurait été un vrai plus, mysql ou mieux un annuaire. De plus on aurait pu éliminer le "single point of failure" qui reste l'"arbitrer".

    Ensuite il me semble qu'il y a sur-découpage des tâches. Je penses que le découpage schedulers/pollers est superflu. Ces deux éléments auraient pu être fusionner sans, à mon avis, trop impacter les performances.

    Je dirais aussi que l'ensemble à l'air énormément complexe et effrayant, il y a plein de services qui sont nécessaire et chacun fait qu'un partie du travail. Un service indique l'action à faire, cette action est récupérée par un service qui fait l'action, le résultat est récupérer et stocker par un service et un autre service intervient pour faire les notifications. Il y a encore le service qui lit et transmet la configuration.

    Ce que je me dis c'est qu'avec un système aussi complexe il faudrait peut-être un nagios pour surveiller que tous les services nécessaires à shinken tourne. C'est un peu l'impression que j'ai à lecture des documents.

    Sinon joli travail quand même.

    "It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell

    • [^] # Re: Vachement gore

      Posté par  . Évalué à 4.

      Les fichiers de configuration de nagios sont, à mon goût, un avantage plus qu'un pb. Un fichier texte, ça se génère facilement, ça se lit bien, ça se partage bien, ça rentre dans un git ou équivalent pr gérer l'historique. Faire l'équivalent dans une base de données, avec notamment la gestion des héritages, me semble très complexe mais je peux me tromper.

      Le seul reproche que je ferais à nagios concernant les fichiers de configuration est de réussir à sortir simplement tous les paramètres de configuration d'un host ou d'un service. En effet, avec l'héritage, on est pas toujours certain du résultat et l'interface web n'aide pas.
      • [^] # Re: Vachement gore

        Posté par  (site web personnel) . Évalué à 4.

        Les fichiers de configuration de nagios sont, à mon goût, un avantage plus qu'un pb. Un fichier texte, ça se génère facilement, ça se lit bien, ça se partage bien, ça rentre dans un git ou équivalent pr gérer l'historique.

        Oui, il y a des avantages aux fichiers textes. Mais au bout d'un moment il faut se dire qu'on duplique beaucoup trop les données sans gagner en haute-disponibilité. Je penses qu'en utilisant un système d'annuaire LDAP on peut facilement avoir :
        - L'inventaire matériel
        - Le serveur DNS
        - DHCP
        - Les services nagios à contrôler (donc la liste des services par machine)
        - Les services ont des comptes utilisateurs, on uniformise donc les uid et gid à travers tout le parc
        - ...

        Je me rends compte que je passes de plus en plus de temps à faire des scripts qui vont pomper les informations dans le LDAP pour nourrir les différents services parce qu'au final ont a tout dans l'annuaire.
        Avec le LDAP on a de la haute-disponibilité facilement, de la délégation (dans le cas des sites, ça se fonctionnerai très bien), ...
        Par contre gérer l'historique c'est plus délicat, mais on a déjà les sauvegardes régulières qui font une sorte d'historique mais ça pourrait être mieux.

        Faire l'équivalent dans une base de données, avec notamment la gestion des héritages, me semble très complexe mais je peux me tromper.

        Un annuaire LDAP se prête bien à ça à mon avis.

        "It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell

        • [^] # Re: Vachement gore

          Posté par  . Évalué à 2.

          Nous utilisons Nagios dans notre entreprise et c'est vrai que la configuration imposée par Nagios est assez horrible. Pour environ 1000 services, nous avions plus de 10 000 lignes de configuration !
          C'est pourquoi, j'avais réfléchi à l'époque à un système pour simplifier la configuration et j'ai fini par développé un générateur de configuration pour Nagios. L'idée est de prendre un fichier XML en entrée et de sortir une config pour nagios.

          L'avantage de mon fichier est l'ajout d'une notion assez puissante : les listes de services. En gros, je créé des listes de services qui contiennent plusieurs services, puis j'utilise ces listes dans la déclaration des "hosts". Comme nous avons généralement les mêmes profiles de serveurs, la définition d'une liste de service par profile de serveur est très pratique.
          J'ai tout de même laissé la possibilité de redéfinir au sein de chaque "host" les services qu'il contient de manière individuel.
          Ensuite, pour la génération c'est pareil, je peux ne générer la conf que pour une partie des serveurs ou des services.

          Grâce à cela, nous sommes passé de 10 000 lignes de conf à environ 2 000. Et encore, dans ces 2 000 lignes, il y en a une grande partie qui ne bougent jamais.

          Je partage donc l'idée de reféfinir la configuration de Nagios si tu te lance dans un projet comme celui-ci et je pense qu'intégrer la notion de "profiles" serait une bonne chose.

          Chose amusante, le générateur de configuration est lui aussi en python :)
          • [^] # Re: Vachement gore

            Posté par  (site web personnel) . Évalué à 0.

            XML

            Aïe.

            "It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell

          • [^] # Re: Vachement gore

            Posté par  (site web personnel) . Évalué à 3.

            Pourquoi avoir pris du verbeux XML ?
            A moins que tu n'aie un éditeur ad-hoc qui te fasse une interface graphique...
            Perso, pour un fichier à éditer à la main, je préfère de loin des choses comme yaml, ou encore carrément des sources Python en mettant en place quelques classes de wrapping pour alléger la saisie.

            M'enfin, les goûts et les couleurs.

            Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN

            • [^] # Re: Vachement gore

              Posté par  . Évalué à 6.

              A l'époque où l'outil a été créé, le XML était très en vogue et les mêmes qui disent "Aïe" dès qu'on parle de XML auraient approuvés à l'époque en disant "si tu veux un truc portable et simple, choisis du XML".
              J'avais aussi à l'idée de faire une interface graphique à mon outil qui aurait pu modifier le XML facilement. Encore une fois à l'époque c'était un choix pertinent.

              En tout cas, on peut débattre très longtemps sur le choix d'un format de fichier, mais je préfère largement voir ça :

              <host name="monserveur" services-list="unix-www" ip="X.X.X.X" />

              Plutôt que ça :

              define host {
              address X.X.X.X
              host_name monserveur
              alias monserveur

              use generic-host
              }

              Pas sûr qu'en YAML ça soit mieux.

              Enfin je préfère le choix d'un fichier de conf sur fichier plutôt que d'une conf en base ou par du LDAP qui oblige à installer des outils tiers et à maintenir des services.
              Le fichier, pour de la configuration, c'est bien. Ca se lit facilement, ça se modifie facilement, ça se partage facilement avec du NFS, ça se backup facilement.
              • [^] # Re: Vachement gore

                Posté par  (site web personnel) . Évalué à 3.

                Perso je fais de plus en plus de fichiers de config sous la forme de modules Python (valable pour des configs qui seront éditées par des programmeurs ou adminsys, moins bon pour du monsieur tout le monde car il y a une syntaxe a respecter plus sioux que du .ini par exemple - mais quelqu'un qui peut éditer du XML à la mano ne devrais pas avoir de problème avec des données en Python).

                Et en général ça donne, pour reprendre ton exemple:

                Une définition de classe, du genre:

                hosts_list = []
                class Host(object) ;
                ....def __init__(self,name,services_list,ip) :
                ........# ...
                ........hosts_list.append(self)

                (si c'est une config dans un outil que pour moi, ça va directement dans le fichier de config, si c'est destiné à être plus réutilisé, ça va dans un module importé au début du fichier de config).

                Et après le fichier de config devient:
                Host("monserveur", "unix-www", "X.X.X.X")

                L'avantage que j'y vois, c'est que tu peux utiliser toutes les fonctionnalités de Python pour faciliter l'expression de la configuration et les contrôles. Tu peux définir des constantes globales (par exemple UNIX_WWW="unix-www") pour éviter les fautes de frappe, tu peux ajouter des méthodes, utiliser des listes, etc...
                Si tu organise bien les outils, ça fait quelque chose de bien lisible, facile à maintenir, et versionnable.
                Par exemple, si tu fairefaire des modèles réutilisables:
                class ServicesSet(object) :...

                servicemail = ServiceSet("imap","pop","simap","spop","smtp")
                Host("monserveur,"servicemail,"X.X.X.X")

                Ca a un inconvénient par rapport à XML: c'est pour Python et difficilement réutilisable si tu recodes ton application dans un autre langage. Encore que... rien n'empêche de réécrire un fichier XML à partir d'une telle description en Python.

                Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN

          • [^] # Re: Vachement gore

            Posté par  (site web personnel) . Évalué à 3.

            Ah non, pas de XML dans les fichiers de config !

            Et pas de base de données, a terme cela veut dire mélange des données et de la configuration et on accède à tout cela avec le même mot de passe. Déjà que Firefox me gonfle avec son SQLite !

            L'idée du LDAP est plus séduisante mais par exemple, mes fichiers nagios sont versionnés via svn et mis sur le serveur via cfengine. Donc on pourrait avoir un backend ldap qui génère les fichiers nagios en asynchrone.

            Le problème est de vouloir avoir des fichiers de conf "synchrone" qui deviennent donc des données et qu'ils ne deviennent vite modifiable que par des IHM graphique.
            • [^] # Re: Vachement gore

              Posté par  . Évalué à 1.

              Je plussois.

              Certe, les fichiers de configuration actuels de Nagios sont assez pénibles, notamment du fait de la mauvaise habitude qu'a Nagios de ne pas démarrer à la moindre faute de frappe plutôt que d'isoler l'élément fautif.

              Mais cela est toujours plus simple à gérer qu'une configuration en base de donnée justement parce que tant la génération que la vérification sont scriptable, et parce qu'il est possible de mettre en place un suivi des modifications.

              Gérant par ailleurs des annuaires LDAPs, on peut certe gérer les héritages, mais tant la gestion d'intégrité que la gestion de version sont assez vite pénible si l'on veut faire cela correctement, et au final pas plus complexe qu'un générateur de conf à partir de fichiers plats ;-).

              Quand aux bases SQL, pitié !!!
              Rien ne me gonfle plus que de devoir installer MySQL juste pour gérer 3 lignes de conf (parce que bon, pour les vraies données, quand on a pris gout à PostgreSQL, il n'y a pas photo (oui, je sais, encore 2h à tenir avant vendredi... ;-) )
              • [^] # Re: Vachement gore

                Posté par  . Évalué à 5.

                la mauvaise habitude qu'a Nagios de ne pas démarrer à la moindre faute de frappe plutôt que d'isoler l'élément fautif.

                Hihihi, pour ça il y a :
                $ nagios -v /etc/nagios/nagios.conf

                Article Quarante-Deux : Toute personne dépassant un kilomètre de haut doit quitter le Tribunal. -- Le Roi de Cœur

                • [^] # Re: Vachement gore

                  Posté par  . Évalué à 1.

                  Oui et non...
                  Je connais et j'utilise, mais je trouve que c'est tout sauf un modèle de souplesse.

                  En particulier, si pour une raison ou pour une autre le service redémarre avant que tu n'ais stabilisé la conf, tu peux dire au revoir à la totalité de ta supervision, et pas seulement à la partie que tu étais en train de mettre à jour. Certe, cela ne devrait pas arriver, mais entre la théorie et la pratique...
                  • [^] # Re: Vachement gore

                    Posté par  . Évalué à 3.

                    Je suis d'accord qu'il n'est pas toujours très souple, mais il permet de valider un minimum.

                    Après je pense qu'il faut être un peu rigoureux, et par exemple ne pas modifier la configuration en production : idéalement, il faut dupliquer la configuration dans /etc/nagios.test par exemple, et tester celle-ci. Une fois qu'elle est OK, il suffit d'un rsync pour l'appliquer et c'est terminé.

                    Article Quarante-Deux : Toute personne dépassant un kilomètre de haut doit quitter le Tribunal. -- Le Roi de Cœur

            • [^] # Re: Vachement gore

              Posté par  (site web personnel) . Évalué à 2.

              L'idée du LDAP est plus séduisante mais par exemple, mes fichiers nagios sont versionnés via svn et mis sur le serveur via cfengine. Donc on pourrait avoir un backend ldap qui génère les fichiers nagios en asynchrone.

              C'est ce que je souhaites faire dès que j'ai le temps.

              Le problème est de vouloir avoir des fichiers de conf "synchrone" qui deviennent donc des données et qu'ils ne deviennent vite modifiable que par des IHM graphique.

              Il y a ldapvi. Tu vois ton arbres ldap comme un grand fichier ldif et tu l'édites avec vi.

              "It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell

              • [^] # Re: Vachement gore

                Posté par  (site web personnel) . Évalué à 2.

                Et pourquoi on ne ferrait pas les deux? Après tout, la source de la configuration peut être une option non? L'administrateur est assez grand pour savoir ce qu'il veut. Certains on l'air d'aimer les conf en fichiers plats (je suis dedans), d'autres en annuaire ou même en base de données. Nagios s'est limité aux fichiers plats, mais pourquoi on ne lui permettrait pas de faire plus sans lâcher l'ancienne lecture de conf en fichier plat.
              • [^] # Re: Vachement gore

                Posté par  . Évalué à 2.

                Merci beaucoup pour ldapvi :)
          • [^] # Re: Vachement gore

            Posté par  (site web personnel) . Évalué à 2.

            >L'avantage de mon fichier est l'ajout d'une notion assez puissante : les listes de services. En gros, je créé des listes de services qui contiennent plusieurs services, puis j'utilise ces listes dans la déclaration des "hosts".

            Excuse moi, mais je ne vois pas l'avantage par rapport a la configuration "native": nagios te permet de le faire directement, certes dans l'autre sens (déclarer des services pour une liste de hosts) mais le résultat est le même.
    • [^] # Re: Vachement gore

      Posté par  (site web personnel) . Évalué à 1.

      Avec une bonne utilisation des techniques d'héritage de conf, c'est parfaitement gérable (et pas que les modèles, mais vraiment toutes les techniques d'héritages, notamment l'implicite).

      On pourrait penser à une possibiltié de conf en base, mais lâcher la possibilité d'avoir sa conf en fichier plat est dangereuse. C'est pratique un fichier plat :)

      Pour l'Arbiter oui, pour l'instant il est seul, mais je vais régler ça.

      Pour le découpage scheduler/poller j'y ais beaucoup pensé dernièrement. Pour de toute petites sondes rapides, on a plus de perf si on se passe de poller. En effet, 60% de perfs consommées les sont dans ... l'échange des checks (et des exports de status vers le broker) avec des sondes qui ne font rien (juste sleep). Mais avec des sondes lourdes (du perl codé à la va-vite par exemple) là c'est la fin, il te faut plusieurs pollers par scheduler. Donc lorsque la charge des sondes devient plus importante que celle du transfert, pouvoir augmenter le nombre de poller est intéressant.

      Ce découpage est violent par rapport à Nagios oui. Mais à mon goût il fallait séparer les rôles. C'est bien plus facile à maintenir comme ça je trouve. Ca fait un peu plus composants qui travaillent ensemble, et non pas un gros bloc monolithique.

      Sinon merci :)
  • # Enfin !

    Posté par  . Évalué à 2.

    Depuis que j'utilise Nagios j'ai toujours pensé que la meilleure chose à faire pour son évolution était de le réécrire entièrement à la mode Unix avec un programme pour chaque fonction mais que le fait bien avec des interfaces de communication bien définies. Ca facilite l'extensibilité (aussi bien en terme de fonctionnalités que de performances). Nagios a un historique énorme qui le rend désormais très difficile à faire évoluer. C'est fondamentalement une simple ordonnanceur de checks mais il mélange beaucoup trop de chose à ce rôle qui devraient être des addons. Il faut le modulariser, profiter de l'état de l'art en termes de programmation réseau asynchrone.

    Le fait de conserver la compatibilité avec Nagios pour la configuration et les checks n'est pas optimal (la configuration mériterait d'avoir une syntaxe plus claire, de pouvoir être générée à partir d'autres sources comme des inventaires sous forme d'annuaire ou de base de données ; certains checks mériteraient d'être intégrés au moins pour les cas de figure les plus communs comme le SNMP, un peu à la manière de Cacti) mais c'est le choix gagnant vu la base installée.

    En plus en Python ! Si tu persistes, j'aurai très envie d'y contribuer.
    • [^] # Re: Enfin !

      Posté par  (site web personnel) . Évalué à 3.

      Merci, toute aide sera acceptée avec plaisir :)
      • [^] # Re: Enfin !

        Posté par  . Évalué à 2.

        Est-ce qu'il est prévu d'ouvrir une mailing-list pour le développement de Shinken? Je n'ai pas pu trouver de références à une liste existante.
        • [^] # Re: Enfin !

          Posté par  (site web personnel) . Évalué à 5.

          Je suis en discussion sur la mailing list Nagios pour voir ce que l'on fait de shinken : branche de Nagios ou pas? Avant que ce soit tranché, je n'ouvre pas les hostilités de ce qui ressemblerait à un Fork. Si je peux faire accepter Shinken comme une branche de Nagios (genre long-term-dev) je préfère. Ça devrait se décanter rapidement je pense.
  • # Tentative de réponse à la question

    Posté par  . Évalué à 1.

    Nagios va-t-il quitter le C pour le Python?

    Remplacer C par Python, outch, tu bouscules les « core » développeurs là ;-) Si des idées de shinken pouvait être intégrées dans une future version, ce serait déjà pas mal, quel que soit le langage. L'utilisation massive de fichiers texte pour communiquer entre les différentes parties de nagios®, c'est robuste, pratique mais en 2009, on doit pouvoir faire mieux.

    Nagios® a déjà connu un fork : inciga. Nagios® XI™ sent le propriétaire. Ethan est absent des listes de diffusion. Tout cela n'est pas très réjouissant pour la communauté nagios® :-(

    Pour finir, la réponse à la question sera très probablement : non.
    • [^] # Re: Tentative de réponse à la question

      Posté par  (site web personnel) . Évalué à 2.

      Oui, c'est ce que je pense aussi. La réposne d'Ethan, si on en a une.., sera négative d'après ce qu'a dit Marc Powell. Il faut bien voir que je n'ai pas sorti Shinken comme ça du jour au lendemain concernant les core dev. Ceci fait un petit moment que je leur présente les idées avec une preuve à l'appui qu'elles fonctionnent. Je me suis fait envoyer sur les roses à chaque essaie.

      A un moment, il fallait faire un électrochoc, la mailing list me tendait les bras. Je pense qu'il est plus rapide de compléter Shinken que de reprendre ses idées et de les incorporer dans l'implémentation actuelle. J'ai peut être tord, mais qu'au moins les core dev prennent position et disent clairement ce qu'ils en pensent. S'ils disent qu'ils sont partant et motivés pour m'aider à prendre les idées et les incorporer au Nagios actuel, c'est parti.

      Je pense qu'Ethan est très orienté XI (close source) en ce moment. On ne le reverra pas sur la mailing avant un moment, et les annonces qui tendent à lui couper l'herbe sous le pied des modules close source qu'il voulaient pour XI ne vont pas lui plaire. Et c'est exactement ce qu'est cette annonce.
  • # réimplementation?

    Posté par  . Évalué à 0.

    Vu le parc grandissant de Nagios déjà installés, je pense que son maintien et son évolutions doivent continuer tels qu'ils existent aujourd'hui.

    Par contre, tous les défauts de Nagios, en terme de performances, de modularité et de gestion de configuration sont justifiés, mais remettent en cause l'architecture complète de Nagios.
    Et je ne parle pas même des rustines comme Centron&Co pour arriver à faire ce qu'un produit comme Nagios devrait savoir faire à la base.

    Je trouve qu'il faudrait plutôt représenter cela comme un nouveau concurrent, qui en reprendrait les qualités de Nagios sans les défauts. Rien n'empecherait d'ailleurs les dev Nagios de collaborer au deux. C'est le libre quoi!

    Quant au choix du Python, je pense qu'il est discutable, même s'il est évident qu'il faut un langage du XXIe siècle (indépendance OS, gestion mémoire, orientation objet, modularité, etc...).
    • [^] # Re: réimplementation?

      Posté par  (Mastodon) . Évalué à 3.

      La proposition de Jean Gabès est justement intelligente puisque d'après ce que j'en ai compris, Shinken ne remplace que le coeur de nagios et se base sur l'existant. Il sait lire les fichiers de conf de nagios non (je n'ai pas encore) ?

      Tout ce qui fait qu'une migration vers une solution de monitoring concurrente est difficile dans une entreprise, c'est quand des plugins doivent être réécris ou adaptés, que des access lists pour accéder à différentes machines sur le réseau doivent être modifiées, etc...hors la ça ne semble pas être le cas.

      Un projet à suivre, et à faire vivre donc.

      Question à l'auteur ? puisque les devs originaux sont peu perméables à vos propositions, un rapprochement avec d'autres acteurs comme op5 (les auteurs de merlin et ninja) ou icinga ne serait-il pas plus productif ?
      • [^] # Re: réimplementation?

        Posté par  (site web personnel) . Évalué à 2.

        Oui changer le coeur, et uniquement le coeur et bien l'objectif.

        Icinga je suis en pourparlé avec eux, mais ils ne semblent pas partant pour lâcher l'ancien code. dommage. OP5 je ne sais pas, un de leur dev est en train de tester Shinken pour voir.

        toute cette histoire risque fort de partir en Fork. Mon objectif est de ne pas m'éloigner trop des fichiers de conf de Nagios (bon un peu, j'ai de nouveaux objets à déclarer) pour qu'une fusion, si elle peu se faire "politiquement", se fasse sans trop de problèmes.
  • # Dommage

    Posté par  . Évalué à 1.

    Le C est un langage qui a encore beaucoup la cote et c'est compliqué de faire ce genre de changement d'un langage compilé en natif, avec des pointeurs, qui manipule directement la mémoire et qui est impératif vers un langage qui pourrait être son exact opposé. Ne serais-ce que parce que les développeurs ne sont pas habitués, n'ont pas envie, ne connaissent pas le nouveau langage.

    Mais je ne vois vraiment pas ce qui empêche l'intégration de ton projet et d'implémenter chaque fonctionnalité en C. Ça permettrait :

    d'avoir des changements petits et régulier plutôt que gros et en une fois
    valider point par point et dans l'ordre chacune de tes idées
    ne pas faire peur aux développeurs qui sont habitués à nagios et au C


    En tout cas je te souhaite tout le courage du monde pour la partie politique qui semble s'annoncer plus compliquée que la partie technique (et c'est dommage).

    Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

    • [^] # Re: Dommage

      Posté par  . Évalué à 4.

      Il y a aussi un autre aspect à prendre en compte : on n'a pas forcément envie d'avoir une dépendance à Python...
      • [^] # Re: Dommage

        Posté par  (site web personnel) . Évalué à 3.

        C'est vrai que cela ne m'a même pas effleuré l'esprit. Sur la totalité de mes serveurs il est installé de base, mais certains OS ne l'on pas en standard il est vrai.
        • [^] # Re: Dommage

          Posté par  . Évalué à 2.

          Cela dit, PsychoFox a raison : il n'est pas forcément nécessaire d'installer Python partout. :-) Je ne faisais que donner une raison possible (pas forcément une raison pertinente).
      • [^] # Re: Dommage

        Posté par  (Mastodon) . Évalué à 3.

        en même temps cette couche python n'a à être installée que sur le serveur de monitoring, et pas sur chaque serveur monitoré.

        Moi je dirais qu'il faut être pragmatique, si on veut vraiment quelque chose, il faut savoir aussi se donner les moyens et passer outre une bête histoire de dépendance.
    • [^] # Re: Dommage

      Posté par  (site web personnel) . Évalué à 2.

      C'était mon idée au début de ce projet : prototyper en Python, puis porter en C. Mais j'ai été un peu trop loin, le retour en Full C va être complexe et long. Et pour quel gain? Là on parle de développeurs qui ont peur de changer. Les anciens utilisateurs vont voir leur habitude légèrement changer (ils gardent la même conf, mais au lieu d'avoir un daemon, ils en ont plusieurs même si au jour le jouir, un seul les intéressent).

      Ce qui est complexe c'est l'intégration avec le projet existant. Mais le prix pour avoir un outil autrement plus flexible et apte à contrer ses concurrents est bien celui-ci. Si tu prends un Zenoss par exemple, ce n'est pas pour rien qu'il évolue très très vite.

      S'il faut passer par un nouvel outil indépendant c'est dommage mais j'irai. Je n'irai sur cette voie que si je n'ai pas d'autres solutions. Je suis prêt à des concessions, mais Nagios a suffisamment stagné. Il est temps de repartir sur de meilleurs bases pour affronter les problématiques de la supervision qui ne sont plus les mêmes qu'il y a 10ans.
      • [^] # Re: Dommage

        Posté par  . Évalué à 2.

        Selon comment se présente les choses (si les dev nagios ne veulent pas changer et si tu as du soutiens (j'entends par là des gens qui sont vraiment prête à s'investir)) il est possible que Shinken, après quelque mois de concurrence avec nagios, redonne de la vie à nagio et si le monde est bien fait une fusion dans quelques temps. Ça c'est déjà vu. En tout cas ne perd pas espoir c'est vraiment excellent ce que tu (as) fais.

        Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

Suivre le flux des commentaires

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