Umstellung auf einen Logger mit Sensei
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.
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.
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
Ä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.
Ä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());
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.
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`.
Ein kurzes Beispiel für die Erstellung eines Rezepts zur Umstellung von System.out.println auf die Verwendung eines Java-Loggers.
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 buchenAlan 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.
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.
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.
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
Ä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.
Ä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());
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.
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`.
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.
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.
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
Ä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.
Ä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());
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.
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`.
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 buchenAlan 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.
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.
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.
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
Ä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.
Ä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());
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.
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
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 buchenHerunterladenRessourcen für den Einstieg
Benchmarking von Sicherheitskompetenzen: Optimierung von Secure-by-Design im Unternehmen
Die Secure-by-Design-Bewegung ist die Zukunft der sicheren Softwareentwicklung. Erfahren Sie mehr über die wichtigsten Elemente, die Unternehmen berücksichtigen müssen, wenn sie über eine Secure-by-Design-Initiative nachdenken.
DigitalOcean verringert Sicherheitsverschuldung mit Secure Code Warrior
DigitalOceans Einsatz von Secure Code Warrior hat die Sicherheitsverschuldung deutlich reduziert, so dass sich die Teams stärker auf Innovation und Produktivität konzentrieren können. Die verbesserte Sicherheit hat die Produktqualität und den Wettbewerbsvorteil des Unternehmens gestärkt. Mit Blick auf die Zukunft wird der SCW Trust Score dem Unternehmen helfen, seine Sicherheitspraktiken weiter zu verbessern und Innovationen voranzutreiben.
Ressourcen für den Einstieg
Trust Score zeigt den Wert von Secure-by-Design-Upskilling-Initiativen
Unsere Forschung hat gezeigt, dass Schulungen für sicheren Code funktionieren. Trust Score verwendet einen Algorithmus, der auf mehr als 20 Millionen Lerndaten aus der Arbeit von mehr als 250.000 Lernenden in über 600 Organisationen basiert, und zeigt, wie effektiv die Initiative ist, um Schwachstellen zu beseitigen und wie man sie noch effektiver gestalten kann.
Reaktive versus präventive Sicherheit: Prävention ist das bessere Heilmittel
Der Gedanke, Legacy-Code und -Systeme zur gleichen Zeit wie neuere Anwendungen mit präventiver Sicherheit auszustatten, kann entmutigend erscheinen, aber ein Secure-by-Design-Ansatz, der durch die Weiterbildung von Entwicklern durchgesetzt wird, kann die besten Sicherheitsverfahren auf diese Systeme anwenden. Dies ist für viele Unternehmen die beste Chance, ihre Sicherheitslage zu verbessern.
Die Vorteile eines Benchmarking der Sicherheitskompetenzen von Entwicklern
Der zunehmende Fokus auf sicheren Code und Secure-by-Design-Prinzipien erfordert, dass Entwickler von Beginn des SDLC an in Cybersicherheit geschult werden, wobei Tools wie Secure Code Warrior's Trust Score dabei helfen, ihre Fortschritte zu messen und zu verbessern.
Wesentlicher Erfolg für Enterprise Secure-by-Design-Initiativen
Unser jüngstes Forschungspapier „Benchmarking Security Skills: Streamlining Secure-by-Design in the Enterprise“ ist das Ergebnis einer umfassenden Analyse echter Secure-by-Design-Initiativen auf Unternehmensebene und der Ableitung von Best-Practice-Ansätzen auf Grundlage datengesteuerter Erkenntnisse.