Dorian Fevrier's blog - Mot-clé - versionJe m’appelle FEVRIER Dorian, je suis infographiste 3D passionné par mon métier, l’informatique en général, l’internet, la programmation et l’évolution de tout ce petit monde. Vous trouverez sur ce blog des tutoriaux, mes coups de cœurs, avis, etc.2024-01-02T23:48:05+01:00FEVRIER Dorianurn:md5:695d9c73474c33ce3dab043823509c4bDotclearGeler les rigs en productionurn:md5:d346816af5966faf09e63db5c22d1bc92022-04-17T17:50:00+02:002023-06-09T12:01:49+02:00NarannInfographie 3D - Boulotpipelineproductionrigversion<p><img alt="dessin rig gele" class="media" src="https://www.fevrierdorian.com/blog/public/billets/2022_02_05_rig_gele/rig_gele_tn.png" style="float: left; margin: 0px 1em 1em 0px; width: 150px; height: 150px;" />Ce billet aurait pu être sous-titré : « Se tirer une balle dans le pied, mais rester debout ». :trollface:</p>
<p>Le gèle des versions du rig (et du reste, d’une façon générale) est une question qui revient régulièrement au cours d’une production. Nous allons voir en détail pourquoi est-ce qu’il s’agit d’un problème insoluble (bah ouais… Sinon on en parlerait plus… :baffed: ) et avec de nombreuses ramifications qui nécessitent d’être comprises si on souhaite contenir leurs effets.</p> <h3>Qu’entend-on par « geler une version » ?</h3>
<p>Un paradigme récurrent dans un pipeline d’animation est la capacité à pouvoir gérer des versions « nommées ». Par exemple, on aurait des versions :</p>
<ul>
<li>toto_rig.v1.mb</li>
<li>toto_rig.v2.mb</li>
<li>toto_rig.v3.mb</li>
</ul>
<p>Mais également :</p>
<ul>
<li>toto_rig.latest.mb</li>
<li>toto_rig.release.mb</li>
<li>toto_rig.FIXURGENTSHOT10.mb</li>
</ul>
<p>Les versions numérotées n’ont, en principe, pas vocation à être modifié. La « v3 » dans six mois est <em>supposé</em> être le même fichier que lors de sa publication. :perplex:</p>
<p>Ce n’est pas le cas des versions « nommées » :</p>
<ul>
<li>« latest » serait logiquement défini comme pointant systématiquement sur la dernière version.</li>
<li>« release » sur la version « à utiliser en production ».</li>
<li>« FIXURGENTSHOT10 » une version spéciale visant à résoudre un problème bien spécifique (ce n’est pas propre, mais un tel mécanisme permet cela).</li>
<li>etc.</li>
</ul>
<p>Ces versions « nommées » sont, en quelque sorte, des définitions de ce qu’est la version :</p>
<pre>
<code>latest -> v6
release -> v3
OMAGADSHOT10IZDOWN -> v4</code></pre>
<p>Notez que ces concepts peuvent exister, même si les choses ne sont pas formalisées de la sorte. Par exemple, si un studio n’a pas d’outils pour gérer des versions nommées, il peut le faire en sauvegardant systématiquement la dernière version du rig sur la « v1 » (le fichier <em>toto_rig.v1.mb</em>). Ainsi, la « v1 » peut être considéré comme la « latest » et on ne créera une « v2 » que si le rig change au point de casser les scènes d’animations ; par mise à jour des noms et/ou comportements des contrôleurs.</p>
<p>Dans tous les cas, ces versions (dites « nommées ») ont pour vocation d’être mises à jour et modifiées, sans imposer à ceux qui en dépendent de repointer dessus ; si votre scène pointe vers <em>toto_rig.latest.mb</em>, vous aurez toujours la dernière version. C’est une propriété qui permet d’éviter une gestion granulaire des versions quand la balance entre les conséquences négatives d’une mise à jour de version et le temps économisé par le fait que cette mise à jour soit automatique et instantanée penche en faveur du second.</p>
<p>Traduisez : Si toutes les scènes utilisent « latest » et qu’on choisit de republier (donc, de modifier « latest ») une version qui n’a aucune conséquence sur le comportement du rig (au-delà de corriger, le bug), alors c’est une option valable pour corriger rapidement un rig partout où il est utilisé. Idem pour « v1 », si on choisit de la ré-écraser.</p>
<p>Ce que j’essaye de dire, c’est qu’en pratique il n’est pas forcément nécessaire de pointer vers des versions nouvellement publiées ; quand on se débrouille bien, avoir une version « latest » en référence des scènes d’animation est possible.</p>
<p>Toutefois, il vient forcément un moment ou ce mécanisme, si économique, joue en votre défaveur.</p>
<p>Il arrive un moment où cette version, ici « latest », doit pointer vers une version qui ne changera plus avec le temps, la version numérotée vers laquelle elle pointe. On parle alors de « geler la version ».</p>
<h3>Pourquoi a-t-on besoins de geler les rigs ?</h3>
<p>Même si la réponse arrive d’elle-même en cours de production, il est intéressant de regarder comment les choses se passent avec un exemple concret.</p>
<p>Les parties exposées du rig (ses contrôleurs et attributs) doivent avoir un comportement identique d’une version à l’autre.</p>
<p>Par « comportement identique », j’entends : À valeurs d’attributs et de positions égales entre les deux versions le rig, le résultat dans la scène doit être le même ; la géométrie des objets ne doit pas changer.</p>
<p>En cours de production, cela nous donne :</p>
<p>Les scènes d’animation utilisent une version d’un rig (en référence ou non). Pour cet exemple : La « release » au moment de la génération de la scène, qui pointe disons, sur la « v1 ».</p>
<p>Plusieurs animateurs commencent à animer leurs plans et à les faire valider.</p>
<p>Viens ensuite le moment que tout <em>rigger</em> redoute : Le comportement de base du rig est problématique, et les animateurs passent beaucoup de temps à se battre contre celui-ci pour obtenir ce qu’ils veulent. Il faut modifier le rig pour le bien du reste de la production.</p>
<p>À ce stade, des animations ont été commencées avec un rig donné (la version « release », qui pointe sur la « v1 ») et certaines animations sont peut-être déjà validées.</p>
<p>Il faut créer une nouvelle version du rig en s’assurant que le comportement (le résultat de la pose pour des attributs donnés) ne changent pas. :jdicajdirien:</p>
<p>Plusieurs approches sont possibles suivant la nature le la-dite mise à jour :</p>
<h4>La nouvelle version ne change rien au comportement du rig.</h4>
<p>Ce sont souvent des mises à jour mineurs ; ajout d’un tag sur une shape pour le rendu ou l’export, modification des couleurs des vertices, parfois même une correction d’UV, etc.</p>
<p>Dans une telle situation, vous pouvez changer la version du rig sans que cela influe sur la géométrie et/ou l’animation. Vous pourriez presque écraser la version…</p>
<p>C’est le cas le plus simple à gérer, mais aussi le plus rare.</p>
<h4>Une nouvelle version de rig peut aussi se retrouver à ajouter des fonctionnalités.</h4>
<p>Ce cas est la voie à privilégier lors de la création d’une nouvelle version de rig. C’est sûrement pour cela que c’est, d’après moi, le cas le plus fréquent.</p>
<p>L’idée de base est que cette nouvelle version ne modifie pas le comportement du rig, sauf si on active des choses (qui sont désactivées par défaut). Il s’agit parfois d’ajouter des petits contrôleurs optionnels qui n’était pas présent avant, pour donner plus de contrôle à l’animation ; modifier l’épaisseur des bras, du cou, etc.</p>
<p>Cette méthode peut avoir le désavantage de surcharger le rig, mais est largement compensé par le fait qu’elle ne nécessite pas de discussion avec les équipes d’animation : Comme le comportement est désactivé par défaut, il ne change rien au résultat de ce qui est déjà en prod, et peut être déployé partout sans conséquences.</p>
<p>On a alors « augmenté » le rig. Quand on a une modification à faire en cours de production, il peut être intéressant de privilégier cette approche, quitte à ce qu’elle impose plus de tests.</p>
<p>Optionnel : Suivant la nature de la modification (et si votre pipeline le permet), vous pouvez activer l’attribut (le nouveau comportement) lors de la création des nouvelles scènes d’animation, ce qui permet aux animateurs de ne pas avoir à le faire. Ils vous feront des bisous, vous enverront des chocolats et inonderont votre profil LinkedIn de chants à votre gloire.</p>
<p><img alt="" class="media" src="https://www.fevrierdorian.com/blog/public/billets/2022_02_05_rig_gele/review_linkedin.png" style="margin: 0px auto; display: table; width: 615px; height: 145px;" />Dernier cas : La nouvelle version de rig casse l’animation.</p>
<p>Ça y est, on est dans le fond du problème : Le comportement des attributs a changé. Mettre cette version en production casserait l’animation. Le gel des versions du rig est votre seule sortie.</p>
<p>Arrivé ici, il est rare qu’on puisse s’en sortir sans conséquences désagréables, et c’est souvent la raison pour laquelle vous aurez à vous poser la question du gel des versions du rig en animation.</p>
<h3>Éviter le problème ?</h3>
<p>Avant d’aborder les stratégies pour minimiser l’impact d’une telle mise à jour, je dois aborder comment l’éviter.</p>
<p>Si vous lisez ce billet, il est possible que les quelques lignes qui suivent ne vous aident pas énormément, mais je suis obligé d’en parler. :redface:</p>
<p>La technique qui permet de diminuer drastiquement les problèmes de rig c’est déjà de les tester au maximum avant leur entrée en production. Si ce n’est pas systématique, les superviseurs anim ne sont pas forcément les plus amènes de remonter des problèmes pertinants. Du fait de leurs responsabilités, ils passeront plus de temps à organiser le travail des équipes, que le nez dans les scènes à animer des plans. Ils auront alors le réflexe de faire des remarques générales sur le comportement du rig. Il est donc important que des leads (ou personnes supposées devenir lead à la suite de la production) puissent également faire des retours. Ces derniers ayant une approche de support (de leurs graphistes), ils se poseront beaucoup plus la question de ce qui est fatiguant au quotidien, autant pour les équipes que pour eux.</p>
<p>Leur feu vert garantis à la production que le département de rig ne soit pas le seul à supporter la responsabilité d’un problème. Si le rig est considéré comme mauvais parce qu’on découvre un problème qui aurait pu être détecté par les animateurs avant le début de la production, le problème ne vient pas du rig, mais du manque de tests de l’animation. Un rigger n’est jamais un utilisateur de ses propres rigs, et malgré l’expérience, rien ne remplace un retour après plusieurs heures d’utilisation.</p>
<p>Un moyen très pratique de rentabiliser ce temps de travail/test est de mutualiser la fabrication des rigs (souvent via un auto-rig), afin qu’ils soient similaires et aient les mêmes options et comportement. Ce qui revient à doubler l’argument celons lequel les tests de rigs sont importants, car ils ne servent pas qu’à un seul rig, mais à tous les rigs à venir.</p>
<p>Mais c’est un autre sujet. :cayMal:</p>
<h3>Stratégies</h3>
<p>Il y a plusieurs façons d’éviter le drame d’une mise à jour de rig qui détruise l’animation. :neutral:</p>
<p>Si vos scènes d’animations pointent vers des versions nommées « release », ou « latest », il va falloir trouver un moyen de définir que ce n’est plus vraiment le cas.</p>
<p>Un gel de version a des implications importantes et c’est le choix de <em>quand</em> vous le faites qui est déterminant. Dis autrement : C’est le moment, dans votre pipeline, ou vous choisissez de geler une version qui va déterminer la façon dont vous allez vous y prendre.</p>
<p>Imaginons la situation suivante :</p>
<ul>
<li>Votre version « release » pointe sur la « v1 ».</li>
<li>Vous souhaitez publier un rig « v3 » que vous voulez passer en « release ».</li>
</ul>
<p>Notez qu’afin de ne pas complexifier mon exemple, je ne parlerais pas de la version « latest », mais la logique est similaire.</p>
<p>La méthode brute consiste à ouvrir toutes les scènes d’animation et changer la référence de « release » vers « v1 », puis de republier une scène de travail. Cette méthode vous garantit qu’un animateur ouvrant sa scène aura le même rig que ce qu’il avait au moment où il a arrêté son travail, même si « release » change entre-temps.</p>
<p>Cette méthode peut fonctionner dans des petits groupes, mais est difficile à mettre en place dans des grosses structures. :papi:</p>
<p>Une autre méthode consiste à stocker la version à laquelle correspondait la version « release » dans chaque publication. En gros, vous laissez la version d’animation pointer vers « release », mais vous mettez, en métadonnées de la version de la scène d’animation, la version vers laquelle « release » pointe. Ainsi, après ouverture de la scène avant export de l’Alembic vous forcerez la version du rig à utiliser.</p>
<p>Ceci a les effets suivants :</p>
<ul>
<li>L’Alembic exporté est garanti d’utiliser la version du rig qu’avait l’animateur au moment de sa publication.</li>
<li>Les scènes d’animations vont casser au moment de l’ouverture, laissant l’animateur la capacité de corriger l’animation. Ou, via un petit outil, un moyen de repointer vers la « v1 », en dur.</li>
</ul>
<p>Cette méthode assume que le problème du rig est bénin à corriger pour l’animateur et que ce dernier va immédiatement voir le problème. Or il est tout à fait possible que :</p>
<ul>
<li>L’animateur, réouvre sa scène pour un correctif en fin (de timeline) d’animation.</li>
<li>Ne remarque pas que la mise à jour a cassé le mouvement en début d’animation.</li>
<li>Republie sa scène pointant vers la dernière version actuelle (« release » en « v3 »).</li>
</ul>
<p>Ceci qui aura pour effet de publier, en métadonnée, le numéro de la version qui ne fonctionne pas en début d’animation (« v3 ») et de propager le problème dans l’Alembic.</p>
<p>Quand je vous disais qu’il n’y a aucune solution miracle… :vomit:</p>
<p>Voici ma solution, imparfaite, qui semble fonctionner « en pratique » :</p>
<ul>
<li>Le rig doit savoir quand une version cassera l’animation/le comportement de la précédente.</li>
<li>Le rig peut livrer sur n’importe quelle version (il n’est pas obligé de systématiquement publier une version <em>v+1</em>, mais peut écraser une version existante).</li>
<li>Les scènes d’animation pointent vers des versions absolues ; <em>v1</em>, <em>v2</em>, etc.</li>
<li>Les nouvelles scènes d’animation pointent vers la dernière version du rig au moment de leur création.</li>
</ul>
<p>Avec cette approche, c’est le rig qui est responsable de ce qu’il livre et de quand il choisit de faire monter une version.</p>
<p>Comme je le disais, ce système est imparfait, car il oblige une organisation plus fine du rig : Ce dernier peut être amené à faire un correctif non-destructif sur une <em>v1</em>, alors qu’on est sur une <em>v4</em> depuis des mois, d’où l’importance de votre pipeline à stocker et exposer facilement aux graphistes les dépendances de fichiers.</p>
<p>Dans tous les cas, ce système est loin d’être parfait. Certains pipelines sont conceptuellement incapables de réécrire sur une version au fil de temps. C’est au cas par cas.</p>
<h3>Le gel des versions, un problème plus vaste</h3>
<p>Vous l’aurez deviné, la problématique du gel de versions est un problème très vaste qui n’a aucune solution miracle :</p>
<ul>
<li>Modélisation : Peut-on republier une version d’un objet quand des plans sont déjà commencés avec, et sont calé de façon très fine ?</li>
<li>Décors : Peut-on republier une version d’un décor en déplaçant des objets qui <em>normalement</em> ne sont pas supposés être modifié par l’animation ?</li>
<li>Rendu : Est-ce que je gèle les versions de tout ce que j’ai en entré (c’est une bonne pratique) et si oui, quand ? En check assemblage ? À la preview ? Après la preview ? Et comment gérer les mises à jours parfois nécessaires ?</li>
</ul>
<p>Chaque département a ses propres logiques qui va dépendre de l’organisation du studio et de son pipeline qui tentent de trouver un équilibre entre la flexibilité et la granularité de la fabrication.</p>
<p>J’espère que ces lignes vous auront ouvert à la complexité de ce problème et vous aideront à proposer des solutions à vos équipes. J’ai mis énormément de temps à sortir ce billet, car comme vous vous en êtes rendu compte, les embranchements sont importants, mais il me semble que c’est le b.-a.-ba. d’un rigger que de gérer (c.à.d., limiter) ce genre de situations.</p>
<p style="text-align: center;">:marioCours:</p>La ferme de rendu (seconde partie) : Les jobsurn:md5:4087ae2ba44dd0f1c4a520ba193b1c972020-05-16T17:48:00+02:002020-05-21T12:33:43+02:00NarannInfographie 3D - Boulotfrjobrenderfarmversion<p>Dans la <a href="https://www.fevrierdorian.com/blog/post/2018/08/18/La-ferme-de-rendu-premi%C3%A8re-partie-Les-jobs" hreflang="fr">première partie</a>, nous avons abordé les différents jobs qu’on peut retrouver sur une ferme de calcul. Ici nous allons parler de certains aspects tel que la notion de <em>prédiction</em> de données, relation aux versions, gestion du temps de chargement des scènes et des versions des logiciels et plugins.</p> <h3>Prédiction des données</h3>
<p>Si vous ne deviez retenir qu’un point de ce billet ce serait celui-là ! :hehe:</p>
<p>Pas forcément connu, ce concept me semble crucial pour gérer les ressources de sa ferme correctement.</p>
<p>Le principe est de savoir exactement quelles données une chaîne de jobs va produire avant de générer les-dites données. Avant de vous expliquer ce que c’est, on va imaginer une gestion de ferme de calcul sans ce principe.</p>
<p><img alt="dessin_prediction" class="media" src="https://www.fevrierdorian.com/blog/public/billets/2020_05_16_render_farm/prediction.png" style="margin: 0px auto; display: table; width: 490px; height: 400px;" /></p>
<p>Si vous débutez en gestion de ferme, vous aurez tendance à exécuter des gros scripts qui s’occupent de tout faire à la volée, sans vraiment savoir sur quoi ils vont tomber :</p>
<ul>
<li>Ouvrir la scène d’animation Maya.</li>
<li>Choper des trucs dedans (persos, props, etc.).</li>
<li>Créer des versions pour les trucs qu’on va exporter en fichiers Alembic.</li>
<li>Exporter les Alembic.</li>
<li>Créer des versions pour les trucs qu’on va exporter en fichiers Yeti.</li>
<li>Exporter les poils Yeti.</li>
</ul>
<p>Dans le cas de Guerilla :</p>
<ul>
<li>Ouvrir le projet Guerilla.</li>
<li>Choper les trucs dedans (Passe de rendu, AOV, etc.).</li>
<li>Exporter des RIB.</li>
<li>Rendre les RIB.</li>
</ul>
<p>Bim ! Comme ça, d’un coup. :grenadelauncher:</p>
<p>Quand tu as trois personnages légers, c’est cool et plutôt rapide, mais le gros souci de cette méthode c’est que la difficulté à gérer vos jobs augmentera de façon exponentielle au fil de la montée en complexité de vos scènes. Bah oui, si à chaque exécution du job ça recrée des versions, tu vas le sentir passer l’export qui plante et que tu dois relancer dix fois…</p>
<p>Vous l’aurez compris, c’est moisi. Mais qu’est-ce qu’on entend par « gérer vos jobs » ?</p>
<p>Déjà leur utilisation au quotidien : Plus un job est lourd et fait plein de choses, moins il est facile pour les équipes de savoir ce qui est sorti et ce qui ne l’est pas. Sans compter que la moindre chose qui pourrait faire planter le job l’oblige à recommencer entièrement (Et nous savons tous que c’est la <em>dernière</em> partie du job d’export du plan le plus long du projet qui plante, toujours…).</p>
<p>Ensuite le test par les TDs. La facilité à tester un job permet de le développer rapidement (mais ça on s’en fout, parce qu’on sait tous qu’un <em>vrai</em> TD ça fait des cubes et des sphères) et surtout, de le déboguer <s>rapidement</s> moins lentement (Et ça, on s’en fout pas…).</p>
<p>« C’est plus facile de faire un gros script monolithique » diront certains, et ils auront raison, mais je répondrais que « c’est plus facile à déboguer » d’en faire plusieurs petits. Le temps économisé à l’écriture du code se paie par la lourdeur des jobs. En gros, la question n’est pas d’aller vite, mais d’aller loin (C’est beau… :petrus: ).</p>
<p>Le pire, c’est si vos jobs créent des jobs à la volée (création dynamique). Encore une fois, tout ceci est pratique (et parfois nécessaire), mais il n’est pas toujours simple de déboguer de tels jobs.</p>
<p>Je le crie sur tous les toits mais l’argument « c’est plus facile à déboguer » est vraiment fondamental dans un pipeline. En particulier sur les jobs de fermes qu’il est difficile de garder rigides tant ils tendent à évoluer au fil des projets en ouvrant tout et n’importe quoi ; scènes d’animateurs™, scène de rendu, versions des logiciels différentes suivant les projets, etc. Sans compter qu’il faut, pour tester, que la ferme puisse exécuter votre code à vous (La méthode la plus simple consistant à faire passer sa machine pour un <em>worker</em> de la ferme).</p>
<p>Bref, pour pouvoir développer, tester et déboguer des jobs efficacement, il faut qu’ils soient le plus légers et rapide possible (à démarrer et à s’exécuter) et ne fasse qu’une seule et unique chose. La capacité de mettre votre ferme à l’échelle avec des projets de plus en plus gros dépends de ça.</p>
<p>Si vous gardez ça à l’esprit quand vous structurez vos jobs, vous allez vite vous rendre compte que le meilleur (seul ?) moyen d’avoir des jobs précis et granulaires, c’est de savoir à l’avance ce qu’il y a dans vos scènes, c’est-a-dire au moment où vous générez le graphe de dépendance de jobs.</p>
<p>En effet, si vous savez <em>avant</em> d’ouvrir une scène d’animation ce qu’il y a dedans, vous allez pouvoir faire autant de job d’export qu’il y a de personnages (ou <em>prop</em>) et ainsi gagner en temps.</p>
<p>Si vous avez trois personnages avec, pour chaque personnage, un export Alembic et une simulation automatique de <em>cloth</em>, vous aurez une chaîne de six jobs :</p>
<pre>
toto_001_abc -> toto_001_auto_cloth
tata_001_abc -> tata_001_auto_cloth
tutu_001_abc -> tutu_001_auto_cloth</pre>
<p>Le petit malin du fond me fera remarquer qu’il suffit d’ouvrir la scène Maya et de générer la chaîne de job depuis cette dernière pour savoir ce qu’il y a à générer. Après lui avoir rappelé que les petits malins du fond dans son genre finissent seul, alcoolique et au chômage, je lui expliquerai qu’on a pas que ça à faire d’ouvrir des scènes Maya et que même si on le fait dans un job qui se charge d’ouvrir les scènes Maya pour générer les jobs, on ne sait pas, au moment où on génère ce fameux job ce qu’il va générer. En faisant ça, vous avez simplement décalé le problème. :reflechi:</p>
<p>Bref, pas le choix, il faut connaître à l’avance, au moment où on fait toute la chaîne de job.</p>
<p>Il y a plusieurs méthodes pour y arriver suivant votre pipeline. Voici quelques pistes :</p>
<ul>
<li>Écrire un fichier à côté de votre scène (<em>side car</em>) contenant les instances présentes dedans ; toto001, tata001, etc.</li>
<li>Sauvegarder les informations en métadonnées de votre version dans la base de donnée que vous utilisez.</li>
<li>Si vous utilisez un pipeline s’appuyant sur des notions de connexions et de nœud, vous pouvez faire un nouveau type de connexion.</li>
<li>etc.</li>
</ul>
<p>Ces méthodes ont en commun de s’exécuter au moment de la publication afin d’avoir les informations nécessaires à disposition.</p>
<p>Cela implique aussi que ces informations doivent être accessible et lu au moment de la création du graph de job.</p>
<h3>Le <em>versionning</em></h3>
<p><img alt="dessin_versioning" class="media" src="https://www.fevrierdorian.com/blog/public/billets/2020_05_16_render_farm/versioning.png" style="margin: 0px auto; display: table; width: 215px; height: 292px;" /></p>
<p>Comme je le disais, un des risques qu’il y a à relancer une chaîne de job non prédictible est de se retrouver avec autant de versions créées que de fois où la chaîne est relancé. Une manière d’éviter ça consiste à créer les versions au moment de la soumission du job. Ceci permet d’avoir une gestion <em>synchrone</em> des versions, mais c’est la ferme, <em>asynchrone</em> par nature, qui va les remplir, puis les « fermer ».</p>
<p>Un problème se pose toutefois rapidement : En effet, quand on crée une version, elle est souvent accessible immédiatement. Ainsi, si vous assemblez un plan dans la minute qui suit la publication d’un asset qui le compose (e.g. l’export d’une animation d’un personnage), le plan assemblé utilisera cette version, mais si la sauvegarde du fichier se fait en décalé (de façon asynchrone, par la ferme), vous risquez d’avoir des problèmes, car l’assembleur de scène ne comprendra pas pourquoi une version existe mais le fichier n’est pas présent et/ou invalide.</p>
<p>Une façon de résoudre ce problème passe par la possibilité d’activer ou de désactiver d’une version. Ainsi, une version crée mais non « fini » (le fichier n’est pas encore là), sera « désactivée » aux yeux du pipeline, et ne sera activé (et ses fichiers mis en lecture seule) qu’une fois la génération du fichier (export Alembic, rendu, playblast, etc.) terminé.</p>
<p>Toute version visant à être « remplis » sur la ferme est donc désactivée à sa création, et un job dédié s’occupe de l’activer quand la chaîne de job est terminé.</p>
<p>Dernier problème (promis) : Si on relance une chaîne de job qui s’est totalement terminé, et dont, implicitement, les fichiers sont « fermés » à la modification, il est donc nécessaire de les rouvrir. Une étape (un job) est donc également nécessaire <em>avant</em> la modification d’une version.</p>
<p>On a donc :</p>
<ul>
<li>Créations des versions : Localement, au moment de la soumission de la chaîne de job (synchrone).</li>
<li>Ouverture/modification/fermeture des versions : Sur la ferme, par chaque worker (asynchrone).</li>
</ul>
<p>Il n’est pas nécessaire de passer par un job dédié pour l’ouverture et la fermeture des versions, cela peut se faire directement dans le code qui s’exécute sur la ferme. À titre personnel, je préfère des jobs dédiés, car la modification d’une version peut nécessiter que deux jobs (ou plus) lui passe dessus.</p>
<p>J’appelle l’ensemble de cette approche « l’allocation de versions » : À un moment <em>t</em>, vous demandez au pipeline des « espaces » (ici, des versions) qui vont être modifié, plus tard, par différentes machines de la ferme qui s’occuperont ensuite de les libérer. Si aucune erreur ne s’est produite lors de l’exécution de votre chaîne de job, les versions créées par la ferme sont remplis, disponibles pour le reste du pipeline et les permissions y sont correctement appliquées.</p>
<h3>Durée d’ouverture des scènes d’animation</h3>
<p>Je vous invite à garder à l’esprit que la durée d’ouverture des scènes d’animation peut être importante. Certains plans de <em>certains</em> projets sur lesquelles j’ai pu travailler mettaient quasiment 30 minutes à s’ouvrir. C’est souvent un problème à résoudre en amont (car c’est l’animateur qui perd du temps), mais comme souvent en production, ce n’est pas possible pour le projet en cours. Si vous exportez vos Alembics directement depuis la scène d’animation, ça veut dire qu’une mise à jour du <em>rig</em> d’un seul personnage nécessite la réouverture complète de la scène que ce soit par l’animateur ou un job de ferme, c’est du gâchis.</p>
<p><img alt="dessin_toutessoukontrolle" class="media" src="https://www.fevrierdorian.com/blog/public/billets/2020_05_16_render_farm/toutessoukontrolle.png" style="margin: 0px auto; display: table; width: 640px; height: 400px;" /></p>
<p>Une méthode pour éviter ça consiste à n’exporter que les courbes d’animation et de reconstruire l’ensemble en partant d’une scène vide.</p>
<p>Il y a plusieurs façons d’exporter des courbes d’animation, je vous en donne deux, en vrac :</p>
<ul>
<li>Exporter les nœuds (principalement les courbes d’animations) seuls en format .mb/.ma ainsi qu’un fichier texte avec les informations de reconnexions de ces nœuds. Cette méthode permet de conserver l’animation originale de Maya, mais nécessite pas mal de développement et ne résout pas le problème des contraintes.</li>
<li>Exporter un fichier ATOM, ce dernier comprenant une version baké des courbes d’animations. C’est ma méthode préférée, car elle permet de n’importer qu’un range précis d’une animation sur un autre range, permettant ainsi de reconstruire une animation en y ajoutant un <em>preroll</em> automatique pour nos amis du cloth. En passant par le bake, cette méthode résout le problème des contraintes qui ne sont plus utiles.</li>
</ul>
<p>Une fois les courbes exportées, vous n’avez plus qu’à ouvrir une scène vide, importer la dernière version du <em>rig</em> et y coller vos courbes pour exporter l’Alembic.</p>
<p>Ces mécanismes, qui, mine de rien, ajoutent des étapes d’export, permettent de gérer des exports complexes car chaque asset est exporté individuellement.</p>
<h3>Un dossier temporaire pour votre ferme</h3>
<p>Il peut être pratique de disposer la ferme d’un système de fichier temporaire partagé par tous les <em>worker</em>. L’avantage immédiat étant de ne plus s’embêter avec des problématiques de pipeline et de version. Vous créez un dossier /farm/tmp/mon_id/ et vous y mettez ce que vous voulez. Les différents jobs liront et écriront à l’intérieur, avec, éventuellement, un job de nettoyage en fin de chaîne.</p>
<p>Un exemple d’utilisation que j’ai souvent observé tourne autour de l’assemblage de scènes :</p>
<ul>
<li>On exporte/assemble les scènes dans leur format de rendu (RIB, ass).</li>
<li>On les rend.</li>
<li>On sépare, parfois, les layers des images.</li>
<li>On supprime les fichiers de rendu ; RIB, ass, voir les images brutes qui ne sont plus utiles (sauf pour du débogage).</li>
</ul>
<p>On pourrait grossir cette liste d’étapes avec du précalcul de fichier (bake d’illumination, simulation et génération de poils) qui vient se faire <em>avant</em> le rendu. Bien que cela se fasse moins qu’il y a quelques années, le précalcul peut se révéler nécessaire pour rendre des plans qui sortent de l’ordinaire ; transitions bizarres, plans séquences, etc.</p>
<p>Les graphistes utilisant Houdini et ayant la responsabilité de plans complexes ainsi que les studios travaillant sur plusieurs projets de natures différentes (e.g. La publicité) s’appuient beaucoup sur ce système.</p>
<p>Plus un plan est complexe et spécifique, plus il est difficile de mettre en place un mécanisme de prédiction poussé. Le temps passé à généraliser une solution étant trop important et/ou le nombre de plan concerné étant trop faible.</p>
<p>Il y a un dernier cas où vous n’avez pas beaucoup le choix : Si la taille de votre ligne de commande est trop importante, vous devez sérialiser les arguments. Ça semble absurde, mais pour m’être déjà retrouvé dos au mur (une ligne de commande dont le nombre d’argument a augmenté au fil des semaines), écrire un JSON dans un dossier temporaire plutôt que d’avoir à repasser sur toute la gestion de la commande (on était en fin de production) peut vous sauver la mise.</p>
<p>Passer par un dossier partagé a le mérite de proposer une solution simple à comprendre pour tout le monde. On est clairement sur une approche artisanale de la ferme, tout en gardant une distinction claire entre ce qui est dans le pipeline et à l’extérieur.</p>
<p>Malgré ça, ne pas avoir de suivi granulaire des données générées par la ferme peut entraîner son lot de complication. Ainsi, une ferme multi-site devient un calvaire à gérer. Les dossiers temporaires n’étant pas au même endroit, soit vous faites un partage direct (ce qui implique une occupation continue de la bande passante), soit vous calez des jobs de synchro entre les jobs utilisant des machines de sites différents. Dans les deux cas, cela ajoute de la complexité à l’ensemble et il faut peser le pour et contre.</p>
<p>À titre personnel, j’ai pu remarquer que, dès lors qu’il faut synchroniser des choses, avoir un suivi précis est plus efficace : Gardez un suivi des choses à l’échelle du pipeline (asset, version, etc.) pour tout ce que vous pouvez anticiper et ne sortez la solution des fichiers temporaires de ferme que pour les exceptions.</p>
<p>D’un point de vue code, une petite API distribuée aux superviseurs leur évite d’avoir à gérer ça eux-mêmes : Une fonction qui crée le dossier temporaire, renvoi son chemin ainsi que le job chargé de supprimer de dossier en question est un bon début. Pour le nom du dossier temporaire généré par cette API, lui préfixer la date (2020_04_12) permet d’avoir rapidement un coup d’œil sur ce qui ne semble plus nécessaire.</p>
<p>Faites un suivi régulier de la taille de ces dossiers et impliquez les superviseurs qui l’utilisent, ils sont bien plus en mesure de savoir ce qui est nécessaire ou non.</p>
<p>Il va de soi qu’aucun autre script ne doit s’appuyer sur ce dossier. <em>Certains</em> pourraient avoir l’idée de s’en servir comme dossier d’échange dans le studio.</p>
<h3>Nettoyage des jobs</h3>
<p>On en a déjà un peu parlé, mais le nettoyage des jobs concerne plusieurs choses qui peuvent se faire à plusieurs moments du <em>cycle de vie</em> d’un job.</p>
<ul>
<li>Il y a le nettoyage qui se fait immédiatement après le job ou la chaîne de job. C’est celui qu’on fait naturellement quand le job est supposé avoir fini son travail (nettoyage des RIB).</li>
<li>L’autre est plus subtile et se fait au moment de la suppression du job du manager. En pratique, on supprime rarement le job, mais on procède à son archivage. Cela faisant, les fichiers de logs sont également supprimés du système de fichier.</li>
</ul>
<p>La plupart du temps, on aura un job dédié au nettoyage, mais certains jobs managers intègrent le concept de nettoyage en tant que paramètre du job. Cela peut prendre la forme de clef comme <em>clean_dir</em>, <em>clean_file</em>, <em>clean_files</em>, etc.</p>
<h3>Des jobs génériques, ou spécifique ?</h3>
<p>Au moment de l’écriture d’un job, une balance tend à apparaitre : Doit-on écrire un job qui fonctionnera pour tout type de tâche ? Ou doit-on écrire un job qui fonctionnera pour un besoin précis ? Doit-on gérer les choses de façon abstraite ou de façon concrète ? Ma réponse ne va pas énormément vous aider : Les deux mon capitaine !</p>
<p>Prenons un exemple : Vous souhaitez faire les jobs « d’export des personnages ». Exprimé de la sorte, c’est un besoin abstrait. En effet, « exporter un personnage » se fait, à priori, en plusieurs étapes :</p>
<ul>
<li>Exporter des courbes d’animation.</li>
<li>Exporter un ou plusieurs Alembics.</li>
<li>Calculer une ou plusieurs simulations de poils (cheveux, poils).</li>
<li>Baker un ou plusieurs systèmes de poils.</li>
<li>Calculer une, ou plusieurs simulations de vêtements.</li>
<li>Calculer et exporter des simulations au sol (zones de contact pour le FX).</li>
</ul>
<p>J’ai donné une liste aussi exhaustive que possible, mais il est évidant que peu de projets cochent toutes les cases et qu’il n’est pas forcément optimal de faire un export de personnage aussi granulaire que ça (tout dépend de votre budget).</p>
<p>La question de savoir si ont fait des jobs pour « exporter un personnage » ou « exporter un Alembic » se pose. Si on choisit de faire un job « d’export de personnages », vous vous rendrez vite compte qu’il doit être séparé en petits jobs. Ensuite, si on choisit de faire des jobs qui « exportent un Alembic », on risque de buter, plus loin, sur des problématiques <em>spécifiques</em> : Est-ce qu’on exporte un Alembic de la même façon pour un personnage que pour une simulation ? Dès lors, un besoin de faire un job qui « export un Alembic <em>FX</em> » apparaît et il est probable qu’il n’ait pas été anticipé. Dans le pire des cas, vous vous retrouvez avec un département FX complet à qui on a dit que les jobs « d’export d’Alembic » étaient près et qu’il pouvait commencer le travail.</p>
<p>Si tout ceci peut sembler relever du domaine académiques, c’est parce qu’il s’agit rarement de questions qui se posent en début de production, quand on met notre ferme en place, mais plutôt quand la nature de ce que fait votre ferme évolue (milieux de production ou entre deux saisons d’une série). Ces questions, mise de côté, agissent comme un ressort.</p>
<p>La raison pour laquelle j’insiste sur cette distinction, c’est pour que vous soyez en mesure de la « détecter » en production, au risque de perdre du temps en enchevêtrement de paradigmes et/ou discussion avec la production.</p>
<p>Quand des graphistes ou des superviseurs vous parleront, ils ne feront pas cette distinction. C’est vous le codeur, c’est votre travail de la faire et de l’expliquer. Dans notre exemple, si un superviseur pense qu’il va pouvoir exporter des Alembic de FX parce que vous lui avez fait un job d’export d’Alembic sans en définir correctement le contour, vous êtes en parti responsable de cette confusion. En gros, ne « pensez » pas les jobs suivant leur nom, mais suivant ce qu’ils font, et assurez-vous que vous n’êtes pas le seul.</p>
<p>On peut, légitimement, se demander s’il est utile d’avoir des jobs génériques qui font des choses dont la définition n’est pas (encore ?) clair aux yeux de la production. Quand un besoin est « ballant » (comprenez, on sait qu’on en a besoin, mais on ne sait pas si c’est la bonne façon de faire), il me semble que faire un job qui fait « le truc » est la solution.</p>
<h3>Gestion des différentes versions des logiciels sur la ferme</h3>
<p>Suivant la nature des projets que vous avez à sortir, il est fort probable que vous ayez à gérer différentes versions de logiciels et des plugins qui les compose.</p>
<p>Vous pouvez définir des versions « à la machine », mais cela vous prive de puissance de calcul, car vous risquez de ne pas pouvoir utiliser une machine au simple prétexte qu’elle n’a pas la bonne version de Maya d’installée.</p>
<p>On serait donc tenté d’avoir plusieurs versions d’un logiciel, disponible sur chaque machine. Dès lors qu’une machine rend disponible plusieurs versions d’un logiciel, vos jobs doivent pouvoir appeler la bonne version.</p>
<p>Les méthodes pour y arriver sont nombreuses aucune n’est parfaite et leur utilisation dépend beaucoup de l’organisation de votre studio (rien que ça). La plus naïve consiste à appeler l’exécutable d’un logiciel par un nom précis. Dans le cas de Maya, on aurait donc une ligne de commande :</p>
<pre>
<code class="language-bash">maya2019 -c "print 'toto'"</code></pre>
<p>J’ai quelque à priori vis-à-vis de cette méthode. Le principal étant la gestion des versions des plugins. En effet, si vous utilisez un plugin (e.g. Yeti pour Maya), il est probable que vous ayez à <em>glisser</em> de version en cours de production (vous commencez les nouveaux plans avec la nouvelle version, vous finissez les anciens plans avec l’ancienne).</p>
<p>Je rappelle l’évidence : Il est dangereux de changer de version d’un logiciel en cours de production. En revanche, certains bugs peuvent être tellement bloquants qu’ils remettent en question ce dogme. Il peut s’agir de problèmes corrigés dans une version mineure (2.5.0 -> 2.5.1), comme de problèmes plus graves qui remettent en cause l’utilisation de l’outil. C’est une situation qui peut apparaître quand on utilise un tout nouvel outil en production et qu’on réalise, trop tard, que ce qui était prévu de faire avec n’est pas possible à cause d’un bug corrigé dans une version majeure (2.5.0 -> 3.2.0).</p>
<p>À cela vient s’ajouter un dernier point, pratique, qui est le test : Vous êtes en 2.5.0 et que la version 2.5.1 corrige le problème, vous passez tout le plancher en 2.5.1. Plus tard, en production, un problème, différent mais qui semble lié apparait. Vous avez un doute : Est-ce que ce problème apparaissait en 2.5.0 ?</p>
<p>Et là on parle d’un seul plugin, mais certains logiciels sont amenés à faire tourner pas mal de plugins différents. Dès lors, vous voyez une matrice se dessiner : Version du logiciel/Version du plugin A/Version du plugin B/etc. Et si vous utilisez des plugins compilés « maison », c’est encore pire, car vous pouvez être amené à livrer une version plusieurs fois par jour.</p>
<p>Il est tout à fait possible de ne s’appuyer que sur le nom de l’exécutable dans la ligne de commande :</p>
<pre>
<code class="language-bash">maya2019-yeti2.5.0-rigNodeMaison3.6.5 -c "print 'toto'"
maya2019.sp1-yeti2.5.0-rigNodeMaison3.6.5 -c "print 'toto'"
maya2019.sp1-yeti2.5.1-rigNodeMaison3.6.4 -c "print 'toto'"
...</code></pre>
<p>Notez que <a alt="PeregrineLabs Ecosystem github repository" href="https://github.com/PeregrineLabs/Ecosystem">Ecosystem</a> de PeregrinLabs fonctionne un peu suivant ce principe, mais je suis dubitatif quant à la taille de tels lignes de commandes quand vos graphistes deviennent mordu de plugins maisons. Je lui préfère une approche via variables d’environnement :</p>
<pre>
<code class="language-bash">export MYENV_MAYA_VERSION=2019.sp1;
export MYENV_YETI_VERSION=2.5.0;
export MYENV_RIGNODEMAISON_VERSION=3.6.5;
myenv -- maya -c "print 'toto'"</code></pre>
<p>Ici, <em>myenv</em> est un exécutable qui consomme les variables d’environnement commençant par <em>MYENV_</em> pour en faire des environnements dans lequel la commande qui suit « -- » est exécuté.</p>
<p>Bien entendu, les commandes <em>export</em> ne sont pas exécutées par vous, mais envoyé avec le job au moment de la soumission :</p>
<pre>
<code class="language-python">my_env = {'MYENV_MAYA_VERSION': '2019.sp1',
'MYENV_YETI_VERSION': '2.5.0',
'MYENV_RIGNODEMAISON_VERSION': '3.6.5'}
job = {'command': 'myenv -- maya -c "print \'toto\'",
'env': my_env}
farm.submit(job)</code></pre>
<p>Je suis un adepte de cette méthode.</p>
<p>Arrivé ici, je ne peux pas ne pas vous parler de <a alt="Rez github repository" href="https://github.com/nerdvegas/rez">Rez</a>. Je ne l’ai jamais utilisé personnellement, mais j’en ai entendu beaucoup de bien.</p>
<p>Rez résout des environnements via un système de dépendance. La charge cognitive initiale due à son apprentissage est importante, mais il est considéré comme une brique solide d’un pipeline avec une bonne <a alt="Documentation de Rez" href="https://github.com/nerdvegas/rez/wiki">documentation</a>.</p>
<p>La gestion des environnements étant souvent central dans un studio, vous pouvez aussi être tenté d’écrire le vôtre. Ce n’est pas particulièrement difficile à faire (pour tout vous dire, je n’ai encore jamais fait autrement), mais c’est une maintenance en continue. L’avantage étant que ce gestionnaire s’en tiendra à faire <em>exactement</em> ce que vous voudrez, pas plus, pas moins.</p>
<p>Si vous choisissez de le faire en Python, gardez le module aussi isolé et indépendant que possible. S’il vous vient à l’idée de questionner la BDD sur les métadonnées d’un shot pour résoudre un environnement, vous fonctionnez peut-être à l’envers (et si vraiment vous n’avez pas le choix, passez par une variable d’environnement : MYENV_SHOT_NUMBER)</p>
<h3>Data mining</h3>
<p>C’est le sujet sexy du moment et il est difficile d’avoir un avis tranché tant le secteur « tâtonne » à déterminer si le temps de compréhension et d’interprétation des données justifie d’y dépenser de l’énergie.</p>
<p>La première erreur consisterait à utiliser des données de ferme pour répondre à des questions de production : Si vous voulez répondre à des questions de production (e.g. nombre de validation par semaine), analysez des données de production (e.g. Shotgun). En revanche il est très utile de comparer les données de ferme à des données de production, cette dernière influençant la première. Vous serez peut-être en mesure d’y trouver des corrélations intéressantes, voir, surprenantes.</p>
<p>Pour l’anecdote, sur un projet, on avait pu remarquer que plus on se rapproche de la fin du projet, plus le temps de rendu <em>moyen</em> par image diminuait, en parallèle de quelques plans qui voyaient leur temps de rendu augmenter drastiquement. On avait mis ça sur le compte du fait que, la <em>deadline</em> arrivant, les graphistes ne prenaient plus le risque d’augmenter les temps de rendu et forçait sur l’optimisation de leurs scènes pour éviter de les voir « revenir » de la ferme au motif d’un temps de rendu trop long, ce qui, par effet de débordement, diminuait la qualité générale. La pression qui peut apparaître en fin de production peut entraîner, à tous les niveaux de la hiérarchie, une diminution du zèle (que je crois) nécessaire à la sortie de belles images. Les superviseurs et les <em>leads</em> doivent alors se focaliser sur ce qui est essentiel à la qualité d’un plan. C’est d’ailleurs le moment ou le ratio qualité/temps de travail graphiste est le meilleur, les gens ayant pris l’habitude des erreurs à ne surtout pas faire et de ce qui plaît. Quant aux quelques rendus qui explosent ? C’est les laissés pour compte, les rendus qui ont un problème, mais qu’on a plus le temps de régler.</p>
<p>Mais je digresse…</p>
<p>Les données de ferme ne répondront qu’à des questions de gestion de ferme : Alimentation, charge, licence. Ces données sont très utiles pour élaborer correctement des budgets par juxtaposition. Il est, en effet, plus simple de définir les besoins d’une production quand on a déjà une base chiffrée de l’utilisation d’une ferme sur un projet.</p>
<h3>Avoir des <em>logs</em> explicites</h3>
<p>Isoler un job pour reproduire un bogue prend du temps, et ce, malgré le travail effectué pour simplifier cette démarche. Quand un problème apparaît, vous aurez rapidement le réflexe de lire le <em>log</em> du-dis job en le comparant avec les appels à <em>print()</em> de votre code. En faisant cela vous aurez rapidement une idée de <strong>où</strong> votre script a planté. Et si vous avez affiché les valeurs des différentes variables, vous serez potentiellement en mesure de reproduire le problème avec une simple commande.</p>
<p>Il est donc important d’avoir des <em>logs</em> descriptif et suffisamment claires. Il ne faut pas hésiter à être verbeux, car si vous n’affichez que quelques informations, vous risquez de vous retrouver face à un gros bloc de code dans lequel le problème apparaît, sans que vous puissiez être en mesure de déterminer ce qu’il fait.</p>
<p>Je vous invite également à ajouter des informations de temps afin de déceler les écarts qui peuvent se produire entre deux lignes :</p>
<pre>
<code>2018-01-22 10:53:00,500|CMD |INFO|...
2018-01-22 10:53:01,589|CMD |INFO|...
2018-01-22 10:53:01,589|CMD |INFO|...
2018-01-22 10:53:02,351|MAYA|INFO|...
2018-01-22 10:53:02,351|MAYA|INFO|...
2018-01-22 10:53:02,605|MAYA|WARN|...
2018-01-22 10:53:02,605|MAYA|INFO|...</code></pre>
<h3>Conclusion</h3>
<p>J’aurais pu aborder le cloud, mais le sujet est très large et je ne pense pas avoir assez d’expérience pour donner des conseils pertinents.</p>
<p>J’espère que ces deux billets vous auront plus.</p>
<p>À bientôt !</p>
<center>:marioCours:</center>1and1, Dotclear et Piwik: Modifier la version de PHP utilisée et installer Piwikurn:md5:a4a4536bf426a8ce84ccbdd9cdd60f9b2010-01-31T23:05:00+01:002013-07-26T22:33:35+02:00NarannMes coups de coeur1and1blogdotclearfiltrefrinstallipphppiwikstatsversion<p><img src="https://www.fevrierdorian.com/blog/public/billets/2010_install_piwik/piwik_tn.png" alt="piwik_tn.png" style="float:left; margin: 0 1em 1em 0;" title="piwik_tn.png, fév. 2010" height="150" width="150" />Bonjours à tous! Ça fait un petit moment que j'entends parler de <a href="http://piwik.org">Piwik</a>. Piwik est une interface d'analyse de statistiques de site web. Il permet de calculer le nombre de visiteur, le nombre de page vu, etc... Il n'est pas comme <a href="http://www.atinternet.com/Produits/Solutions-XiTi.aspx">Xiti</a> (ou l'outil de stat n'est pas hébergé chez vous) mais il s'installe (<a href="http://piwik.org/docs/installation/">très facilement</a>) directement sur votre serveur. Étant chez <a href="http://www.1and1.fr">1and1</a>, il existe déjà un outil de statistique mais celui ci n'est pas terrible et assez lent. Étant donné qu'il existe un <a href="http://plugins.dotaddict.org/dc2/details/Piwik">plugin Piwik</a> pour <a href="http://fr.dotclear.org">dotclear</a>, je me suis décidé à franchir le pas. Seul problème, <a href="http://piwik.org/docs/requirements/">il nécessite PHP 5.1.3</a> pour fonctionner. Et il m'afficha lors de l'installation un joli message d'erreur comme quoi il fallait que j'ai PHP 5.1.3 d'installé...</p> <h5>Installation</h5>
<p>Déjà, pour installer Piwik, ce n'est vraiment pas compliqué. Vous allez sur <a href="http://piwik.org/" hreflang="en">le site officiel</a>, vous téléchargez la dernière version de Piwik, vous la dézippé et vous placez le dossier "piwik" à la racine de votre serveur.</p>
<p>Vous y allez ensuite (par exemple monserveur.com/piwik) et il vous posera deux trois questions et s'installera sans (trop) problèmes...</p>
<h5>Le problème avec PHP 5</h5>
<p>...sauf quand votre serveur est en PHP 4, ce qui est le cas des serveurs mutualisé de 1and1.
<img src="https://www.fevrierdorian.com/blog/public/logos/elephpant-elephant-php-logo_1_.png" alt="elephpant-elephant-php-logo_1_.png" style="display:block; margin:0 auto;" title="elephpant-elephant-php-logo_1_.png, janv. 2010" height="255" width="397" />
Quand vous utilisez un serveur chez vous en local, vous avez tout pouvoirs dessus et donc vous pouvez facilement modifier votre version de PHP. Mais sur un hébergement mutualisé, on peut dire que vous l'avez dans l'os. :baffed:</p>
<p>En effet vous n'avez pas possibilité de modifier la configuration du serveur mutualisé (et au final: Encore heureux! Si tous le monde le pouvait, les serveurs ne tiendrait pas longtemps :sourit: ).</p>
<p>Seulement tout ça me semblait très louche... La version 4.4.9 <a href="http://www.php.net/archive/2008.php#id2008-08-07-1" hreflang="en">à été lancé en Aout 2008</a> et date un peu, ça me paraissait fou, à l'heure ou l'<a href="http://www.nexen.net/articles/dossier/18064-php_6_:_ca_marche_et_ca_va_vite.php" hreflang="fr">on parle déjà de PHP 6</a> qu'un hébergeur n'offre aucune solution pour passer en PHP 5...</p>
<p>Mais voila, en fouillant un peu dans la FAQ de 1and1 (très mal faite mais assez complète, on ne lui demande pas plus), j'ai trouvé <a href="http://faq.1and1.fr/scripts/php/5.html" hreflang="fr">la solution</a>:</p>
<ul>
<li>Il faut créer un fichier ".htaccess" à la racine du dossier dans lequel ou souhaite utiliser PHP 5 (en ce qui me concerne, c'est le dossier "piwik") et y mettre écrire ça:</li>
</ul>
<pre>
AddType x-mapp-php5 .php
</pre>
<p>Dorénavant, tout les fichier .php seront interprété en PHP 5. La classe quand même :laClasse:</p>
<h5>Piwik</h5>
<p><img src="https://www.fevrierdorian.com/blog/public/logos/piwik_logo_1_.png" alt="piwik_logo_1_.png" style="display:block; margin:0 auto;" title="piwik_logo_1_.png, janv. 2010" height="100" width="100" />
Comme c'est si bien dit sur le site officiel:</p>
<blockquote><p>Piwik aims to be an open source alternative to Google Analytics.</p></blockquote>
<p>Rien que ça :sourit:</p>
<p>Une fois Piwik installé, on pourrait installer le plugin Piwik pour Dotclear dont je parlais tout à l'heure.</p>
<p>On "pourrait" en effet... Car chez moi ça n'a pas marché! :baffed: En effet j'ai un gros:</p>
<pre>
Socket (0)
</pre>
<p>Quand j'essaie de le configurer via l'interface. Bon, je décide de faire ça manuellement.</p>
<p>Pour ça, il faut insérer un petit javascript qui s'affichera dans toute les pages du site. Ce code vous est donné à la fin de votre installation de Piwik. Si vous l'avez perdu, il suffit, dans votre interface Piwik, d'aller dans "Paramètres" (en haut à droite), onglet "Site" puis "Afficher le code".</p>
<p>Comme on est sur un site dynamique, la solution la plus simple pour ce genre de manipulation est d'insérer ça dans le "footer" ou le "header" (ce sont les zones tout en haut et tout en bas d'un site).</p>
<p>Sur Dotclear il faut aller dans de Tableau de bord:
<img src="https://www.fevrierdorian.com/blog/public/billets/2010_install_piwik/tableau_de_bord.png" alt="tableau_de_bord.png" style="display:block; margin:0 auto;" title="tableau_de_bord.png, janv. 2010" height="118" width="169" />
Apparence du blog:
<img src="https://www.fevrierdorian.com/blog/public/billets/2010_install_piwik/apparence_du_blog.png" alt="apparence_du_blog.png" style="display:block; margin:0 auto;" title="apparence_du_blog.png, janv. 2010" height="118" width="176" />
Éditeur de thème:
<img src="https://www.fevrierdorian.com/blog/public/billets/2010_install_piwik/editeur_de_theme.png" alt="editeur_de_theme.png" style="display:block; margin:0 auto;" title="editeur_de_theme.png, janv. 2010" height="159" width="217" />
Et selectionner "_footer.php":
<img src="https://www.fevrierdorian.com/blog/public/billets/2010_install_piwik/select_footer.png" alt="select_footer.png" style="display:block; margin:0 auto;" title="select_footer.png, janv. 2010" height="99" width="168" /></p>
<p>Ici, après:</p>
<pre>
{{tpl:SysBehavior behavior="publicFooterContent"}}
</pre>
<p>Il ne reste plus qu'a insérer votre code javascript derrière cette ligne.</p>
<p>Maintenant Piwik devrait commencer à afficher les visiteurs. Testez! :banaeyouhou:</p>
<h5>Filtrer son IP</h5>
<p>Le problème, vous vous en rendrez compte assez vite est que sur votre blog, vous avez peu de visite et que finalement, vous-même affichez plus de page que vos visiteur (je sais, c'est la loose... :triste: ).</p>
<p>Donc, si vous voulez pouvoir "filtrer" votre IP afin que Piwik ne considère pas vos visite comme de "vraix" visites, il faut "péachpéter" (haha je ris tout seul de ma minable blague...).</p>
<p>En gros, on va demander à dotclear de n'afficher le code javascript que si l'IP est différente de la votre. En PHP, la commande pour connaitre l'IP du "demandeur", c'est:</p>
<pre>
$_SERVER["REMOTE_ADDR"] //Qui renvoit une adresse ip sous la forme 55.98.165.77, au pif ici
</pre>
<p>Donc une petite boucle du genre:</p>
<pre class="php php"><span style="color: #000000; font-weight: bold;"><?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">[</span><span style="color: #0000ff;">"REMOTE_ADDR"</span><span style="color: #009900;">]</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">"55.98.165.77"</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #000000; font-weight: bold;">?></span>
<!-- Javascript Piwik -->
<span style="color: #000000; font-weight: bold;"><?php</span> <span style="color: #009900;">}</span> <span style="color: #000000; font-weight: bold;">?></span></pre>
<p>Alala... Si c'était aussi simple... :gniarkgniark:</p>
<p>Et oui! Dotclear n'exécute pas de code PHP de template (ce qu'on fait) par défaut. il faut aller l'autoriser dans about:config:
<img src="https://www.fevrierdorian.com/blog/public/billets/2010_install_piwik/aboutconfig.png" alt="aboutconfig.png" style="display:block; margin:0 auto;" title="aboutconfig.png, janv. 2010" height="78" width="131" />
Puis mettre tpl_php_allow sur "oui":
<img src="https://www.fevrierdorian.com/blog/public/billets/2010_install_piwik/tpl_php_allow.png" alt="tpl_php_allow.png" style="display:block; margin:0 auto;" title="tpl_php_allow.png, janv. 2010" height="76" width="313" />
Voila, Piwik ne devrait plus comptabiliser vos visites! :sourit:</p>
<p>Si vous souhaitez ajouter une IP, la boucle ressemblera à ça:</p>
<pre class="php php"><span style="color: #000000; font-weight: bold;"><?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span> <span style="color: #009900;">(</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">[</span><span style="color: #0000ff;">"REMOTE_ADDR"</span><span style="color: #009900;">]</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">"55.98.165.77"</span><span style="color: #009900;">)</span> <span style="color: #339933;">&&</span> <span style="color: #009900;">(</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">[</span><span style="color: #0000ff;">"REMOTE_ADDR"</span><span style="color: #009900;">]</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">"55.98.165.78"</span><span style="color: #009900;">)</span> <span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #000000; font-weight: bold;">?></span>
<!-- Javascript Piwik -->
<span style="color: #000000; font-weight: bold;"><?php</span> <span style="color: #009900;">}</span> <span style="color: #000000; font-weight: bold;">?></span></pre>
<p>En espérant que ce billet vous soit utile...</p>
<p>Amusez vous bien! ;)</p>
<p>Dorian</p>