Blog

Umstellung auf einen Logger mit Sensei

Alan Richardson
Veröffentlicht Nov 30, 2020

Umstellung auf einen Logger mit Sensei

Dieser Beitrag beschreibt die Erstellung eines Rezepts für die Umstellung von System.out.println auf die Verwendung eines Java-Loggers.

Wenn ich Code hacke, anstatt TDD zu verwenden, und ich Fehler mache, habe ich die schlechte Angewohnheit, eine Zeile in System.out zu drucken, und ich wollte mir diese Angewohnheit abgewöhnen.

Beim Schreiben des untenstehenden Codes habe ich einen Haufen Fehler gemacht:

   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;
    }


Ursprünglich habe ich countdown++ geschrieben und die Schleife wurde nicht beendet.

Und ich habe Countdown > 1 verwendet, also nicht die gewünschte Ausgabe erhalten.

Am Ende habe ich meinen Code mit System.out.println überhäuft, um mir beim Debuggen zu helfen. Und die Erfahrung hat mich darin bestärkt, dass ich lernen muss, einen Logger als Standardansatz zu verwenden.

Forschung

Glücklicherweise habe ich mir die Dokumentation vonSensei durchgelesen und mich für die Anleitung "Erste Schritte" entschieden, die mir bei der Erstellung eines Rezepts zur Konvertierung von System.out.println hilft und mich zur Verwendung eines Loggers ermutigt:

  • java.util.logging.Logger

Erstellen eines Rezepts

Als erstes klicke ich auf println und dann auf alt+enter, um ein neues Rezept zu erstellen.

System ausdrucken Ein neues Rezept erstellen


Ich erstelle sie mit den folgenden Angaben:


Name: Logger: Logger anstelle von println verwenden
Beschreibung: Logger statt println verwenden - denken Sie daran, System.out.println nicht mehr zu verwenden
Ebene: Fehler


Und ich beginne mit einem passenden Methodenaufruf mit dem Namen println


suchen:
  Methodenaufruf:
    Name: "println"

Und die Vorschau zeigt mir alle Übereinstimmungen in meinem Code.


Rezepteinstellungen Methodcall Println


Ich kann sehen, dass alle Übereinstimmungen in meinem Code für System.out.println sind, aber ich vertraue nicht darauf, dass dies auf lange Sicht die einzige Übereinstimmung sein wird. Ich möchte eine qualifiziertere Anweisung abgleichen, die ich ändern möchte.

Ich erweitere den Matcher, um nach einem Methodenaufruf auf ein Feld zu suchen, das in der Klasse System.


suchen:
  Methodenaufruf:
    Name: "println"
    "ein":
      Feld:
        in:
          Klasse:
            Name: "System"
        Name: "aus"



Ich könnte, wenn ich wollte, den Namen System vollständig zu java.lang.System qualifizieren

Rezepteinstellungen Methodcall name system

Ändern des Codes zum Protokollieren


Als nächstes möchte ich den QuickFix erstellen.

Zuerst möchte ich die Codezeile ändern, die die Ausgabe protokolliert:


availableFixes:
- Name: "Logger verwenden"
  Aktionen:
  - umschreiben:
      to: "logger.log(Level.INFO, {{{ arguments.0 }}})"



Ich muss mir das Format der Schnurrbartvorlage nicht merken. Ich benutzte die Funktion "Variablen anzeigen" in der GUI, um mir das Argument anzeigen zu lassen und doppelklickte es an. Dann füllte die GUI die entsprechende passende Schnurrbartvorlage aus.



Wenn ich es ausprobiere, kann ich sehen, dass ich immer noch alt+enter drücken muss, um das Level-Enum zu importieren. Wenn ich jedoch meinen QuickFix so ändere, dass er ein voll qualifiziertes Element enthält, fügt Sensei den Import für mich hinzu, z. B.

  • Sie ersetzt System.out.println(output); durch

logger.log(Level.INFO, output);

  • Und fügen Sie einen Import für das Enum hinzu:

import java.util.logging.Level;

  • Wenn ich umschreibe in:
logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})

Das wird auch funktionieren, aber ich muss mir immer noch die Syntax merken, um den Logger überhaupt erst zu instanziieren.

Syntax zum Instanziieren des Loggers an erster Stelle


Ändern des Codes zum Hinzufügen des Logger-Feldes

Ich kann meinen QuickFix ändern, um das Feld auch für mich zu erstellen.

Ich werde den Logger zuerst codieren und dann zu meinem Rezept hinzufügen, damit ich ihn nie wieder codieren muss.

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


Ich neige dazu, den Beispielcode, den ich generiert sehen möchte, zuerst zu schreiben, weil ich dann die IntelliJ-Codevervollständigung und die Syntaxprüfung verwenden kann, um sicherzustellen, dass ich ihn richtig hinbekomme. Als Nebeneffekt wird er dann in der Codevorschau angezeigt, wenn ich das Rezept bearbeite, um die QuickFix-Zeilen hinzuzufügen, die diesen Code erzeugen.

Und wenn ich den Beispielcode schreibe, möchte ich einen anderen Feldnamen verwenden (hier verwende ich logger2), denn Sensei ist schlau genug, um kein doppeltes Feld hinzuzufügen, also muss ich es mit einem anderen Namen täuschen.

Ich ändere also das Rezept, um diesen Code zu erstellen, indem ich ein Feld mit dem Namen logger hinzufüge.

availableFixes:

- Name: "Logger verwenden"
  Aktionen:
  - umschreiben:
      to: "logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})"
  - addField:
      field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        }}}.class.getName())"
      Ziel: "parentClass"


Beachten Sie, dass ich SysOutTest in eine Mustache-Variable geändert habe, damit sie den Namen jeder Klasse aufnimmt, in der ich dieses Rezept verwende. Und wieder habe ich mir die Mustache-Syntax nicht gemerkt, ich habe die GUI Show Variables benutzt, um den Ersatz zu finden, den ich brauchte.

Indem ich den Logger vollständig auf java.util.logging.Logger qualifiziere, fügt Sensei den Import hinzu und schreibt die Codezeile, die ich haben möchte, d.h.

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


Vollständige Qualifizierung des Loggers zu java.util.logging.Logger


Eine nützliche Sache an diesem Rezept ist, dass es das Logger-Feld nur einmal hinzufügt, so dass ich es auf jeden bestehenden Code anwenden kann, in dem ich `System.out.println` verwendet habe, und Sensei verwenden kann, um alle Vorkommen in meiner Codedatei zur gleichen Zeit zu ändern.


Logger verwenden Alle Probleme in der Datei beheben



Nächste Schritte

Sobald ich mich daran gewöhnt habe, werde ich mir irgendwann abgewöhnen, System.out.println zu verwenden.

Ich kann Sensei verwenden, um mir beim proaktiven Schreiben von Code zu helfen, indem ich ein zweites Rezept erstelle, das mir hilft, einen Logger zu erstellen.

Ich kann z. B. auf eine Klasse passen, in der es kein Feld namens Logger gibt, und eines hinzufügen.

Wenn ich ein Rezept der Ebene Information erstelle


Name: Logger: Logger hinzufügen

Beschreibung: Logger zur Klasse hinzufügen


Zum Anpassen an eine Klasse ohne Loggerfeld:

suchen:
  Klasse:
    ohne:
      Kind:
        Feld:
          Name: "Logger"


Und dann werde ich einen Teil des QuickFix wiederverwenden, den wir vorhin gesehen haben:


availableFixes:

  - name: "Logger hinzufügen"
    Aktionen:
      - addField:
          field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        }}}.class.getName())"
          Ziel: "selbst"


Beachten Sie den Unterschied im Ziel hier im Vergleich zum ersten QuickFix. Hier wird self verwendet, weil unsere Suche mit der Klasse übereinstimmt. Der erste QuickFix verwendet parentClass, weil wir Code innerhalb der Klasse selbst gefunden haben.

Zusammenfassung

Dies stellt einen der wichtigsten Abläufe dar, die mit der Verwendung von Sensei verbunden sind, um Ihre persönlichen Programmierkenntnisse zu verbessern:

  • ein Rezept erstellen, das Ihnen bei der unmittelbaren "besten Praxis" hilft
  • Sobald Sie wissen, wie Sie diese Best Practice anwenden können... erstellen Sie ein Rezept, um Ihren Arbeitsablauf zu beschleunigen


---


Sie können Sensei aus IntelliJ heraus über "Preferences \ Plugins" (Mac) oder "Settings \ Plugins" (Windows) installieren und dann einfach nach "sensei secure code" suchen.


Der Quellcode und die Rezepte dafür befinden sich im `sensei-blog-examples` Repository im Secure Code Warrior GitHub-Konto, im Modul `pojoexamples`.




Ressource anzeigen
Ressource anzeigen

Ein kurzes Beispiel für die Erstellung eines Rezepts zur Umstellung von System.out.println auf die Verwendung eines Java-Loggers.

Interessiert an mehr?

Alan Richardson verfügt über mehr als zwanzig Jahre Berufserfahrung in der IT-Branche. Er arbeitete als Entwickler und auf jeder Ebene der Testhierarchie, vom Tester bis hin zum Head of Testing. Als Head of Developer Relations bei Secure Code Warrior arbeitet er direkt mit Teams zusammen, um die Entwicklung von hochwertigem, sicherem Code zu verbessern. Alan ist der Autor von vier Büchern, darunter "Dear Evil Tester" und "Java For Testers". Alan hat auch Online-Schulungen courses erstellt, um Menschen beim Erlernen von technischen Web-Tests und Selenium WebDriver mit Java zu helfen. Alan veröffentlicht seine Schriften und Schulungsvideos auf SeleniumSimplified.com, EvilTester.com, JavaForTesters.com und CompendiumDev.co.uk.

Secure Code Warrior ist für Ihr Unternehmen da, um Sie dabei zu unterstützen, Ihren Code über den gesamten Lebenszyklus der Softwareentwicklung hinweg zu sichern und eine Kultur zu schaffen, in der Cybersicherheit an erster Stelle steht. Ganz gleich, ob Sie AppSec-Manager, Entwickler, CISO oder ein anderer Sicherheitsverantwortlicher sind, wir können Ihrem Unternehmen helfen, die mit unsicherem Code verbundenen Risiken zu reduzieren.

Demo buchen
Weitergeben:
Autor
Alan Richardson
Veröffentlicht Nov 30, 2020

Alan Richardson verfügt über mehr als zwanzig Jahre Berufserfahrung in der IT-Branche. Er arbeitete als Entwickler und auf jeder Ebene der Testhierarchie, vom Tester bis hin zum Head of Testing. Als Head of Developer Relations bei Secure Code Warrior arbeitet er direkt mit Teams zusammen, um die Entwicklung von hochwertigem, sicherem Code zu verbessern. Alan ist der Autor von vier Büchern, darunter "Dear Evil Tester" und "Java For Testers". Alan hat auch Online-Schulungen courses erstellt, um Menschen beim Erlernen von technischen Web-Tests und Selenium WebDriver mit Java zu helfen. Alan veröffentlicht seine Schriften und Schulungsvideos auf SeleniumSimplified.com, EvilTester.com, JavaForTesters.com und CompendiumDev.co.uk.

Weitergeben:

Umstellung auf einen Logger mit Sensei

Dieser Beitrag beschreibt die Erstellung eines Rezepts für die Umstellung von System.out.println auf die Verwendung eines Java-Loggers.

Wenn ich Code hacke, anstatt TDD zu verwenden, und ich Fehler mache, habe ich die schlechte Angewohnheit, eine Zeile in System.out zu drucken, und ich wollte mir diese Angewohnheit abgewöhnen.

Beim Schreiben des untenstehenden Codes habe ich einen Haufen Fehler gemacht:

   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;
    }


Ursprünglich habe ich countdown++ geschrieben und die Schleife wurde nicht beendet.

Und ich habe Countdown > 1 verwendet, also nicht die gewünschte Ausgabe erhalten.

Am Ende habe ich meinen Code mit System.out.println überhäuft, um mir beim Debuggen zu helfen. Und die Erfahrung hat mich darin bestärkt, dass ich lernen muss, einen Logger als Standardansatz zu verwenden.

Forschung

Glücklicherweise habe ich mir die Dokumentation vonSensei durchgelesen und mich für die Anleitung "Erste Schritte" entschieden, die mir bei der Erstellung eines Rezepts zur Konvertierung von System.out.println hilft und mich zur Verwendung eines Loggers ermutigt:

  • java.util.logging.Logger

Erstellen eines Rezepts

Als erstes klicke ich auf println und dann auf alt+enter, um ein neues Rezept zu erstellen.

System ausdrucken Ein neues Rezept erstellen


Ich erstelle sie mit den folgenden Angaben:


Name: Logger: Logger anstelle von println verwenden
Beschreibung: Logger statt println verwenden - denken Sie daran, System.out.println nicht mehr zu verwenden
Ebene: Fehler


Und ich beginne mit einem passenden Methodenaufruf mit dem Namen println


suchen:
  Methodenaufruf:
    Name: "println"

Und die Vorschau zeigt mir alle Übereinstimmungen in meinem Code.


Rezepteinstellungen Methodcall Println


Ich kann sehen, dass alle Übereinstimmungen in meinem Code für System.out.println sind, aber ich vertraue nicht darauf, dass dies auf lange Sicht die einzige Übereinstimmung sein wird. Ich möchte eine qualifiziertere Anweisung abgleichen, die ich ändern möchte.

Ich erweitere den Matcher, um nach einem Methodenaufruf auf ein Feld zu suchen, das in der Klasse System.


suchen:
  Methodenaufruf:
    Name: "println"
    "ein":
      Feld:
        in:
          Klasse:
            Name: "System"
        Name: "aus"



Ich könnte, wenn ich wollte, den Namen System vollständig zu java.lang.System qualifizieren

Rezepteinstellungen Methodcall name system

Ändern des Codes zum Protokollieren


Als nächstes möchte ich den QuickFix erstellen.

Zuerst möchte ich die Codezeile ändern, die die Ausgabe protokolliert:


availableFixes:
- Name: "Logger verwenden"
  Aktionen:
  - umschreiben:
      to: "logger.log(Level.INFO, {{{ arguments.0 }}})"



Ich muss mir das Format der Schnurrbartvorlage nicht merken. Ich benutzte die Funktion "Variablen anzeigen" in der GUI, um mir das Argument anzeigen zu lassen und doppelklickte es an. Dann füllte die GUI die entsprechende passende Schnurrbartvorlage aus.



Wenn ich es ausprobiere, kann ich sehen, dass ich immer noch alt+enter drücken muss, um das Level-Enum zu importieren. Wenn ich jedoch meinen QuickFix so ändere, dass er ein voll qualifiziertes Element enthält, fügt Sensei den Import für mich hinzu, z. B.

  • Sie ersetzt System.out.println(output); durch

logger.log(Level.INFO, output);

  • Und fügen Sie einen Import für das Enum hinzu:

import java.util.logging.Level;

  • Wenn ich umschreibe in:
logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})

Das wird auch funktionieren, aber ich muss mir immer noch die Syntax merken, um den Logger überhaupt erst zu instanziieren.

Syntax zum Instanziieren des Loggers an erster Stelle


Ändern des Codes zum Hinzufügen des Logger-Feldes

Ich kann meinen QuickFix ändern, um das Feld auch für mich zu erstellen.

Ich werde den Logger zuerst codieren und dann zu meinem Rezept hinzufügen, damit ich ihn nie wieder codieren muss.

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


Ich neige dazu, den Beispielcode, den ich generiert sehen möchte, zuerst zu schreiben, weil ich dann die IntelliJ-Codevervollständigung und die Syntaxprüfung verwenden kann, um sicherzustellen, dass ich ihn richtig hinbekomme. Als Nebeneffekt wird er dann in der Codevorschau angezeigt, wenn ich das Rezept bearbeite, um die QuickFix-Zeilen hinzuzufügen, die diesen Code erzeugen.

Und wenn ich den Beispielcode schreibe, möchte ich einen anderen Feldnamen verwenden (hier verwende ich logger2), denn Sensei ist schlau genug, um kein doppeltes Feld hinzuzufügen, also muss ich es mit einem anderen Namen täuschen.

Ich ändere also das Rezept, um diesen Code zu erstellen, indem ich ein Feld mit dem Namen logger hinzufüge.

availableFixes:

- Name: "Logger verwenden"
  Aktionen:
  - umschreiben:
      to: "logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})"
  - addField:
      field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        }}}.class.getName())"
      Ziel: "parentClass"


Beachten Sie, dass ich SysOutTest in eine Mustache-Variable geändert habe, damit sie den Namen jeder Klasse aufnimmt, in der ich dieses Rezept verwende. Und wieder habe ich mir die Mustache-Syntax nicht gemerkt, ich habe die GUI Show Variables benutzt, um den Ersatz zu finden, den ich brauchte.

Indem ich den Logger vollständig auf java.util.logging.Logger qualifiziere, fügt Sensei den Import hinzu und schreibt die Codezeile, die ich haben möchte, d.h.

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


Vollständige Qualifizierung des Loggers zu java.util.logging.Logger


Eine nützliche Sache an diesem Rezept ist, dass es das Logger-Feld nur einmal hinzufügt, so dass ich es auf jeden bestehenden Code anwenden kann, in dem ich `System.out.println` verwendet habe, und Sensei verwenden kann, um alle Vorkommen in meiner Codedatei zur gleichen Zeit zu ändern.


Logger verwenden Alle Probleme in der Datei beheben



Nächste Schritte

Sobald ich mich daran gewöhnt habe, werde ich mir irgendwann abgewöhnen, System.out.println zu verwenden.

Ich kann Sensei verwenden, um mir beim proaktiven Schreiben von Code zu helfen, indem ich ein zweites Rezept erstelle, das mir hilft, einen Logger zu erstellen.

Ich kann z. B. auf eine Klasse passen, in der es kein Feld namens Logger gibt, und eines hinzufügen.

Wenn ich ein Rezept der Ebene Information erstelle


Name: Logger: Logger hinzufügen

Beschreibung: Logger zur Klasse hinzufügen


Zum Anpassen an eine Klasse ohne Loggerfeld:

suchen:
  Klasse:
    ohne:
      Kind:
        Feld:
          Name: "Logger"


Und dann werde ich einen Teil des QuickFix wiederverwenden, den wir vorhin gesehen haben:


availableFixes:

  - name: "Logger hinzufügen"
    Aktionen:
      - addField:
          field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        }}}.class.getName())"
          Ziel: "selbst"


Beachten Sie den Unterschied im Ziel hier im Vergleich zum ersten QuickFix. Hier wird self verwendet, weil unsere Suche mit der Klasse übereinstimmt. Der erste QuickFix verwendet parentClass, weil wir Code innerhalb der Klasse selbst gefunden haben.

Zusammenfassung

Dies stellt einen der wichtigsten Abläufe dar, die mit der Verwendung von Sensei verbunden sind, um Ihre persönlichen Programmierkenntnisse zu verbessern:

  • ein Rezept erstellen, das Ihnen bei der unmittelbaren "besten Praxis" hilft
  • Sobald Sie wissen, wie Sie diese Best Practice anwenden können... erstellen Sie ein Rezept, um Ihren Arbeitsablauf zu beschleunigen


---


Sie können Sensei aus IntelliJ heraus über "Preferences \ Plugins" (Mac) oder "Settings \ Plugins" (Windows) installieren und dann einfach nach "sensei secure code" suchen.


Der Quellcode und die Rezepte dafür befinden sich im `sensei-blog-examples` Repository im Secure Code Warrior GitHub-Konto, im Modul `pojoexamples`.




Ressource anzeigen
Ressource anzeigen

Füllen Sie das folgende Formular aus, um den Bericht herunterzuladen

Wir bitten Sie um Ihre Erlaubnis, Ihnen Informationen über unsere Produkte und/oder verwandte Themen der sicheren Codierung zuzusenden. Wir werden Ihre persönlichen Daten immer mit äußerster Sorgfalt behandeln und sie niemals zu Marketingzwecken an andere Unternehmen verkaufen.

Senden
Um das Formular abzuschicken, aktivieren Sie bitte "Analytics"-Cookies. Sie können die Cookies wieder deaktivieren, sobald Sie fertig sind.

Umstellung auf einen Logger mit Sensei

Dieser Beitrag beschreibt die Erstellung eines Rezepts für die Umstellung von System.out.println auf die Verwendung eines Java-Loggers.

Wenn ich Code hacke, anstatt TDD zu verwenden, und ich Fehler mache, habe ich die schlechte Angewohnheit, eine Zeile in System.out zu drucken, und ich wollte mir diese Angewohnheit abgewöhnen.

Beim Schreiben des untenstehenden Codes habe ich einen Haufen Fehler gemacht:

   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;
    }


Ursprünglich habe ich countdown++ geschrieben und die Schleife wurde nicht beendet.

Und ich habe Countdown > 1 verwendet, also nicht die gewünschte Ausgabe erhalten.

Am Ende habe ich meinen Code mit System.out.println überhäuft, um mir beim Debuggen zu helfen. Und die Erfahrung hat mich darin bestärkt, dass ich lernen muss, einen Logger als Standardansatz zu verwenden.

Forschung

Glücklicherweise habe ich mir die Dokumentation vonSensei durchgelesen und mich für die Anleitung "Erste Schritte" entschieden, die mir bei der Erstellung eines Rezepts zur Konvertierung von System.out.println hilft und mich zur Verwendung eines Loggers ermutigt:

  • java.util.logging.Logger

Erstellen eines Rezepts

Als erstes klicke ich auf println und dann auf alt+enter, um ein neues Rezept zu erstellen.

System ausdrucken Ein neues Rezept erstellen


Ich erstelle sie mit den folgenden Angaben:


Name: Logger: Logger anstelle von println verwenden
Beschreibung: Logger statt println verwenden - denken Sie daran, System.out.println nicht mehr zu verwenden
Ebene: Fehler


Und ich beginne mit einem passenden Methodenaufruf mit dem Namen println


suchen:
  Methodenaufruf:
    Name: "println"

Und die Vorschau zeigt mir alle Übereinstimmungen in meinem Code.


Rezepteinstellungen Methodcall Println


Ich kann sehen, dass alle Übereinstimmungen in meinem Code für System.out.println sind, aber ich vertraue nicht darauf, dass dies auf lange Sicht die einzige Übereinstimmung sein wird. Ich möchte eine qualifiziertere Anweisung abgleichen, die ich ändern möchte.

Ich erweitere den Matcher, um nach einem Methodenaufruf auf ein Feld zu suchen, das in der Klasse System.


suchen:
  Methodenaufruf:
    Name: "println"
    "ein":
      Feld:
        in:
          Klasse:
            Name: "System"
        Name: "aus"



Ich könnte, wenn ich wollte, den Namen System vollständig zu java.lang.System qualifizieren

Rezepteinstellungen Methodcall name system

Ändern des Codes zum Protokollieren


Als nächstes möchte ich den QuickFix erstellen.

Zuerst möchte ich die Codezeile ändern, die die Ausgabe protokolliert:


availableFixes:
- Name: "Logger verwenden"
  Aktionen:
  - umschreiben:
      to: "logger.log(Level.INFO, {{{ arguments.0 }}})"



Ich muss mir das Format der Schnurrbartvorlage nicht merken. Ich benutzte die Funktion "Variablen anzeigen" in der GUI, um mir das Argument anzeigen zu lassen und doppelklickte es an. Dann füllte die GUI die entsprechende passende Schnurrbartvorlage aus.



Wenn ich es ausprobiere, kann ich sehen, dass ich immer noch alt+enter drücken muss, um das Level-Enum zu importieren. Wenn ich jedoch meinen QuickFix so ändere, dass er ein voll qualifiziertes Element enthält, fügt Sensei den Import für mich hinzu, z. B.

  • Sie ersetzt System.out.println(output); durch

logger.log(Level.INFO, output);

  • Und fügen Sie einen Import für das Enum hinzu:

import java.util.logging.Level;

  • Wenn ich umschreibe in:
logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})

Das wird auch funktionieren, aber ich muss mir immer noch die Syntax merken, um den Logger überhaupt erst zu instanziieren.

Syntax zum Instanziieren des Loggers an erster Stelle


Ändern des Codes zum Hinzufügen des Logger-Feldes

Ich kann meinen QuickFix ändern, um das Feld auch für mich zu erstellen.

Ich werde den Logger zuerst codieren und dann zu meinem Rezept hinzufügen, damit ich ihn nie wieder codieren muss.

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


Ich neige dazu, den Beispielcode, den ich generiert sehen möchte, zuerst zu schreiben, weil ich dann die IntelliJ-Codevervollständigung und die Syntaxprüfung verwenden kann, um sicherzustellen, dass ich ihn richtig hinbekomme. Als Nebeneffekt wird er dann in der Codevorschau angezeigt, wenn ich das Rezept bearbeite, um die QuickFix-Zeilen hinzuzufügen, die diesen Code erzeugen.

Und wenn ich den Beispielcode schreibe, möchte ich einen anderen Feldnamen verwenden (hier verwende ich logger2), denn Sensei ist schlau genug, um kein doppeltes Feld hinzuzufügen, also muss ich es mit einem anderen Namen täuschen.

Ich ändere also das Rezept, um diesen Code zu erstellen, indem ich ein Feld mit dem Namen logger hinzufüge.

availableFixes:

- Name: "Logger verwenden"
  Aktionen:
  - umschreiben:
      to: "logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})"
  - addField:
      field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        }}}.class.getName())"
      Ziel: "parentClass"


Beachten Sie, dass ich SysOutTest in eine Mustache-Variable geändert habe, damit sie den Namen jeder Klasse aufnimmt, in der ich dieses Rezept verwende. Und wieder habe ich mir die Mustache-Syntax nicht gemerkt, ich habe die GUI Show Variables benutzt, um den Ersatz zu finden, den ich brauchte.

Indem ich den Logger vollständig auf java.util.logging.Logger qualifiziere, fügt Sensei den Import hinzu und schreibt die Codezeile, die ich haben möchte, d.h.

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


Vollständige Qualifizierung des Loggers zu java.util.logging.Logger


Eine nützliche Sache an diesem Rezept ist, dass es das Logger-Feld nur einmal hinzufügt, so dass ich es auf jeden bestehenden Code anwenden kann, in dem ich `System.out.println` verwendet habe, und Sensei verwenden kann, um alle Vorkommen in meiner Codedatei zur gleichen Zeit zu ändern.


Logger verwenden Alle Probleme in der Datei beheben



Nächste Schritte

Sobald ich mich daran gewöhnt habe, werde ich mir irgendwann abgewöhnen, System.out.println zu verwenden.

Ich kann Sensei verwenden, um mir beim proaktiven Schreiben von Code zu helfen, indem ich ein zweites Rezept erstelle, das mir hilft, einen Logger zu erstellen.

Ich kann z. B. auf eine Klasse passen, in der es kein Feld namens Logger gibt, und eines hinzufügen.

Wenn ich ein Rezept der Ebene Information erstelle


Name: Logger: Logger hinzufügen

Beschreibung: Logger zur Klasse hinzufügen


Zum Anpassen an eine Klasse ohne Loggerfeld:

suchen:
  Klasse:
    ohne:
      Kind:
        Feld:
          Name: "Logger"


Und dann werde ich einen Teil des QuickFix wiederverwenden, den wir vorhin gesehen haben:


availableFixes:

  - name: "Logger hinzufügen"
    Aktionen:
      - addField:
          field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        }}}.class.getName())"
          Ziel: "selbst"


Beachten Sie den Unterschied im Ziel hier im Vergleich zum ersten QuickFix. Hier wird self verwendet, weil unsere Suche mit der Klasse übereinstimmt. Der erste QuickFix verwendet parentClass, weil wir Code innerhalb der Klasse selbst gefunden haben.

Zusammenfassung

Dies stellt einen der wichtigsten Abläufe dar, die mit der Verwendung von Sensei verbunden sind, um Ihre persönlichen Programmierkenntnisse zu verbessern:

  • ein Rezept erstellen, das Ihnen bei der unmittelbaren "besten Praxis" hilft
  • Sobald Sie wissen, wie Sie diese Best Practice anwenden können... erstellen Sie ein Rezept, um Ihren Arbeitsablauf zu beschleunigen


---


Sie können Sensei aus IntelliJ heraus über "Preferences \ Plugins" (Mac) oder "Settings \ Plugins" (Windows) installieren und dann einfach nach "sensei secure code" suchen.


Der Quellcode und die Rezepte dafür befinden sich im `sensei-blog-examples` Repository im Secure Code Warrior GitHub-Konto, im Modul `pojoexamples`.




Auf Ressource zugreifen

Klicken Sie auf den unten stehenden Link und laden Sie die PDF-Datei dieser Ressource herunter.

Secure Code Warrior ist für Ihr Unternehmen da, um Sie dabei zu unterstützen, Ihren Code über den gesamten Lebenszyklus der Softwareentwicklung hinweg zu sichern und eine Kultur zu schaffen, in der Cybersicherheit an erster Stelle steht. Ganz gleich, ob Sie AppSec-Manager, Entwickler, CISO oder ein anderer Sicherheitsverantwortlicher sind, wir können Ihrem Unternehmen helfen, die mit unsicherem Code verbundenen Risiken zu reduzieren.

Bericht ansehenDemo buchen
Weitergeben:
Interessiert an mehr?

Weitergeben:
Autor
Alan Richardson
Veröffentlicht Nov 30, 2020

Alan Richardson verfügt über mehr als zwanzig Jahre Berufserfahrung in der IT-Branche. Er arbeitete als Entwickler und auf jeder Ebene der Testhierarchie, vom Tester bis hin zum Head of Testing. Als Head of Developer Relations bei Secure Code Warrior arbeitet er direkt mit Teams zusammen, um die Entwicklung von hochwertigem, sicherem Code zu verbessern. Alan ist der Autor von vier Büchern, darunter "Dear Evil Tester" und "Java For Testers". Alan hat auch Online-Schulungen courses erstellt, um Menschen beim Erlernen von technischen Web-Tests und Selenium WebDriver mit Java zu helfen. Alan veröffentlicht seine Schriften und Schulungsvideos auf SeleniumSimplified.com, EvilTester.com, JavaForTesters.com und CompendiumDev.co.uk.

Weitergeben:

Umstellung auf einen Logger mit Sensei

Dieser Beitrag beschreibt die Erstellung eines Rezepts für die Umstellung von System.out.println auf die Verwendung eines Java-Loggers.

Wenn ich Code hacke, anstatt TDD zu verwenden, und ich Fehler mache, habe ich die schlechte Angewohnheit, eine Zeile in System.out zu drucken, und ich wollte mir diese Angewohnheit abgewöhnen.

Beim Schreiben des untenstehenden Codes habe ich einen Haufen Fehler gemacht:

   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;
    }


Ursprünglich habe ich countdown++ geschrieben und die Schleife wurde nicht beendet.

Und ich habe Countdown > 1 verwendet, also nicht die gewünschte Ausgabe erhalten.

Am Ende habe ich meinen Code mit System.out.println überhäuft, um mir beim Debuggen zu helfen. Und die Erfahrung hat mich darin bestärkt, dass ich lernen muss, einen Logger als Standardansatz zu verwenden.

Forschung

Glücklicherweise habe ich mir die Dokumentation vonSensei durchgelesen und mich für die Anleitung "Erste Schritte" entschieden, die mir bei der Erstellung eines Rezepts zur Konvertierung von System.out.println hilft und mich zur Verwendung eines Loggers ermutigt:

  • java.util.logging.Logger

Erstellen eines Rezepts

Als erstes klicke ich auf println und dann auf alt+enter, um ein neues Rezept zu erstellen.

System ausdrucken Ein neues Rezept erstellen


Ich erstelle sie mit den folgenden Angaben:


Name: Logger: Logger anstelle von println verwenden
Beschreibung: Logger statt println verwenden - denken Sie daran, System.out.println nicht mehr zu verwenden
Ebene: Fehler


Und ich beginne mit einem passenden Methodenaufruf mit dem Namen println


suchen:
  Methodenaufruf:
    Name: "println"

Und die Vorschau zeigt mir alle Übereinstimmungen in meinem Code.


Rezepteinstellungen Methodcall Println


Ich kann sehen, dass alle Übereinstimmungen in meinem Code für System.out.println sind, aber ich vertraue nicht darauf, dass dies auf lange Sicht die einzige Übereinstimmung sein wird. Ich möchte eine qualifiziertere Anweisung abgleichen, die ich ändern möchte.

Ich erweitere den Matcher, um nach einem Methodenaufruf auf ein Feld zu suchen, das in der Klasse System.


suchen:
  Methodenaufruf:
    Name: "println"
    "ein":
      Feld:
        in:
          Klasse:
            Name: "System"
        Name: "aus"



Ich könnte, wenn ich wollte, den Namen System vollständig zu java.lang.System qualifizieren

Rezepteinstellungen Methodcall name system

Ändern des Codes zum Protokollieren


Als nächstes möchte ich den QuickFix erstellen.

Zuerst möchte ich die Codezeile ändern, die die Ausgabe protokolliert:


availableFixes:
- Name: "Logger verwenden"
  Aktionen:
  - umschreiben:
      to: "logger.log(Level.INFO, {{{ arguments.0 }}})"



Ich muss mir das Format der Schnurrbartvorlage nicht merken. Ich benutzte die Funktion "Variablen anzeigen" in der GUI, um mir das Argument anzeigen zu lassen und doppelklickte es an. Dann füllte die GUI die entsprechende passende Schnurrbartvorlage aus.



Wenn ich es ausprobiere, kann ich sehen, dass ich immer noch alt+enter drücken muss, um das Level-Enum zu importieren. Wenn ich jedoch meinen QuickFix so ändere, dass er ein voll qualifiziertes Element enthält, fügt Sensei den Import für mich hinzu, z. B.

  • Sie ersetzt System.out.println(output); durch

logger.log(Level.INFO, output);

  • Und fügen Sie einen Import für das Enum hinzu:

import java.util.logging.Level;

  • Wenn ich umschreibe in:
logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})

Das wird auch funktionieren, aber ich muss mir immer noch die Syntax merken, um den Logger überhaupt erst zu instanziieren.

Syntax zum Instanziieren des Loggers an erster Stelle


Ändern des Codes zum Hinzufügen des Logger-Feldes

Ich kann meinen QuickFix ändern, um das Feld auch für mich zu erstellen.

Ich werde den Logger zuerst codieren und dann zu meinem Rezept hinzufügen, damit ich ihn nie wieder codieren muss.

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


Ich neige dazu, den Beispielcode, den ich generiert sehen möchte, zuerst zu schreiben, weil ich dann die IntelliJ-Codevervollständigung und die Syntaxprüfung verwenden kann, um sicherzustellen, dass ich ihn richtig hinbekomme. Als Nebeneffekt wird er dann in der Codevorschau angezeigt, wenn ich das Rezept bearbeite, um die QuickFix-Zeilen hinzuzufügen, die diesen Code erzeugen.

Und wenn ich den Beispielcode schreibe, möchte ich einen anderen Feldnamen verwenden (hier verwende ich logger2), denn Sensei ist schlau genug, um kein doppeltes Feld hinzuzufügen, also muss ich es mit einem anderen Namen täuschen.

Ich ändere also das Rezept, um diesen Code zu erstellen, indem ich ein Feld mit dem Namen logger hinzufüge.

availableFixes:

- Name: "Logger verwenden"
  Aktionen:
  - umschreiben:
      to: "logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})"
  - addField:
      field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        }}}.class.getName())"
      Ziel: "parentClass"


Beachten Sie, dass ich SysOutTest in eine Mustache-Variable geändert habe, damit sie den Namen jeder Klasse aufnimmt, in der ich dieses Rezept verwende. Und wieder habe ich mir die Mustache-Syntax nicht gemerkt, ich habe die GUI Show Variables benutzt, um den Ersatz zu finden, den ich brauchte.

Indem ich den Logger vollständig auf java.util.logging.Logger qualifiziere, fügt Sensei den Import hinzu und schreibt die Codezeile, die ich haben möchte, d.h.

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


Vollständige Qualifizierung des Loggers zu java.util.logging.Logger


Eine nützliche Sache an diesem Rezept ist, dass es das Logger-Feld nur einmal hinzufügt, so dass ich es auf jeden bestehenden Code anwenden kann, in dem ich `System.out.println` verwendet habe, und Sensei verwenden kann, um alle Vorkommen in meiner Codedatei zur gleichen Zeit zu ändern.


Logger verwenden Alle Probleme in der Datei beheben



Nächste Schritte

Sobald ich mich daran gewöhnt habe, werde ich mir irgendwann abgewöhnen, System.out.println zu verwenden.

Ich kann Sensei verwenden, um mir beim proaktiven Schreiben von Code zu helfen, indem ich ein zweites Rezept erstelle, das mir hilft, einen Logger zu erstellen.

Ich kann z. B. auf eine Klasse passen, in der es kein Feld namens Logger gibt, und eines hinzufügen.

Wenn ich ein Rezept der Ebene Information erstelle


Name: Logger: Logger hinzufügen

Beschreibung: Logger zur Klasse hinzufügen


Zum Anpassen an eine Klasse ohne Loggerfeld:

suchen:
  Klasse:
    ohne:
      Kind:
        Feld:
          Name: "Logger"


Und dann werde ich einen Teil des QuickFix wiederverwenden, den wir vorhin gesehen haben:


availableFixes:

  - name: "Logger hinzufügen"
    Aktionen:
      - addField:
          field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
        }}}.class.getName())"
          Ziel: "selbst"


Beachten Sie den Unterschied im Ziel hier im Vergleich zum ersten QuickFix. Hier wird self verwendet, weil unsere Suche mit der Klasse übereinstimmt. Der erste QuickFix verwendet parentClass, weil wir Code innerhalb der Klasse selbst gefunden haben.

Zusammenfassung

Dies stellt einen der wichtigsten Abläufe dar, die mit der Verwendung von Sensei verbunden sind, um Ihre persönlichen Programmierkenntnisse zu verbessern:

  • ein Rezept erstellen, das Ihnen bei der unmittelbaren "besten Praxis" hilft
  • Sobald Sie wissen, wie Sie diese Best Practice anwenden können... erstellen Sie ein Rezept, um Ihren Arbeitsablauf zu beschleunigen


---


Sie können Sensei aus IntelliJ heraus über "Preferences \ Plugins" (Mac) oder "Settings \ Plugins" (Windows) installieren und dann einfach nach "sensei secure code" suchen.


Der Quellcode und die Rezepte dafür befinden sich im `sensei-blog-examples` Repository im Secure Code Warrior GitHub-Konto, im Modul `pojoexamples`.




Inhaltsübersicht

Ressource anzeigen
Interessiert an mehr?

Alan Richardson verfügt über mehr als zwanzig Jahre Berufserfahrung in der IT-Branche. Er arbeitete als Entwickler und auf jeder Ebene der Testhierarchie, vom Tester bis hin zum Head of Testing. Als Head of Developer Relations bei Secure Code Warrior arbeitet er direkt mit Teams zusammen, um die Entwicklung von hochwertigem, sicherem Code zu verbessern. Alan ist der Autor von vier Büchern, darunter "Dear Evil Tester" und "Java For Testers". Alan hat auch Online-Schulungen courses erstellt, um Menschen beim Erlernen von technischen Web-Tests und Selenium WebDriver mit Java zu helfen. Alan veröffentlicht seine Schriften und Schulungsvideos auf SeleniumSimplified.com, EvilTester.com, JavaForTesters.com und CompendiumDev.co.uk.

Secure Code Warrior ist für Ihr Unternehmen da, um Sie dabei zu unterstützen, Ihren Code über den gesamten Lebenszyklus der Softwareentwicklung hinweg zu sichern und eine Kultur zu schaffen, in der Cybersicherheit an erster Stelle steht. Ganz gleich, ob Sie AppSec-Manager, Entwickler, CISO oder ein anderer Sicherheitsverantwortlicher sind, wir können Ihrem Unternehmen helfen, die mit unsicherem Code verbundenen Risiken zu reduzieren.

Demo buchenHerunterladen
Weitergeben:
Ressourcendrehscheibe

Ressourcen für den Einstieg

Mehr Beiträge
Ressourcendrehscheibe

Ressourcen für den Einstieg

Mehr Beiträge