Blog

Migrer vers un enregistreur avec Sensei

Alan Richardson
Publié le 30 novembre 2020

Migrer vers un enregistreur avec Sensei

Ce billet décrit la création d'une recette pour migrer de System.out.println à l'utilisation d'un logger Java.

Lorsque je bidouille du code, plutôt que d'utiliser le TDD, et que je fais des erreurs, j'ai la mauvaise habitude d'imprimer une ligne dans System.out, et j'ai voulu me débarrasser de cette habitude.

J'ai fait un certain nombre d'erreurs en écrivant le code ci-dessous :

   private String getCountdownString() {
        String output = "";
        String prefix="";
        for(int countdown = 10; countdown > 0; countdown-- ){
            output = output + prefix + countdown;
            System.out.println(output);
            prefix=", ";
        }
        System.out.println(output);
        return output;
    }


Initialement, j'ai écrit countdown++ et la boucle ne s'est pas terminée.

Et j'ai utilisé countdown > 1 donc je n'ai pas obtenu le résultat que je voulais.

Au final, j'ai truffé mon code de System.out.println pour m'aider à déboguer. Et cette expérience m'a conforté dans l'idée que je dois apprendre à utiliser un logger comme approche par défaut.

Recherche

Heureusement, j'ai lu la documentation deSensei et j'ai décidé d'utiliser le guide "Getting Started" pour m'aider à créer une recette pour convertir System.out.println et m'encourager à utiliser un logger :

  • java.util.logging.Logger

Création d'une recette

La première chose que je fais est de cliquer sur println puis sur alt+enter pour créer une nouvelle recette.

Système Out Print Créer une nouvelle recette


Je le crée avec les détails suivants :


Nom : Logger : utilisez logger au lieu de println
Description : utiliser logger au lieu de println - n'oubliez pas d'arrêter d'utiliser System.out.println
Niveau : Erreur


Je commencerai par faire correspondre l'appel de méthode avec le nom println


recherche :
  appel de méthode :
    nom : "println"

Et l'aperçu me montre toutes les correspondances dans mon code.


Méthode de paramétrage des recettes appel Println


Je peux voir que toutes les correspondances dans mon code sont pour System.out.println mais je ne suis pas sûr qu'à long terme ce sera la seule correspondance. Je veux faire correspondre une déclaration plus qualifiée que je veux modifier.

Je développe le matcheur pour rechercher un appel de méthode sur un champ nommé dans la classe System.


recherche :
  appel de méthode :
    nom : "println"
    "on" :
      domaine :
        en :
          classe :
            nom : "Système"
        nom : "out"



Je pourrais, si je le souhaitais, qualifier complètement le nom du système en java.lang.System

Réglages de la recette MéthodeSystème de noms d'appel

Modification du code pour l'enregistrement


Ensuite, je veux créer le QuickFix.

Tout d'abord, je souhaite modifier la ligne de code qui enregistre la sortie :


les correctifs disponibles :
- name : "use Logger" (utiliser l'enregistreur)
  actions :
  - réécrire :
      to: "logger.log(Level.INFO, {{{ arguments.0 }}})"



Je n'ai pas besoin de me souvenir du format du modèle de moustache. J'ai utilisé la fonction Show Variables de l'interface graphique pour afficher l'argument et j'ai double-cliqué dessus. L'interface graphique a ensuite rempli le modèle de moustache correspondant.



Lorsque je l'essaie, je constate que je dois toujours appuyer sur alt+enter pour importer l'énumération des niveaux. Mais si je modifie mon QuickFix pour avoir un élément pleinement qualifié, alors Sensei ajoutera l'importation pour moi, par exemple.

  • Il remplacera System.out.println(output) ; par

logger.log(Level.INFO, output) ;

  • Et ajoutez un import pour l'enum :

import java.util.logging.Level ;

  • Si je réécris en :
logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})

Et cela fonctionnera, mais je devrai toujours me souvenir de la syntaxe pour instancier le logger en premier lieu.

Syntaxe d'instanciation de l'enregistreur en premier lieu


Modification du code pour ajouter le champ logger

Je peux modifier mon QuickFix pour créer le champ pour moi aussi.

Je vais d'abord coder le logger, puis l'ajouter à ma recette pour ne plus avoir à le coder.

Logger logger2 = Logger.getLogger(SysOutTest.class.getName()) ;


J'ai tendance à écrire le code d'exemple que je veux voir généré en premier, car je peux alors utiliser la complétion de code et la vérification syntaxique d'IntelliJ pour m'assurer qu'il est correct. Comme effet secondaire, il sera alors dans l'aperçu du code lorsque j'éditerai la recette pour ajouter les lignes QuickFix qui créeront ce code.

Et lorsque j'écris le code d'exemple, je veux utiliser un nom de champ différent (ici j'utilise logger2) parce que Sensei est assez intelligent pour ne pas ajouter un champ en double, donc je dois le tromper en utilisant un nom différent.

Je vais donc modifier la recette pour créer ce code en ajoutant un champ appelé logger.

les correctifs disponibles :

- name : "use Logger" (utiliser l'enregistreur)
  actions :
  - réécrire :
      to: "logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})"
  - addField :
      field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        \}}.class.getName())"
      cible : "parentClass"


Notez que j'ai modifié SysOutTest pour en faire une variable mustache afin qu'elle prenne le nom de n'importe quelle classe dans laquelle j'utilise cette recette. Et encore une fois, je ne me suis pas souvenu de la syntaxe mustache, j'ai utilisé l'interface graphique Show Variables pour trouver le remplacement dont j'avais besoin.

En qualifiant complètement le Logger de java.util.logging.Logger, Sensei ajoutera l'importation et écrira la ligne de code que je veux, c'est-à-dire

Logger logger = Logger.getLogger(SysOutTest.class.getName()) ;


Qualification complète du logger en java.util.logging.Logger


Une chose utile à propos de cette recette est que, parce qu'elle n'ajoute le champ logger qu'une seule fois, je peux l'utiliser sur n'importe quel code existant où j'ai utilisé `System.out.println` et utiliser Sensei pour changer toutes les occurrences dans mon fichier de code en même temps.


Utiliser l'enregistreur de données Résoudre tous les problèmes dans le fichier



Prochaines étapes

Une fois que je me serai habitué à cela, je finirai par m'entraîner à ne plus utiliser System.out.println.

Je peux utiliser Sensei pour m'aider à écrire du code de manière proactive en créant une deuxième recette qui m'aide à créer un logger.

Par exemple, je peux trouver une classe dans laquelle il n'y a pas de champ appelé logger, et en ajouter un.

Si je crée une recette de niveau Information


Nom : Logger : ajouter un logger

Description : Ajouter un logger à la classe


Pour faire correspondre une classe sans champ d'enregistrement :

recherche :
  classe :
    sans :
      enfant :
        domaine :
          nom : "logger"


Je vais ensuite réutiliser une partie de la correction rapide que nous avons vue plus tôt :


les correctifs disponibles :

  - name : "Ajouter un enregistreur"
    actions :
      - addField :
          field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        \}}.class.getName())"
          cible : "self"


Notez la différence de cible par rapport à la première correction rapide. Celle-ci utilise self parce que notre Search correspondait à la classe. La première correction rapide utilise parentClass parce que nous avons trouvé du code dans la classe elle-même.

Résumé

Il s'agit de l'un des principaux flux associés à l'utilisation de Sensei pour améliorer vos compétences personnelles en matière de programmation :

  • créer une recette pour vous aider à mettre en œuvre votre "meilleure pratique" immédiate
  • une fois que vous savez comment utiliser cette meilleure pratique, créez une recette pour accélérer votre flux de travail.


---


Vous pouvez installer Sensei à partir d'IntelliJ en utilisant "Preferences \ Plugins" (Mac) ou "Settings \ Plugins" (Windows) puis en recherchant simplement "sensei secure code".


Le code source et les recettes se trouvent dans le dépôt `sensei-blog-examples` sur le compte GitHub Secure Code Warrior , dans le module `pojoexamples`.




Voir la ressource
Voir la ressource

Un exemple rapide de création d'une recette pour passer de System.out.println à l'utilisation d'un logger Java.

Vous souhaitez en savoir plus ?

Alan Richardson a plus de vingt ans d'expérience professionnelle dans le domaine des technologies de l'information. Il a travaillé en tant que développeur et à tous les niveaux de la hiérarchie des tests, du testeur au responsable des tests. Responsable des relations avec les développeurs à l'adresse Secure Code Warrior, il travaille directement avec les équipes pour améliorer le développement de codes sécurisés de qualité. Alan est l'auteur de quatre livres, dont "Dear Evil Tester" et "Java For Testers". Alan a également créé une formation en ligne courses pour aider les gens à apprendre les tests techniques sur le Web et Selenium WebDriver avec Java. Alan publie ses écrits et ses vidéos de formation sur SeleniumSimplified.com, EvilTester.com, JavaForTesters.com et CompendiumDev.co.uk.

Secure Code Warrior est là pour vous aider à sécuriser le code tout au long du cycle de vie du développement logiciel et à créer une culture dans laquelle la cybersécurité est une priorité. Que vous soyez responsable AppSec, développeur, CISO ou toute autre personne impliquée dans la sécurité, nous pouvons aider votre organisation à réduire les risques associés à un code non sécurisé.

Réservez une démonstration
Partager sur :
Auteur
Alan Richardson
Publié le 30 novembre 2020

Alan Richardson a plus de vingt ans d'expérience professionnelle dans le domaine des technologies de l'information. Il a travaillé en tant que développeur et à tous les niveaux de la hiérarchie des tests, du testeur au responsable des tests. Responsable des relations avec les développeurs à l'adresse Secure Code Warrior, il travaille directement avec les équipes pour améliorer le développement de codes sécurisés de qualité. Alan est l'auteur de quatre livres, dont "Dear Evil Tester" et "Java For Testers". Alan a également créé une formation en ligne courses pour aider les gens à apprendre les tests techniques sur le Web et Selenium WebDriver avec Java. Alan publie ses écrits et ses vidéos de formation sur SeleniumSimplified.com, EvilTester.com, JavaForTesters.com et CompendiumDev.co.uk.

Partager sur :

Migrer vers un enregistreur avec Sensei

Ce billet décrit la création d'une recette pour migrer de System.out.println à l'utilisation d'un logger Java.

Lorsque je bidouille du code, plutôt que d'utiliser le TDD, et que je fais des erreurs, j'ai la mauvaise habitude d'imprimer une ligne dans System.out, et j'ai voulu me débarrasser de cette habitude.

J'ai fait un certain nombre d'erreurs en écrivant le code ci-dessous :

   private String getCountdownString() {
        String output = "";
        String prefix="";
        for(int countdown = 10; countdown > 0; countdown-- ){
            output = output + prefix + countdown;
            System.out.println(output);
            prefix=", ";
        }
        System.out.println(output);
        return output;
    }


Initialement, j'ai écrit countdown++ et la boucle ne s'est pas terminée.

Et j'ai utilisé countdown > 1 donc je n'ai pas obtenu le résultat que je voulais.

Au final, j'ai truffé mon code de System.out.println pour m'aider à déboguer. Et cette expérience m'a conforté dans l'idée que je dois apprendre à utiliser un logger comme approche par défaut.

Recherche

Heureusement, j'ai lu la documentation deSensei et j'ai décidé d'utiliser le guide "Getting Started" pour m'aider à créer une recette pour convertir System.out.println et m'encourager à utiliser un logger :

  • java.util.logging.Logger

Création d'une recette

La première chose que je fais est de cliquer sur println puis sur alt+enter pour créer une nouvelle recette.

Système Out Print Créer une nouvelle recette


Je le crée avec les détails suivants :


Nom : Logger : utilisez logger au lieu de println
Description : utiliser logger au lieu de println - n'oubliez pas d'arrêter d'utiliser System.out.println
Niveau : Erreur


Je commencerai par faire correspondre l'appel de méthode avec le nom println


recherche :
  appel de méthode :
    nom : "println"

Et l'aperçu me montre toutes les correspondances dans mon code.


Méthode de paramétrage des recettes appel Println


Je peux voir que toutes les correspondances dans mon code sont pour System.out.println mais je ne suis pas sûr qu'à long terme ce sera la seule correspondance. Je veux faire correspondre une déclaration plus qualifiée que je veux modifier.

Je développe le matcheur pour rechercher un appel de méthode sur un champ nommé dans la classe System.


recherche :
  appel de méthode :
    nom : "println"
    "on" :
      domaine :
        en :
          classe :
            nom : "Système"
        nom : "out"



Je pourrais, si je le souhaitais, qualifier complètement le nom du système en java.lang.System

Réglages de la recette MéthodeSystème de noms d'appel

Modification du code pour l'enregistrement


Ensuite, je veux créer le QuickFix.

Tout d'abord, je souhaite modifier la ligne de code qui enregistre la sortie :


les correctifs disponibles :
- name : "use Logger" (utiliser l'enregistreur)
  actions :
  - réécrire :
      to: "logger.log(Level.INFO, {{{ arguments.0 }}})"



Je n'ai pas besoin de me souvenir du format du modèle de moustache. J'ai utilisé la fonction Show Variables de l'interface graphique pour afficher l'argument et j'ai double-cliqué dessus. L'interface graphique a ensuite rempli le modèle de moustache correspondant.



Lorsque je l'essaie, je constate que je dois toujours appuyer sur alt+enter pour importer l'énumération des niveaux. Mais si je modifie mon QuickFix pour avoir un élément pleinement qualifié, alors Sensei ajoutera l'importation pour moi, par exemple.

  • Il remplacera System.out.println(output) ; par

logger.log(Level.INFO, output) ;

  • Et ajoutez un import pour l'enum :

import java.util.logging.Level ;

  • Si je réécris en :
logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})

Et cela fonctionnera, mais je devrai toujours me souvenir de la syntaxe pour instancier le logger en premier lieu.

Syntaxe d'instanciation de l'enregistreur en premier lieu


Modification du code pour ajouter le champ logger

Je peux modifier mon QuickFix pour créer le champ pour moi aussi.

Je vais d'abord coder le logger, puis l'ajouter à ma recette pour ne plus avoir à le coder.

Logger logger2 = Logger.getLogger(SysOutTest.class.getName()) ;


J'ai tendance à écrire le code d'exemple que je veux voir généré en premier, car je peux alors utiliser la complétion de code et la vérification syntaxique d'IntelliJ pour m'assurer qu'il est correct. Comme effet secondaire, il sera alors dans l'aperçu du code lorsque j'éditerai la recette pour ajouter les lignes QuickFix qui créeront ce code.

Et lorsque j'écris le code d'exemple, je veux utiliser un nom de champ différent (ici j'utilise logger2) parce que Sensei est assez intelligent pour ne pas ajouter un champ en double, donc je dois le tromper en utilisant un nom différent.

Je vais donc modifier la recette pour créer ce code en ajoutant un champ appelé logger.

les correctifs disponibles :

- name : "use Logger" (utiliser l'enregistreur)
  actions :
  - réécrire :
      to: "logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})"
  - addField :
      field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        \}}.class.getName())"
      cible : "parentClass"


Notez que j'ai modifié SysOutTest pour en faire une variable mustache afin qu'elle prenne le nom de n'importe quelle classe dans laquelle j'utilise cette recette. Et encore une fois, je ne me suis pas souvenu de la syntaxe mustache, j'ai utilisé l'interface graphique Show Variables pour trouver le remplacement dont j'avais besoin.

En qualifiant complètement le Logger de java.util.logging.Logger, Sensei ajoutera l'importation et écrira la ligne de code que je veux, c'est-à-dire

Logger logger = Logger.getLogger(SysOutTest.class.getName()) ;


Qualification complète du logger en java.util.logging.Logger


Une chose utile à propos de cette recette est que, parce qu'elle n'ajoute le champ logger qu'une seule fois, je peux l'utiliser sur n'importe quel code existant où j'ai utilisé `System.out.println` et utiliser Sensei pour changer toutes les occurrences dans mon fichier de code en même temps.


Utiliser l'enregistreur de données Résoudre tous les problèmes dans le fichier



Prochaines étapes

Une fois que je me serai habitué à cela, je finirai par m'entraîner à ne plus utiliser System.out.println.

Je peux utiliser Sensei pour m'aider à écrire du code de manière proactive en créant une deuxième recette qui m'aide à créer un logger.

Par exemple, je peux trouver une classe dans laquelle il n'y a pas de champ appelé logger, et en ajouter un.

Si je crée une recette de niveau Information


Nom : Logger : ajouter un logger

Description : Ajouter un logger à la classe


Pour faire correspondre une classe sans champ d'enregistrement :

recherche :
  classe :
    sans :
      enfant :
        domaine :
          nom : "logger"


Je vais ensuite réutiliser une partie de la correction rapide que nous avons vue plus tôt :


les correctifs disponibles :

  - name : "Ajouter un enregistreur"
    actions :
      - addField :
          field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        \}}.class.getName())"
          cible : "self"


Notez la différence de cible par rapport à la première correction rapide. Celle-ci utilise self parce que notre Search correspondait à la classe. La première correction rapide utilise parentClass parce que nous avons trouvé du code dans la classe elle-même.

Résumé

Il s'agit de l'un des principaux flux associés à l'utilisation de Sensei pour améliorer vos compétences personnelles en matière de programmation :

  • créer une recette pour vous aider à mettre en œuvre votre "meilleure pratique" immédiate
  • une fois que vous savez comment utiliser cette meilleure pratique, créez une recette pour accélérer votre flux de travail.


---


Vous pouvez installer Sensei à partir d'IntelliJ en utilisant "Preferences \ Plugins" (Mac) ou "Settings \ Plugins" (Windows) puis en recherchant simplement "sensei secure code".


Le code source et les recettes se trouvent dans le dépôt `sensei-blog-examples` sur le compte GitHub Secure Code Warrior , dans le module `pojoexamples`.




Voir la ressource
Voir la ressource

Remplissez le formulaire ci-dessous pour télécharger le rapport

Nous aimerions que vous nous autorisiez à vous envoyer des informations sur nos produits et/ou sur des sujets liés au codage sécurisé. Nous traiterons toujours vos données personnelles avec le plus grand soin et ne les vendrons jamais à d'autres entreprises à des fins de marketing.

Soumettre
Pour soumettre le formulaire, veuillez activer les cookies "Analytics". N'hésitez pas à les désactiver à nouveau une fois que vous aurez terminé.

Migrer vers un enregistreur avec Sensei

Ce billet décrit la création d'une recette pour migrer de System.out.println à l'utilisation d'un logger Java.

Lorsque je bidouille du code, plutôt que d'utiliser le TDD, et que je fais des erreurs, j'ai la mauvaise habitude d'imprimer une ligne dans System.out, et j'ai voulu me débarrasser de cette habitude.

J'ai fait un certain nombre d'erreurs en écrivant le code ci-dessous :

   private String getCountdownString() {
        String output = "";
        String prefix="";
        for(int countdown = 10; countdown > 0; countdown-- ){
            output = output + prefix + countdown;
            System.out.println(output);
            prefix=", ";
        }
        System.out.println(output);
        return output;
    }


Initialement, j'ai écrit countdown++ et la boucle ne s'est pas terminée.

Et j'ai utilisé countdown > 1 donc je n'ai pas obtenu le résultat que je voulais.

Au final, j'ai truffé mon code de System.out.println pour m'aider à déboguer. Et cette expérience m'a conforté dans l'idée que je dois apprendre à utiliser un logger comme approche par défaut.

Recherche

Heureusement, j'ai lu la documentation deSensei et j'ai décidé d'utiliser le guide "Getting Started" pour m'aider à créer une recette pour convertir System.out.println et m'encourager à utiliser un logger :

  • java.util.logging.Logger

Création d'une recette

La première chose que je fais est de cliquer sur println puis sur alt+enter pour créer une nouvelle recette.

Système Out Print Créer une nouvelle recette


Je le crée avec les détails suivants :


Nom : Logger : utilisez logger au lieu de println
Description : utiliser logger au lieu de println - n'oubliez pas d'arrêter d'utiliser System.out.println
Niveau : Erreur


Je commencerai par faire correspondre l'appel de méthode avec le nom println


recherche :
  appel de méthode :
    nom : "println"

Et l'aperçu me montre toutes les correspondances dans mon code.


Méthode de paramétrage des recettes appel Println


Je peux voir que toutes les correspondances dans mon code sont pour System.out.println mais je ne suis pas sûr qu'à long terme ce sera la seule correspondance. Je veux faire correspondre une déclaration plus qualifiée que je veux modifier.

Je développe le matcheur pour rechercher un appel de méthode sur un champ nommé dans la classe System.


recherche :
  appel de méthode :
    nom : "println"
    "on" :
      domaine :
        en :
          classe :
            nom : "Système"
        nom : "out"



Je pourrais, si je le souhaitais, qualifier complètement le nom du système en java.lang.System

Réglages de la recette MéthodeSystème de noms d'appel

Modification du code pour l'enregistrement


Ensuite, je veux créer le QuickFix.

Tout d'abord, je souhaite modifier la ligne de code qui enregistre la sortie :


les correctifs disponibles :
- name : "use Logger" (utiliser l'enregistreur)
  actions :
  - réécrire :
      to: "logger.log(Level.INFO, {{{ arguments.0 }}})"



Je n'ai pas besoin de me souvenir du format du modèle de moustache. J'ai utilisé la fonction Show Variables de l'interface graphique pour afficher l'argument et j'ai double-cliqué dessus. L'interface graphique a ensuite rempli le modèle de moustache correspondant.



Lorsque je l'essaie, je constate que je dois toujours appuyer sur alt+enter pour importer l'énumération des niveaux. Mais si je modifie mon QuickFix pour avoir un élément pleinement qualifié, alors Sensei ajoutera l'importation pour moi, par exemple.

  • Il remplacera System.out.println(output) ; par

logger.log(Level.INFO, output) ;

  • Et ajoutez un import pour l'enum :

import java.util.logging.Level ;

  • Si je réécris en :
logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})

Et cela fonctionnera, mais je devrai toujours me souvenir de la syntaxe pour instancier le logger en premier lieu.

Syntaxe d'instanciation de l'enregistreur en premier lieu


Modification du code pour ajouter le champ logger

Je peux modifier mon QuickFix pour créer le champ pour moi aussi.

Je vais d'abord coder le logger, puis l'ajouter à ma recette pour ne plus avoir à le coder.

Logger logger2 = Logger.getLogger(SysOutTest.class.getName()) ;


J'ai tendance à écrire le code d'exemple que je veux voir généré en premier, car je peux alors utiliser la complétion de code et la vérification syntaxique d'IntelliJ pour m'assurer qu'il est correct. Comme effet secondaire, il sera alors dans l'aperçu du code lorsque j'éditerai la recette pour ajouter les lignes QuickFix qui créeront ce code.

Et lorsque j'écris le code d'exemple, je veux utiliser un nom de champ différent (ici j'utilise logger2) parce que Sensei est assez intelligent pour ne pas ajouter un champ en double, donc je dois le tromper en utilisant un nom différent.

Je vais donc modifier la recette pour créer ce code en ajoutant un champ appelé logger.

les correctifs disponibles :

- name : "use Logger" (utiliser l'enregistreur)
  actions :
  - réécrire :
      to: "logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})"
  - addField :
      field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        \}}.class.getName())"
      cible : "parentClass"


Notez que j'ai modifié SysOutTest pour en faire une variable mustache afin qu'elle prenne le nom de n'importe quelle classe dans laquelle j'utilise cette recette. Et encore une fois, je ne me suis pas souvenu de la syntaxe mustache, j'ai utilisé l'interface graphique Show Variables pour trouver le remplacement dont j'avais besoin.

En qualifiant complètement le Logger de java.util.logging.Logger, Sensei ajoutera l'importation et écrira la ligne de code que je veux, c'est-à-dire

Logger logger = Logger.getLogger(SysOutTest.class.getName()) ;


Qualification complète du logger en java.util.logging.Logger


Une chose utile à propos de cette recette est que, parce qu'elle n'ajoute le champ logger qu'une seule fois, je peux l'utiliser sur n'importe quel code existant où j'ai utilisé `System.out.println` et utiliser Sensei pour changer toutes les occurrences dans mon fichier de code en même temps.


Utiliser l'enregistreur de données Résoudre tous les problèmes dans le fichier



Prochaines étapes

Une fois que je me serai habitué à cela, je finirai par m'entraîner à ne plus utiliser System.out.println.

Je peux utiliser Sensei pour m'aider à écrire du code de manière proactive en créant une deuxième recette qui m'aide à créer un logger.

Par exemple, je peux trouver une classe dans laquelle il n'y a pas de champ appelé logger, et en ajouter un.

Si je crée une recette de niveau Information


Nom : Logger : ajouter un logger

Description : Ajouter un logger à la classe


Pour faire correspondre une classe sans champ d'enregistrement :

recherche :
  classe :
    sans :
      enfant :
        domaine :
          nom : "logger"


Je vais ensuite réutiliser une partie de la correction rapide que nous avons vue plus tôt :


les correctifs disponibles :

  - name : "Ajouter un enregistreur"
    actions :
      - addField :
          field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        \}}.class.getName())"
          cible : "self"


Notez la différence de cible par rapport à la première correction rapide. Celle-ci utilise self parce que notre Search correspondait à la classe. La première correction rapide utilise parentClass parce que nous avons trouvé du code dans la classe elle-même.

Résumé

Il s'agit de l'un des principaux flux associés à l'utilisation de Sensei pour améliorer vos compétences personnelles en matière de programmation :

  • créer une recette pour vous aider à mettre en œuvre votre "meilleure pratique" immédiate
  • une fois que vous savez comment utiliser cette meilleure pratique, créez une recette pour accélérer votre flux de travail.


---


Vous pouvez installer Sensei à partir d'IntelliJ en utilisant "Preferences \ Plugins" (Mac) ou "Settings \ Plugins" (Windows) puis en recherchant simplement "sensei secure code".


Le code source et les recettes se trouvent dans le dépôt `sensei-blog-examples` sur le compte GitHub Secure Code Warrior , dans le module `pojoexamples`.




Accès aux ressources

Cliquez sur le lien ci-dessous et téléchargez le PDF de cette ressource.

Secure Code Warrior est là pour vous aider à sécuriser le code tout au long du cycle de vie du développement logiciel et à créer une culture dans laquelle la cybersécurité est une priorité. Que vous soyez responsable AppSec, développeur, CISO ou toute autre personne impliquée dans la sécurité, nous pouvons aider votre organisation à réduire les risques associés à un code non sécurisé.

Voir le rapportRéservez une démonstration
Partager sur :
Vous souhaitez en savoir plus ?

Partager sur :
Auteur
Alan Richardson
Publié le 30 novembre 2020

Alan Richardson a plus de vingt ans d'expérience professionnelle dans le domaine des technologies de l'information. Il a travaillé en tant que développeur et à tous les niveaux de la hiérarchie des tests, du testeur au responsable des tests. Responsable des relations avec les développeurs à l'adresse Secure Code Warrior, il travaille directement avec les équipes pour améliorer le développement de codes sécurisés de qualité. Alan est l'auteur de quatre livres, dont "Dear Evil Tester" et "Java For Testers". Alan a également créé une formation en ligne courses pour aider les gens à apprendre les tests techniques sur le Web et Selenium WebDriver avec Java. Alan publie ses écrits et ses vidéos de formation sur SeleniumSimplified.com, EvilTester.com, JavaForTesters.com et CompendiumDev.co.uk.

Partager sur :

Migrer vers un enregistreur avec Sensei

Ce billet décrit la création d'une recette pour migrer de System.out.println à l'utilisation d'un logger Java.

Lorsque je bidouille du code, plutôt que d'utiliser le TDD, et que je fais des erreurs, j'ai la mauvaise habitude d'imprimer une ligne dans System.out, et j'ai voulu me débarrasser de cette habitude.

J'ai fait un certain nombre d'erreurs en écrivant le code ci-dessous :

   private String getCountdownString() {
        String output = "";
        String prefix="";
        for(int countdown = 10; countdown > 0; countdown-- ){
            output = output + prefix + countdown;
            System.out.println(output);
            prefix=", ";
        }
        System.out.println(output);
        return output;
    }


Initialement, j'ai écrit countdown++ et la boucle ne s'est pas terminée.

Et j'ai utilisé countdown > 1 donc je n'ai pas obtenu le résultat que je voulais.

Au final, j'ai truffé mon code de System.out.println pour m'aider à déboguer. Et cette expérience m'a conforté dans l'idée que je dois apprendre à utiliser un logger comme approche par défaut.

Recherche

Heureusement, j'ai lu la documentation deSensei et j'ai décidé d'utiliser le guide "Getting Started" pour m'aider à créer une recette pour convertir System.out.println et m'encourager à utiliser un logger :

  • java.util.logging.Logger

Création d'une recette

La première chose que je fais est de cliquer sur println puis sur alt+enter pour créer une nouvelle recette.

Système Out Print Créer une nouvelle recette


Je le crée avec les détails suivants :


Nom : Logger : utilisez logger au lieu de println
Description : utiliser logger au lieu de println - n'oubliez pas d'arrêter d'utiliser System.out.println
Niveau : Erreur


Je commencerai par faire correspondre l'appel de méthode avec le nom println


recherche :
  appel de méthode :
    nom : "println"

Et l'aperçu me montre toutes les correspondances dans mon code.


Méthode de paramétrage des recettes appel Println


Je peux voir que toutes les correspondances dans mon code sont pour System.out.println mais je ne suis pas sûr qu'à long terme ce sera la seule correspondance. Je veux faire correspondre une déclaration plus qualifiée que je veux modifier.

Je développe le matcheur pour rechercher un appel de méthode sur un champ nommé dans la classe System.


recherche :
  appel de méthode :
    nom : "println"
    "on" :
      domaine :
        en :
          classe :
            nom : "Système"
        nom : "out"



Je pourrais, si je le souhaitais, qualifier complètement le nom du système en java.lang.System

Réglages de la recette MéthodeSystème de noms d'appel

Modification du code pour l'enregistrement


Ensuite, je veux créer le QuickFix.

Tout d'abord, je souhaite modifier la ligne de code qui enregistre la sortie :


les correctifs disponibles :
- name : "use Logger" (utiliser l'enregistreur)
  actions :
  - réécrire :
      to: "logger.log(Level.INFO, {{{ arguments.0 }}})"



Je n'ai pas besoin de me souvenir du format du modèle de moustache. J'ai utilisé la fonction Show Variables de l'interface graphique pour afficher l'argument et j'ai double-cliqué dessus. L'interface graphique a ensuite rempli le modèle de moustache correspondant.



Lorsque je l'essaie, je constate que je dois toujours appuyer sur alt+enter pour importer l'énumération des niveaux. Mais si je modifie mon QuickFix pour avoir un élément pleinement qualifié, alors Sensei ajoutera l'importation pour moi, par exemple.

  • Il remplacera System.out.println(output) ; par

logger.log(Level.INFO, output) ;

  • Et ajoutez un import pour l'enum :

import java.util.logging.Level ;

  • Si je réécris en :
logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})

Et cela fonctionnera, mais je devrai toujours me souvenir de la syntaxe pour instancier le logger en premier lieu.

Syntaxe d'instanciation de l'enregistreur en premier lieu


Modification du code pour ajouter le champ logger

Je peux modifier mon QuickFix pour créer le champ pour moi aussi.

Je vais d'abord coder le logger, puis l'ajouter à ma recette pour ne plus avoir à le coder.

Logger logger2 = Logger.getLogger(SysOutTest.class.getName()) ;


J'ai tendance à écrire le code d'exemple que je veux voir généré en premier, car je peux alors utiliser la complétion de code et la vérification syntaxique d'IntelliJ pour m'assurer qu'il est correct. Comme effet secondaire, il sera alors dans l'aperçu du code lorsque j'éditerai la recette pour ajouter les lignes QuickFix qui créeront ce code.

Et lorsque j'écris le code d'exemple, je veux utiliser un nom de champ différent (ici j'utilise logger2) parce que Sensei est assez intelligent pour ne pas ajouter un champ en double, donc je dois le tromper en utilisant un nom différent.

Je vais donc modifier la recette pour créer ce code en ajoutant un champ appelé logger.

les correctifs disponibles :

- name : "use Logger" (utiliser l'enregistreur)
  actions :
  - réécrire :
      to: "logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})"
  - addField :
      field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        \}}.class.getName())"
      cible : "parentClass"


Notez que j'ai modifié SysOutTest pour en faire une variable mustache afin qu'elle prenne le nom de n'importe quelle classe dans laquelle j'utilise cette recette. Et encore une fois, je ne me suis pas souvenu de la syntaxe mustache, j'ai utilisé l'interface graphique Show Variables pour trouver le remplacement dont j'avais besoin.

En qualifiant complètement le Logger de java.util.logging.Logger, Sensei ajoutera l'importation et écrira la ligne de code que je veux, c'est-à-dire

Logger logger = Logger.getLogger(SysOutTest.class.getName()) ;


Qualification complète du logger en java.util.logging.Logger


Une chose utile à propos de cette recette est que, parce qu'elle n'ajoute le champ logger qu'une seule fois, je peux l'utiliser sur n'importe quel code existant où j'ai utilisé `System.out.println` et utiliser Sensei pour changer toutes les occurrences dans mon fichier de code en même temps.


Utiliser l'enregistreur de données Résoudre tous les problèmes dans le fichier



Prochaines étapes

Une fois que je me serai habitué à cela, je finirai par m'entraîner à ne plus utiliser System.out.println.

Je peux utiliser Sensei pour m'aider à écrire du code de manière proactive en créant une deuxième recette qui m'aide à créer un logger.

Par exemple, je peux trouver une classe dans laquelle il n'y a pas de champ appelé logger, et en ajouter un.

Si je crée une recette de niveau Information


Nom : Logger : ajouter un logger

Description : Ajouter un logger à la classe


Pour faire correspondre une classe sans champ d'enregistrement :

recherche :
  classe :
    sans :
      enfant :
        domaine :
          nom : "logger"


Je vais ensuite réutiliser une partie de la correction rapide que nous avons vue plus tôt :


les correctifs disponibles :

  - name : "Ajouter un enregistreur"
    actions :
      - addField :
          field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        \}}.class.getName())"
          cible : "self"


Notez la différence de cible par rapport à la première correction rapide. Celle-ci utilise self parce que notre Search correspondait à la classe. La première correction rapide utilise parentClass parce que nous avons trouvé du code dans la classe elle-même.

Résumé

Il s'agit de l'un des principaux flux associés à l'utilisation de Sensei pour améliorer vos compétences personnelles en matière de programmation :

  • créer une recette pour vous aider à mettre en œuvre votre "meilleure pratique" immédiate
  • une fois que vous savez comment utiliser cette meilleure pratique, créez une recette pour accélérer votre flux de travail.


---


Vous pouvez installer Sensei à partir d'IntelliJ en utilisant "Preferences \ Plugins" (Mac) ou "Settings \ Plugins" (Windows) puis en recherchant simplement "sensei secure code".


Le code source et les recettes se trouvent dans le dépôt `sensei-blog-examples` sur le compte GitHub Secure Code Warrior , dans le module `pojoexamples`.




Table des matières

Voir la ressource
Vous souhaitez en savoir plus ?

Alan Richardson a plus de vingt ans d'expérience professionnelle dans le domaine des technologies de l'information. Il a travaillé en tant que développeur et à tous les niveaux de la hiérarchie des tests, du testeur au responsable des tests. Responsable des relations avec les développeurs à l'adresse Secure Code Warrior, il travaille directement avec les équipes pour améliorer le développement de codes sécurisés de qualité. Alan est l'auteur de quatre livres, dont "Dear Evil Tester" et "Java For Testers". Alan a également créé une formation en ligne courses pour aider les gens à apprendre les tests techniques sur le Web et Selenium WebDriver avec Java. Alan publie ses écrits et ses vidéos de formation sur SeleniumSimplified.com, EvilTester.com, JavaForTesters.com et CompendiumDev.co.uk.

Secure Code Warrior est là pour vous aider à sécuriser le code tout au long du cycle de vie du développement logiciel et à créer une culture dans laquelle la cybersécurité est une priorité. Que vous soyez responsable AppSec, développeur, CISO ou toute autre personne impliquée dans la sécurité, nous pouvons aider votre organisation à réduire les risques associés à un code non sécurisé.

Réservez une démonstrationTélécharger
Partager sur :
Centre de ressources

Ressources pour vous aider à démarrer

Plus d'articles
Centre de ressources

Ressources pour vous aider à démarrer

Plus d'articles