Bien "logger" ses mods



  • –-------------------------------

    Bien "logger" ses mods - V3.0

    Bonjour/bonsoir à vous !

    Bien, je sais que le titre n'est pas très explicite mais je vous assure, il est adapté 😄

    Par "Bien logger ses mods" j’entends "bien afficher les étapes de l'initialisation du mod dans la console". Si la notion est encore floue pour vous, vous allez comprendre par la suite.
    [align=center
    SOMMAIRE
    ]
    I. Créer un logger basique
    II. Écrire ses logs dans un fichier
    III. Adapter son logger à une console (launcher, programme etc…)

    [align=center
    I. Créer un logger basique
    ]
    Bon, commençons !

    Tout d'abord, nous allons créer une nouvelle classe, de base, qui n'hérite de rien (rooh, une classe indépendante ❤).
    Nous n'allons même pas créer de constructeur 😠 et nous allons la nommer "Console".
    Vite fait, un bout de code :

    public class Console {
    
    }
    
    

    Inutile de préciser que jusque là ça a été d'une difficulté remarquable. 😛

    Ensuite, nous allons ajouter une méthode de type "void" qui comprendra un argument "String" du nom de votre choix. Pour ma part ce sera "str".
    Pour les débutants en Java, "void" signifie que cette méthode ne renvoie aucune valeur.

    public class Console {
    void write(String str){
    
    }
    }
    
    

    Puis, on y ajoute un petit output, avec en argument, des trucs un peu spéciaux :

    public class Console {
    void write(String str){
    str = str.replace("\n"," ");
    System.out.println("[NOMDEVOTREMOD] "+ str);
    }
    }
    
    

    Remplacez le "NOMDEVOTREMOD" par… le nom de votre mod ! (Je suis sûr que ne vous vous y attendiez pas !)
    Gardez bien les deux crochets et l'espace après le crochet fermé.
    Quant à notre " str = str.replace("\n"," ") ", il permet tout simplement de remplacer les sauts de ligne par des espaces.
    Nous pourrions garder les sauts de ligne mais nous perdrions l'entête avec le nom du mod, et parcourir entièrement la chaîne de caractères avec une boucle for serait vraiment faire compliqué pour quelque chose de simple.
    Bref, ne nous éparpillons pas trop, poursuivons :
    Ajoutons une seconde méthode qui se nommera cette fois "writeErr" et qui aura les mêmes caractéristiques que notre méthode précédente à quelques trucs près :

    public class Console {
    void write(String str){
    str = str.replace("\n"," ");
    System.out.println("[NOMDEVOTREMOD] "+ str);
    }
    void writeErr(String str){
    str = str.replace("\n", " ");
    System.out.println("[NOMDEVOTREMOD] [ERROR] "+ str);
    }
    }
    
    

    Encore une fois, vous pouvez remplacer "NOMDEVOTREMOD" par le nom de votre mod.

    Voilà qui est terminé ! Notre magnifique, merveilleuse, sensationnelle, [remplacez par l'adjectif mélioratif de votre choix] classe est terminée !
    ❗ Une seule classe de ce type par mod uniquement !

    Maintenant, dans chaque constructeur de classe/thread/initialisation de mod, placez une seule ligne de code que voici : (bien sûr, pas dans la classe "Console" hein ^^)

    Console console = new Console();
    

    Tout est prêt pour l'utilisation !

    Lors de l'initialisation de votre mod, vous pourrez marquer :

    console.write("Coucou ! Ceci est un message venant de mon mod !");
    

    ou encore :

    console.writeErr("Coucou ! Ceci est un message d'erreur venant de mon mod !");
    

    Remplacez ces phrases idiotes par les phrases de votre choix.

    Lors de la création d'un bloc par exemple, mettez cette ligne de code à la suite de la déclaration du bloc avec un message comme : "Bloc 'BlocTutoriel' initialisé !".
    Lors d'une erreur employez la seconde ligne de code que je vous ai donné.

    Un petit exemple :

    SuperBoots = new SuperBoots(3840, SuperArmor, 0, 3).setUnlocalizedName("SuperBoots").func_111206_d("monmod:superboots");
    GameRegistry.registerItem(SuperBoots, "SuperBoots", "monMod");
    console.write("Item 'SuperBoots' initialisé avec succès !");
    

    On verra dans la console :

    2013-07-23 14:22:51 [INFO] [STDOUT] [LENOMDUMOD] Item 'SuperBoots' initialisé avec succès !
    

    Bon penchons nous sur la question principale :
    ***A quoi cela va-t-il servir ?***
    Pour l'utilisateur du mod, à rien !
    Pour nous, à tout !
    Lorsque vous regarderez votre console lors d'un plantage, vous pourrez voir où exactement l'erreur a eu lieu. Et lorsque l'on vous dit sur le forum du mod :
    "Bonjour ! Jé eu 1 érreur kan jé lancer mincraft"
    Et qu'il vous communique l'erreur, vous saurez la position exacte de l'erreur. (Car dans certains cas Eclipse vous donne la localisation de l'erreur, mais dans d'autres cas, par exemple, dans Minecraft, il vous dit juste le nom de l'erreur !) Mais heureusement vous avez prévu le coup, vous avez lu mon tutoriel et vous pouvez voir…

    2013-07-23 14:22:51 [INFO] [STDOUT] [LENOMDUMOD] Item 'SuperBoots' initialisé avec succès !
    2013-07-23 14:23:01 [INFO] [STDOUT] [LENOMDUMOD] Item 'SuperLeggingsOfTheDeath' initialisé avec succès !
    [ForgeModLoader] Caught an exception during block registration
    java.lang.NullPointerException
    
    

    …que l'erreur se trouve juste derrière l'initialisation de notre super pantalon de la mort qui tue.

    Donc oui, c'est très utile.
    Enfin, si vous me dites que l'on pourrait utiliser un "System.out.println" directement, je vous répond : non !
    Imaginez que l'utilisateur qui vous donne son erreur ait 18 mods installés, comment voyez-vous que le message provient de votre mod sans le "[NOMDEVOTREMOD]" ?
    (la méthode ajoute automatiquement le [NOMDEVOTREMOD])

    [align=center
    II. Écrire ses logs dans un fichier
    ]

    C'est bien beau de mettre ses erreurs et ses logs dans la console mais ce serait mieux de les placer dans un fichier !
    J'ai crée une petite méthode qui permet d'enregistrer des chaînes de caractère dans un fichier. Inutile de détailler, supprimez tout le contenu de votre classe "Console" (sauf le "package") et placez le nouveau code :

    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;

    public class Console{
    void write(String str) throws IOException{
    str = str.replace("\n"," ");
    System.out.println("[NOMDEVOTREMOD] "+ str);
    fileWrite(str);
    }
    void writeErr(String str) throws IOException{
    str = str.replace("\n", " ");
    System.out.println("[NOMDEVOTREMOD] [ERROR] "+ str);
    fileWrite("[ERROR] "+ str);
    }
    boolean fileWrite(String str) throws IOException{
    boolean works = true;
    FileWriter writer = null;
    try{
    writer = new FileWriter("modid" + "-log.txt", true);
    writer.write(str,0,str.length());
    }catch(IOException ex){
    works = false;
    ex.printStackTrace();
    }finally{
    if(writer != null){
    writer.close();
    }
    }
    return works;
    }
    void deleteLogFile(){
    File logFile= new File("modid"+"-log.txt");
    if(logFile.exists()){
    logFile.delete();
    System.out.println("Fichier '" + "modid" + "-log.txt' supprimé avec succès !");
    }
    else{
    System.out.println("Erreur lors de la supression du fichier '" + "modid" + "-log.txt' : le fichier n'existe pas !");
    }
    }
    }

    Faites un "Ctrl + F" et tapez, dans la case "Search" :

    NOMDEVOTREMOD
    

    Tapez ensuite dans la case "replace" le nom de votre mod et cliquez sur "replace all".
    Puis, dans la case "Search" (écrasez "NOMDEVOTREMOD") tapez :

    modid

    Enfin, dans la case "Replace" tapez le "mod id" de votre mod sans majuscules et sans tirets/espaces/points/deux points etc… et appuyez sur "replace all".

    Vous pouvez maintenant fermer la fenêtre. Votre classe "Console" est terminée !
    Même usage qu'avant, aucune différence à une chose près :
    Au démarrage du mod, dans l'initialisation, ajoutez :

    console.deleteLogFile();

    Ceci aura pour rôle de supprimer le fichier de logs du dossier. Car lorsque l'on démarre Minecraft un certain nombre de fois, le fichier log devient volumineux. On le supprime donc au démarrage de Minecraft. Le fichier sera conservé lors d'un crash mais sera écrasé dés le redémarrage de Minecraft.

    Vous pouvez utiliser la méthode "fileWrite" pour écrire un texte uniquement dans le fichier et non dans la console :

    console.fileWrite("Coucou ! Cette phrase sera écrite uniquement dans le fichier !");
    

    [align=center
    III. Adapter son logger à une console
    ]

    Dans cette troisième partie, nous allons voir comment diriger les logs de la classe "Console" dans une console graphique (GUI).
    Dans ce tutoriel, j'utiliserai l'objet "TextArea" (awt).

    Dans l'initialisation votre interface graphique ajoutez l'objet :

    TextArea console = new TextArea();
    

    Puis créez une variable de classe du même nom (avant le constructeur de votre classe contenant l'interface) :

    static TextArea console;
    

    Eclipse devrait vous sortir quelques erreurs. Appuyez sur les touches "Ctrl + Shift + O" pour générer les "import" nécessaires.
    Voici la nouvelle version de la classe "Console" :

    
    import java.awt.TextArea;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class Console{
    void write(String str) throws IOException{
    str = str.replace("\n"," ");
    System.out.println("[NOMDEVOTREMOD] "+ str);
    fileWrite(str);
    nomDeVotreClassePrincipale.console.append(str);
    nomDeVotreClassePrincipale.console.setCaretPosition(myTextarea.getText().length() -1);
    }
    void writeErr(String str) throws IOException{
    str = str.replace("\n", " ");
    System.out.println("[NOMDEVOTREMOD] [ERROR] "+ str);
    fileWrite("[ERROR] "+ str);
    nomDeVotreClassePrincipale.console.append("ERREUR : " + str);
    nomDeVotreClassePrincipale.console.setCaretPosition(myTextarea.getText().length() -1);
    
    }
    boolean fileWrite(String str) throws IOException{
    boolean works = true;
    FileWriter writer = null;
    try{
    writer = new FileWriter("modid" + "-log.txt", true);
    writer.write(str,0,str.length());
    }catch(IOException ex){
    works = false;
    ex.printStackTrace();
    }finally{
    if(writer != null){
    writer.close();
    }
    }
    return works;
    }
    void deleteLogFile(){
    File logFile= new File("modid"+"-log.txt");
    if(logFile.exists()){
    logFile.delete();
    System.out.println("Fichier '" + "modid" + "-log.txt' supprimé avec succès !");
    }
    else{
    System.out.println("Erreur lors de la supression du fichier '" + "modid" + "-log.txt' : le fichier n'existe pas !");
    }
    }
    void clear(){
    nomDeVotreClassePrincipale.console.setText("");
    nomDeVotreClassePrincipale.console.setCaretPosition(myTextarea.getText().length() -1);
    }
    }
    
    
    NOMDEVOTREMOD
    

    Tapez ensuite dans la case "replace" le nom de votre mod et cliquez sur "replace all".
    Puis, dans la case "Search" (écrasez "NOMDEVOTREMOD") tapez :

    modid

    Dans la case "Replace" tapez le "mod id" de votre mod sans majuscules et sans tirets/espaces/points/deux points etc… et appuyez sur "replace all".
    Pour terminer, remplacez "nomDeVotreClassePrincipale" par le nom de votre classe contenant l'interface graphique.

    Vous pouvez utiliser la méthode "clear" pour effacer le contenu de la console de l'interface graphique :

    console.clear();
    

    Voilà ! L'ajout de nouvelles parties dans ce tutoriel se fera sur commande 😛


  • Moddeurs confirmés Rédacteurs Administrateurs

    Bonsoir,
    Vraiment désolé mais je vais détruire ton tutoriel en 3 lignes de code :
    À la suite des déclaration :

    public static Logger loggertutoriel;
    

    Dans le preInit :

    loggertutoriel = event.getModLog();
    loggertutoriel.info("coucou je suis preInit !");
    

    Ce qui donne dans les logs :

    2013-07-23 01:46:56 [INFO] [ModTutoriel] coucou je suis preInit !
    

    Plus simple et plus jolie 🙂


  • Administrateurs

    Personnellement, j'aurais pu utiliser ce genre de tutoriel pour mon propre jeu en java. ^^ Mais il est vrai que robin vient de "détruire" ce que tu viens de faire par une simple utilisation de la classe Java : Logger ^^. (Après, si on veux faire un "custom" logger, pourquoi pas !)

    Ou si tu modifie bien la classe, tu peux arriver à l'utiliser pour un launcher ! 😉 Mais une chose est sure, tu n'as pas fait ce tuto pour rien, car en modifiant un peu la classe, on peut arriver à quelque chose de vraiment d'utile, comme faire une console pour un launcher ! ^^ (ex: FeedTheBeast)



  • C'est pratique, mais Logger est plus adapté.

    Essaie de remanier ton tutoriel, ou de l'améliorer, pour le rendre plus utile que Logger.



  • Outch ! Désolé !

    Je pense faire un système qui va afficher les logs dans un fichier et créer un output pour l'afficher dans une console.

    comme faire une console pour un launcher !

    On peut rediriger la sortie système vers la console du launcher, donc mettre une fonction telle que celle-ci serait inutile… Je peux essayer de le faire mais suivant le type de la console, chaque chose est différente.

    Pourriez-vous le conserver ici en attendant que je publie la suite ?



  • T'inquiète, on efface pas pour l'instant.

    Le tutoriel reste toujours assez utile, pour ceux qui se lancent dans le java, et qui veulent tester des trucs sans passer par l'API



  • Nouvelle version du tutoriel : V3.0
    -> Ajout de la partie 3

    Le tutoriel est terminé 😄



  • Je ne parviens pas à utiliser le [code_java] :S
    Sinon vu que j'ai tout modifié mon tuto a des chances d'être accepté ? :S


  • Moddeurs confirmés

    Pour le [code_java] pense à le fermer avec le [code_java] mais avec un / devant le code_java



  • Ah oui c'est vrai qu'il faut les fermer avec le même nom ! Ok je vais faire ça !



  • Tu devrais renommer ton tuto en "1.6.2 - Savoir où son mod crash" 🙂



  • Arrange cet partie

    public class Console {
    void write(String str){
    str = str.replace("\n"," ");
    System.out.println("[NOMDEVOTREMOD] "+ str);
    }
    void writeErr(String str){
    str = str.replace("\n", " ");
    System.out.println("[NOMDEVOTREMOD] [ERROR] "+ str);
    }
    }
    
    


  • C'est fait !


  • Moddeurs confirmés Rédacteurs Administrateurs

    Je suis pas sûr que ça sera super utile comme on peut faire beaucoup plus simple avec le log de java + un setParent au logger de FML.


Log in to reply