Migración a un registrador con Sensei
Migración a un registrador con Sensei
Este post describe la creación de una receta para migrar de System.out.println a usar un Logger de Java.
Cuando estoy hackeando el código, en lugar de usar TDD, y cometo errores, tengo la mala costumbre de imprimir una línea en System.out, y he querido despojarme de ese hábito.
He cometido un montón de errores al escribir el código de abajo :
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;
}
Inicialmente, escribí countdown++ y el bucle no terminó.
Y usé la cuenta atrás > 1 por lo que no obtuve la salida que quería.
Al final, llené mi código con System.out.println para ayudarme a depurar. Y la experiencia reforzó que necesito aprender a usar un registrador como mi enfoque por defecto.
Investigar
Afortunadamente, leí la documentación deSensei y decidí usar la guía "Getting Started" para ayudarme a crear una receta para convertir de System.out.println y animarme a usar un registrador:
- java.util.logging.Logger
Creación de una receta
Lo primero que hago es pulsar el println y luego alt+enter para crear una nueva receta.

Lo creo con los siguientes datos:
Nombre: Logger: utilizar logger en lugar de println
Descripción: utilizar logger en lugar de println - recuerde dejar de utilizar System.out.println
Nivel: Error
Y voy a empezar por hacer coincidir methodcall con el nombre println
buscar:
methodcall:
nombre: "println"
Y la vista previa me muestra todas las coincidencias de mi código.

Puedo ver que todas las coincidencias en mi código son para System.out.println pero no confío en que a largo plazo esta sea la única coincidencia. Quiero que coincida con una declaración más calificada que quiero cambiar.
Amplío el matcher para buscar un methodcall en un campo nombrado en la clase System.
buscar:
methodcall:
nombre: "println"
"on":
campo:
en:
clase:
nombre: "Sistema"
nombre: "out"
Podría, si quisiera, calificar completamente el nombre System a java.lang.System

Modificación del Código para registrar
A continuación, quiero crear el QuickFix.
Primero quiero modificar la línea de código que registra la salida:
availableFixes:
- nombre: "use Logger"
acciones:
- Reescritura:
to: "logger.log(Level.INFO, {{{ arguments.0 }}})"
No tengo que recordar el formato de la plantilla del bigote. Utilicé la opción de mostrar variables en la interfaz gráfica de usuario para que me mostrara el argumento y hice doble clic en él. Entonces la GUI rellenó la plantilla de bigote correspondiente.

Cuando lo pruebo, veo que todavía tengo que pulsar alt+enter para importar el Level enum. Pero si modifico mi QuickFix para que tenga un elemento totalmente cualificado, entonces Sensei añadirá la importación por mí, por ejemplo
- Sustituirá System.out.println(output); por
logger.log(Level.INFO, output);
- Y añade una importación para el enum:
import java.util.logging.Level;
- Si vuelvo a escribir a:
logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})
Y esto funcionará, pero todavía tendré que recordar la sintaxis para instanciar el registrador en primer lugar.

Modificación del código para añadir el campo de registro
Puedo modificar mi QuickFix para que me cree el campo también.
Primero codificaré el registrador y luego lo añadiré a mi receta para no tener que volver a codificarlo.
Logger2 = Logger.getLogger(SysOutTest.class.getName());
Suelo escribir primero el código de ejemplo que quiero que se genere porque así puedo utilizar el completamiento de código de IntelliJ y la comprobación de sintaxis para asegurarme de que lo hago bien. Como efecto secundario, luego estará en la vista previa del código cuando edite la receta para añadir las líneas de QuickFix que crearán ese código.
Y cuando escribo el código de ejemplo, quiero usar un nombre de campo diferente (aquí estoy usando logger2) porque Sensei es lo suficientemente inteligente como para no añadir un campo duplicado, así que tengo que engañarlo usando un nombre diferente.
Así que voy a modificar la receta para crear este código añadiendo un campo llamado logger.
availableFixes:
- nombre: "use Logger"
acciones:
- Reescritura:
to: "logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})"
- addField:
field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
}}.class.getName())"
objetivo: "parentClass"
Tenga en cuenta que he cambiado SysOutTest para ser una variable de bigote para que recoja el nombre de cualquier clase en la que utilice esta receta. Y de nuevo, no recordaba la sintaxis del bigote, utilicé la GUI Show Variables para encontrar el reemplazo que necesitaba.
Al calificar completamente el Logger a java.util.logging.Logger, Sensei añadirá la importación y escribirá la línea de código que quiero, es decir
Logger = Logger.getLogger(SysOutTest.class.getName());

Una cosa útil de esta receta es que como sólo añadirá el campo logger una vez, puedo usar esto en cualquier código existente donde haya usado `System.out.println` y usar Sensei para cambiar todas las ocurrencias en mi archivo de código al mismo tiempo.

Próximos pasos
Una vez que me acostumbre a esto, eventualmente me entrenaré para dejar de usar System.out.println.
Puedo utilizar Sensei para ayudarme a escribir código de forma proactiva creando una segunda receta que me ayude a crear un registrador.
Por ejemplo, puedo coincidir en una clase, donde no hay ningún campo llamado logger, y añadir uno.
Si creo una receta de nivel Información
Nombre: Logger: añadir logger
Descripción: Añadir un registrador a la clase
Para coincidir con una clase sin campo de registro:
buscar:
clase:
sin:
niño:
campo:
nombre: "logger"
Y luego reutilizaré parte del QuickFix que vimos antes:
availableFixes:
- nombre: "Añadir registrador"
acciones:
- addField:
field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
}}.class.getName())"
objetivo: "yo"
Observe la diferencia en el objetivo aquí comparado con el primer QuickFix. Este utiliza self porque nuestra Búsqueda coincidió con la clase. El primer QuickFix utiliza parentClass porque hemos buscado código dentro de la propia clase.
Resumen
Esto representa uno de los flujos clave asociados con el uso de Sensei para ayudar a mejorar su conjunto de habilidades de programación personal:
- crear una receta para ayudar a su "mejor práctica" inmediata
- una vez que sepa cómo utilizar esa mejor práctica... cree una receta para agilizar su flujo de trabajo
---
Puede instalar Sensei desde IntelliJ usando "Preferences \ Plugins" (Mac) o "Settings \ Plugins" (Windows) y luego sólo busque "sensei secure code".
El código fuente y las recetas para esto se pueden encontrar en el repositorio `sensei-blog-examples` en la cuenta de GitHub de Secure Code Warrior , en el módulo `pojoexamples`.


Un ejemplo rápido de creación de una receta para migrar de System.out.println a usar un Logger de Java.
Alan Richardson cuenta con más de veinte años de experiencia profesional en TI, trabajando como desarrollador y en todos los niveles de la jerarquía de pruebas, desde probador hasta jefe de pruebas. Jefe de Relaciones con los Desarrolladores en Secure Code Warrior, trabaja directamente con los equipos, para mejorar el desarrollo de un código seguro de calidad. Alan es autor de cuatro libros, entre ellos "Dear Evil Tester" y "Java For Testers". Alan también ha creado una formación en línea courses para ayudar a la gente a aprender las pruebas técnicas de la web y Selenium WebDriver con Java. Alan publica sus escritos y vídeos de formación en SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, y CompendiumDev.co.uk.

Secure Code Warrior está a disposición de su organización para ayudarle a proteger el código a lo largo de todo el ciclo de vida de desarrollo de software y crear una cultura en la que la ciberseguridad sea una prioridad. Tanto si es director de AppSec, desarrollador, CISO o cualquier persona implicada en la seguridad, podemos ayudar a su organización a reducir los riesgos asociados a un código inseguro.
Reservar una demostraciónAlan Richardson cuenta con más de veinte años de experiencia profesional en TI, trabajando como desarrollador y en todos los niveles de la jerarquía de pruebas, desde probador hasta jefe de pruebas. Jefe de Relaciones con los Desarrolladores en Secure Code Warrior, trabaja directamente con los equipos, para mejorar el desarrollo de un código seguro de calidad. Alan es autor de cuatro libros, entre ellos "Dear Evil Tester" y "Java For Testers". Alan también ha creado una formación en línea courses para ayudar a la gente a aprender las pruebas técnicas de la web y Selenium WebDriver con Java. Alan publica sus escritos y vídeos de formación en SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, y CompendiumDev.co.uk.


Migración a un registrador con Sensei
Este post describe la creación de una receta para migrar de System.out.println a usar un Logger de Java.
Cuando estoy hackeando el código, en lugar de usar TDD, y cometo errores, tengo la mala costumbre de imprimir una línea en System.out, y he querido despojarme de ese hábito.
He cometido un montón de errores al escribir el código de abajo :
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;
}
Inicialmente, escribí countdown++ y el bucle no terminó.
Y usé la cuenta atrás > 1 por lo que no obtuve la salida que quería.
Al final, llené mi código con System.out.println para ayudarme a depurar. Y la experiencia reforzó que necesito aprender a usar un registrador como mi enfoque por defecto.
Investigar
Afortunadamente, leí la documentación deSensei y decidí usar la guía "Getting Started" para ayudarme a crear una receta para convertir de System.out.println y animarme a usar un registrador:
- java.util.logging.Logger
Creación de una receta
Lo primero que hago es pulsar el println y luego alt+enter para crear una nueva receta.

Lo creo con los siguientes datos:
Nombre: Logger: utilizar logger en lugar de println
Descripción: utilizar logger en lugar de println - recuerde dejar de utilizar System.out.println
Nivel: Error
Y voy a empezar por hacer coincidir methodcall con el nombre println
buscar:
methodcall:
nombre: "println"
Y la vista previa me muestra todas las coincidencias de mi código.

Puedo ver que todas las coincidencias en mi código son para System.out.println pero no confío en que a largo plazo esta sea la única coincidencia. Quiero que coincida con una declaración más calificada que quiero cambiar.
Amplío el matcher para buscar un methodcall en un campo nombrado en la clase System.
buscar:
methodcall:
nombre: "println"
"on":
campo:
en:
clase:
nombre: "Sistema"
nombre: "out"
Podría, si quisiera, calificar completamente el nombre System a java.lang.System

Modificación del Código para registrar
A continuación, quiero crear el QuickFix.
Primero quiero modificar la línea de código que registra la salida:
availableFixes:
- nombre: "use Logger"
acciones:
- Reescritura:
to: "logger.log(Level.INFO, {{{ arguments.0 }}})"
No tengo que recordar el formato de la plantilla del bigote. Utilicé la opción de mostrar variables en la interfaz gráfica de usuario para que me mostrara el argumento y hice doble clic en él. Entonces la GUI rellenó la plantilla de bigote correspondiente.

Cuando lo pruebo, veo que todavía tengo que pulsar alt+enter para importar el Level enum. Pero si modifico mi QuickFix para que tenga un elemento totalmente cualificado, entonces Sensei añadirá la importación por mí, por ejemplo
- Sustituirá System.out.println(output); por
logger.log(Level.INFO, output);
- Y añade una importación para el enum:
import java.util.logging.Level;
- Si vuelvo a escribir a:
logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})
Y esto funcionará, pero todavía tendré que recordar la sintaxis para instanciar el registrador en primer lugar.

Modificación del código para añadir el campo de registro
Puedo modificar mi QuickFix para que me cree el campo también.
Primero codificaré el registrador y luego lo añadiré a mi receta para no tener que volver a codificarlo.
Logger2 = Logger.getLogger(SysOutTest.class.getName());
Suelo escribir primero el código de ejemplo que quiero que se genere porque así puedo utilizar el completamiento de código de IntelliJ y la comprobación de sintaxis para asegurarme de que lo hago bien. Como efecto secundario, luego estará en la vista previa del código cuando edite la receta para añadir las líneas de QuickFix que crearán ese código.
Y cuando escribo el código de ejemplo, quiero usar un nombre de campo diferente (aquí estoy usando logger2) porque Sensei es lo suficientemente inteligente como para no añadir un campo duplicado, así que tengo que engañarlo usando un nombre diferente.
Así que voy a modificar la receta para crear este código añadiendo un campo llamado logger.
availableFixes:
- nombre: "use Logger"
acciones:
- Reescritura:
to: "logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})"
- addField:
field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
}}.class.getName())"
objetivo: "parentClass"
Tenga en cuenta que he cambiado SysOutTest para ser una variable de bigote para que recoja el nombre de cualquier clase en la que utilice esta receta. Y de nuevo, no recordaba la sintaxis del bigote, utilicé la GUI Show Variables para encontrar el reemplazo que necesitaba.
Al calificar completamente el Logger a java.util.logging.Logger, Sensei añadirá la importación y escribirá la línea de código que quiero, es decir
Logger = Logger.getLogger(SysOutTest.class.getName());

Una cosa útil de esta receta es que como sólo añadirá el campo logger una vez, puedo usar esto en cualquier código existente donde haya usado `System.out.println` y usar Sensei para cambiar todas las ocurrencias en mi archivo de código al mismo tiempo.

Próximos pasos
Una vez que me acostumbre a esto, eventualmente me entrenaré para dejar de usar System.out.println.
Puedo utilizar Sensei para ayudarme a escribir código de forma proactiva creando una segunda receta que me ayude a crear un registrador.
Por ejemplo, puedo coincidir en una clase, donde no hay ningún campo llamado logger, y añadir uno.
Si creo una receta de nivel Información
Nombre: Logger: añadir logger
Descripción: Añadir un registrador a la clase
Para coincidir con una clase sin campo de registro:
buscar:
clase:
sin:
niño:
field:
nombre: "logger"
Y luego reutilizaré parte del QuickFix que vimos antes:
availableFixes:
- nombre: "Añadir registrador"
acciones:
- addField:
field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
}}.class.getName())"
objetivo: "yo"
Observe la diferencia en el objetivo aquí comparado con el primer QuickFix. Este utiliza self porque nuestra Búsqueda coincidió con la clase. El primer QuickFix utiliza parentClass porque hemos buscado código dentro de la propia clase.
Resumen
Esto representa uno de los flujos clave asociados con el uso de Sensei para ayudar a mejorar su conjunto de habilidades de programación personal:
- crear una receta para ayudar a su "mejor práctica" inmediata
- una vez que sepa cómo utilizar esa mejor práctica... cree una receta para agilizar su flujo de trabajo
---
Puede instalar Sensei desde IntelliJ usando "Preferences \ Plugins" (Mac) o "Settings \ Plugins" (Windows) y luego sólo busque "sensei secure code".
El código fuente y las recetas para esto se pueden encontrar en el repositorio `sensei-blog-examples` en la cuenta de GitHub de Secure Code Warrior , en el módulo `pojoexamples`.

Migración a un registrador con Sensei
Este post describe la creación de una receta para migrar de System.out.println a usar un Logger de Java.
Cuando estoy hackeando el código, en lugar de usar TDD, y cometo errores, tengo la mala costumbre de imprimir una línea en System.out, y he querido despojarme de ese hábito.
He cometido un montón de errores al escribir el código de abajo :
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;
}
Inicialmente, escribí countdown++ y el bucle no terminó.
Y usé la cuenta atrás > 1 por lo que no obtuve la salida que quería.
Al final, llené mi código con System.out.println para ayudarme a depurar. Y la experiencia reforzó que necesito aprender a usar un registrador como mi enfoque por defecto.
Investigar
Afortunadamente, leí la documentación deSensei y decidí usar la guía "Getting Started" para ayudarme a crear una receta para convertir de System.out.println y animarme a usar un registrador:
- java.util.logging.Logger
Creación de una receta
Lo primero que hago es pulsar el println y luego alt+enter para crear una nueva receta.

Lo creo con los siguientes datos:
Nombre: Logger: utilizar logger en lugar de println
Descripción: utilizar logger en lugar de println - recuerde dejar de utilizar System.out.println
Nivel: Error
Y voy a empezar por hacer coincidir methodcall con el nombre println
buscar:
methodcall:
nombre: "println"
Y la vista previa me muestra todas las coincidencias de mi código.

Puedo ver que todas las coincidencias en mi código son para System.out.println pero no confío en que a largo plazo esta sea la única coincidencia. Quiero que coincida con una declaración más calificada que quiero cambiar.
Amplío el matcher para buscar un methodcall en un campo nombrado en la clase System.
buscar:
methodcall:
nombre: "println"
"on":
campo:
en:
clase:
nombre: "Sistema"
nombre: "out"
Podría, si quisiera, calificar completamente el nombre System a java.lang.System

Modificación del Código para registrar
A continuación, quiero crear el QuickFix.
Primero quiero modificar la línea de código que registra la salida:
availableFixes:
- nombre: "use Logger"
acciones:
- Reescritura:
to: "logger.log(Level.INFO, {{{ arguments.0 }}})"
No tengo que recordar el formato de la plantilla del bigote. Utilicé la opción de mostrar variables en la interfaz gráfica de usuario para que me mostrara el argumento y hice doble clic en él. Entonces la GUI rellenó la plantilla de bigote correspondiente.

Cuando lo pruebo, veo que todavía tengo que pulsar alt+enter para importar el Level enum. Pero si modifico mi QuickFix para que tenga un elemento totalmente cualificado, entonces Sensei añadirá la importación por mí, por ejemplo
- Sustituirá System.out.println(output); por
logger.log(Level.INFO, output);
- Y añade una importación para el enum:
import java.util.logging.Level;
- Si vuelvo a escribir a:
logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})
Y esto funcionará, pero todavía tendré que recordar la sintaxis para instanciar el registrador en primer lugar.

Modificación del código para añadir el campo de registro
Puedo modificar mi QuickFix para que me cree el campo también.
Primero codificaré el registrador y luego lo añadiré a mi receta para no tener que volver a codificarlo.
Logger2 = Logger.getLogger(SysOutTest.class.getName());
Suelo escribir primero el código de ejemplo que quiero que se genere porque así puedo utilizar el completamiento de código de IntelliJ y la comprobación de sintaxis para asegurarme de que lo hago bien. Como efecto secundario, luego estará en la vista previa del código cuando edite la receta para añadir las líneas de QuickFix que crearán ese código.
Y cuando escribo el código de ejemplo, quiero usar un nombre de campo diferente (aquí estoy usando logger2) porque Sensei es lo suficientemente inteligente como para no añadir un campo duplicado, así que tengo que engañarlo usando un nombre diferente.
Así que voy a modificar la receta para crear este código añadiendo un campo llamado logger.
availableFixes:
- nombre: "use Logger"
acciones:
- Reescritura:
to: "logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})"
- addField:
field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
}}.class.getName())"
objetivo: "parentClass"
Tenga en cuenta que he cambiado SysOutTest para ser una variable de bigote para que recoja el nombre de cualquier clase en la que utilice esta receta. Y de nuevo, no recordaba la sintaxis del bigote, utilicé la GUI Show Variables para encontrar el reemplazo que necesitaba.
Al calificar completamente el Logger a java.util.logging.Logger, Sensei añadirá la importación y escribirá la línea de código que quiero, es decir
Logger = Logger.getLogger(SysOutTest.class.getName());

Una cosa útil de esta receta es que como sólo añadirá el campo logger una vez, puedo usar esto en cualquier código existente donde haya usado `System.out.println` y usar Sensei para cambiar todas las ocurrencias en mi archivo de código al mismo tiempo.

Próximos pasos
Una vez que me acostumbre a esto, eventualmente me entrenaré para dejar de usar System.out.println.
Puedo utilizar Sensei para ayudarme a escribir código de forma proactiva creando una segunda receta que me ayude a crear un registrador.
Por ejemplo, puedo coincidir en una clase, donde no hay ningún campo llamado logger, y añadir uno.
Si creo una receta de nivel Información
Nombre: Logger: añadir logger
Descripción: Añadir un registrador a la clase
Para coincidir con una clase sin campo de registro:
buscar:
clase:
sin:
niño:
campo:
nombre: "logger"
Y luego reutilizaré parte del QuickFix que vimos antes:
availableFixes:
- nombre: "Añadir registrador"
acciones:
- addField:
field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
}}.class.getName())"
objetivo: "yo"
Observe la diferencia en el objetivo aquí comparado con el primer QuickFix. Este utiliza self porque nuestra Búsqueda coincidió con la clase. El primer QuickFix utiliza parentClass porque hemos buscado código dentro de la propia clase.
Resumen
Esto representa uno de los flujos clave asociados con el uso de Sensei para ayudar a mejorar su conjunto de habilidades de programación personal:
- crear una receta para ayudar a su "mejor práctica" inmediata
- una vez que sepa cómo utilizar esa mejor práctica... cree una receta para agilizar su flujo de trabajo
---
Puede instalar Sensei desde IntelliJ usando "Preferences \ Plugins" (Mac) o "Settings \ Plugins" (Windows) y luego sólo busque "sensei secure code".
El código fuente y las recetas para esto se pueden encontrar en el repositorio `sensei-blog-examples` en la cuenta de GitHub de Secure Code Warrior , en el módulo `pojoexamples`.

Haga clic en el siguiente enlace y descargue el PDF de este recurso.
Secure Code Warrior está a disposición de su organización para ayudarle a proteger el código a lo largo de todo el ciclo de vida de desarrollo de software y crear una cultura en la que la ciberseguridad sea una prioridad. Tanto si es director de AppSec, desarrollador, CISO o cualquier persona implicada en la seguridad, podemos ayudar a su organización a reducir los riesgos asociados a un código inseguro.
Ver el informeReservar una demostraciónAlan Richardson cuenta con más de veinte años de experiencia profesional en TI, trabajando como desarrollador y en todos los niveles de la jerarquía de pruebas, desde probador hasta jefe de pruebas. Jefe de Relaciones con los Desarrolladores en Secure Code Warrior, trabaja directamente con los equipos, para mejorar el desarrollo de un código seguro de calidad. Alan es autor de cuatro libros, entre ellos "Dear Evil Tester" y "Java For Testers". Alan también ha creado una formación en línea courses para ayudar a la gente a aprender las pruebas técnicas de la web y Selenium WebDriver con Java. Alan publica sus escritos y vídeos de formación en SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, y CompendiumDev.co.uk.
Migración a un registrador con Sensei
Este post describe la creación de una receta para migrar de System.out.println a usar un Logger de Java.
Cuando estoy hackeando el código, en lugar de usar TDD, y cometo errores, tengo la mala costumbre de imprimir una línea en System.out, y he querido despojarme de ese hábito.
He cometido un montón de errores al escribir el código de abajo :
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;
}
Inicialmente, escribí countdown++ y el bucle no terminó.
Y usé la cuenta atrás > 1 por lo que no obtuve la salida que quería.
Al final, llené mi código con System.out.println para ayudarme a depurar. Y la experiencia reforzó que necesito aprender a usar un registrador como mi enfoque por defecto.
Investigar
Afortunadamente, leí la documentación deSensei y decidí usar la guía "Getting Started" para ayudarme a crear una receta para convertir de System.out.println y animarme a usar un registrador:
- java.util.logging.Logger
Creación de una receta
Lo primero que hago es pulsar el println y luego alt+enter para crear una nueva receta.

Lo creo con los siguientes datos:
Nombre: Logger: utilizar logger en lugar de println
Descripción: utilizar logger en lugar de println - recuerde dejar de utilizar System.out.println
Nivel: Error
Y voy a empezar por hacer coincidir methodcall con el nombre println
buscar:
methodcall:
nombre: "println"
Y la vista previa me muestra todas las coincidencias de mi código.

Puedo ver que todas las coincidencias en mi código son para System.out.println pero no confío en que a largo plazo esta sea la única coincidencia. Quiero que coincida con una declaración más calificada que quiero cambiar.
Amplío el matcher para buscar un methodcall en un campo nombrado en la clase System.
buscar:
methodcall:
nombre: "println"
"on":
campo:
en:
clase:
nombre: "Sistema"
nombre: "out"
Podría, si quisiera, calificar completamente el nombre System a java.lang.System

Modificación del Código para registrar
A continuación, quiero crear el QuickFix.
Primero quiero modificar la línea de código que registra la salida:
availableFixes:
- nombre: "use Logger"
acciones:
- Reescritura:
to: "logger.log(Level.INFO, {{{ arguments.0 }}})"
No tengo que recordar el formato de la plantilla del bigote. Utilicé la opción de mostrar variables en la interfaz gráfica de usuario para que me mostrara el argumento y hice doble clic en él. Entonces la GUI rellenó la plantilla de bigote correspondiente.

Cuando lo pruebo, veo que todavía tengo que pulsar alt+enter para importar el Level enum. Pero si modifico mi QuickFix para que tenga un elemento totalmente cualificado, entonces Sensei añadirá la importación por mí, por ejemplo
- Sustituirá System.out.println(output); por
logger.log(Level.INFO, output);
- Y añade una importación para el enum:
import java.util.logging.Level;
- Si vuelvo a escribir a:
logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})
Y esto funcionará, pero todavía tendré que recordar la sintaxis para instanciar el registrador en primer lugar.

Modificación del código para añadir el campo de registro
Puedo modificar mi QuickFix para que me cree el campo también.
Primero codificaré el registrador y luego lo añadiré a mi receta para no tener que volver a codificarlo.
Logger2 = Logger.getLogger(SysOutTest.class.getName());
Suelo escribir primero el código de ejemplo que quiero que se genere porque así puedo utilizar el completamiento de código de IntelliJ y la comprobación de sintaxis para asegurarme de que lo hago bien. Como efecto secundario, luego estará en la vista previa del código cuando edite la receta para añadir las líneas de QuickFix que crearán ese código.
Y cuando escribo el código de ejemplo, quiero usar un nombre de campo diferente (aquí estoy usando logger2) porque Sensei es lo suficientemente inteligente como para no añadir un campo duplicado, así que tengo que engañarlo usando un nombre diferente.
Así que voy a modificar la receta para crear este código añadiendo un campo llamado logger.
availableFixes:
- nombre: "use Logger"
acciones:
- Reescritura:
to: "logger.log(java.util.logging.Level.INFO, {{{ arguments.0 }}})"
- addField:
field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
}}.class.getName())"
objetivo: "parentClass"
Tenga en cuenta que he cambiado SysOutTest para ser una variable de bigote para que recoja el nombre de cualquier clase en la que utilice esta receta. Y de nuevo, no recordaba la sintaxis del bigote, utilicé la GUI Show Variables para encontrar el reemplazo que necesitaba.
Al calificar completamente el Logger a java.util.logging.Logger, Sensei añadirá la importación y escribirá la línea de código que quiero, es decir
Logger = Logger.getLogger(SysOutTest.class.getName());

Una cosa útil de esta receta es que como sólo añadirá el campo logger una vez, puedo usar esto en cualquier código existente donde haya usado `System.out.println` y usar Sensei para cambiar todas las ocurrencias en mi archivo de código al mismo tiempo.

Próximos pasos
Una vez que me acostumbre a esto, eventualmente me entrenaré para dejar de usar System.out.println.
Puedo utilizar Sensei para ayudarme a escribir código de forma proactiva creando una segunda receta que me ayude a crear un registrador.
Por ejemplo, puedo coincidir en una clase, donde no hay ningún campo llamado logger, y añadir uno.
Si creo una receta de nivel Información
Nombre: Logger: añadir logger
Descripción: Añadir un registrador a la clase
Para coincidir con una clase sin campo de registro:
buscar:
clase:
sin:
niño:
campo:
nombre: "logger"
Y luego reutilizaré parte del QuickFix que vimos antes:
availableFixes:
- nombre: "Añadir registrador"
acciones:
- addField:
field: "java.util.logging.Logger logger = Logger.getLogger({{{ containingClass.name\
}}.class.getName())"
objetivo: "yo"
Observe la diferencia en el objetivo aquí comparado con el primer QuickFix. Este utiliza self porque nuestra Búsqueda coincidió con la clase. El primer QuickFix utiliza parentClass porque hemos buscado código dentro de la propia clase.
Resumen
Esto representa uno de los flujos clave asociados con el uso de Sensei para ayudar a mejorar su conjunto de habilidades de programación personal:
- crear una receta para ayudar a su "mejor práctica" inmediata
- una vez que sepa cómo utilizar esa mejor práctica... cree una receta para agilizar su flujo de trabajo
---
Puede instalar Sensei desde IntelliJ usando "Preferences \ Plugins" (Mac) o "Settings \ Plugins" (Windows) y luego sólo busque "sensei secure code".
El código fuente y las recetas para esto se pueden encontrar en el repositorio `sensei-blog-examples` en la cuenta de GitHub de Secure Code Warrior , en el módulo `pojoexamples`.
Índice
Alan Richardson cuenta con más de veinte años de experiencia profesional en TI, trabajando como desarrollador y en todos los niveles de la jerarquía de pruebas, desde probador hasta jefe de pruebas. Jefe de Relaciones con los Desarrolladores en Secure Code Warrior, trabaja directamente con los equipos, para mejorar el desarrollo de un código seguro de calidad. Alan es autor de cuatro libros, entre ellos "Dear Evil Tester" y "Java For Testers". Alan también ha creado una formación en línea courses para ayudar a la gente a aprender las pruebas técnicas de la web y Selenium WebDriver con Java. Alan publica sus escritos y vídeos de formación en SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, y CompendiumDev.co.uk.

Secure Code Warrior está a disposición de su organización para ayudarle a proteger el código a lo largo de todo el ciclo de vida de desarrollo de software y crear una cultura en la que la ciberseguridad sea una prioridad. Tanto si es director de AppSec, desarrollador, CISO o cualquier persona implicada en la seguridad, podemos ayudar a su organización a reducir los riesgos asociados a un código inseguro.
Reservar una demostraciónDescargarRecursos para empezar
Panorama de la gestión de riesgos de los promotores
La gestión de riesgos del desarrollador es un enfoque holístico y proactivo de la seguridad de las aplicaciones, centrado en quienes contribuyen al código y no en los bits y bytes de la propia capa de la aplicación.
Seguridad desde el diseño: Definición de las mejores prácticas, capacitación de los desarrolladores y evaluación comparativa de los resultados de la seguridad preventiva
En este documento de investigación, los cofundadores Secure Code Warrior , Pieter Danhieux y el Dr. Matias Madou, Ph.D., junto con los expertos colaboradores, Chris Inglis, ex Director Nacional Cibernético de EE.UU. (ahora Asesor Estratégico de Paladin Capital Group), y Devin Lynch, Director Senior, Paladin Global Institute, revelarán los hallazgos clave de más de veinte entrevistas en profundidad con líderes de seguridad empresarial, incluyendo CISOs, un VP de Seguridad de Aplicaciones y profesionales de seguridad de software.
Evaluación comparativa de las competencias en materia de seguridad: optimización del diseño seguro en la empresa
Encontrar datos significativos sobre el éxito de las iniciativas Secure-by-Design es notoriamente difícil. Los responsables de la seguridad de la información se enfrentan a menudo al reto de demostrar el rendimiento de la inversión (ROI) y el valor empresarial de las actividades de los programas de seguridad, tanto a nivel de las personas como de la empresa. Por no mencionar que a las empresas les resulta especialmente difícil obtener información sobre cómo se comparan sus organizaciones con los estándares actuales del sector. La Estrategia Nacional de Ciberseguridad del Presidente desafió a las partes interesadas a "adoptar la seguridad y la resiliencia desde el diseño". La clave para que las iniciativas de seguridad por diseño funcionen no es sólo dotar a los desarrolladores de las habilidades necesarias para garantizar un código seguro, sino también garantizar a los reguladores que esas habilidades están en su lugar. En esta presentación, compartimos una miríada de datos cualitativos y cuantitativos, derivados de múltiples fuentes primarias, incluidos puntos de datos internos recogidos de más de 250.000 desarrolladores, opiniones de clientes basadas en datos y estudios públicos. Aprovechando esta agregación de puntos de datos, pretendemos comunicar una visión del estado actual de las iniciativas Secure-by-Design en múltiples verticales. El informe detalla por qué este espacio está actualmente infrautilizado, el impacto significativo que un programa de mejora de las competencias puede tener en la mitigación de los riesgos de ciberseguridad y el potencial para eliminar categorías de vulnerabilidades de un código base.
Servicios profesionales - Acelerar con experiencia
El equipo de servicios de estrategia de programas (PSS) de Secure Code Warriorle ayuda a crear, mejorar y optimizar su programa de codificación segura. Tanto si empieza de cero como si está perfeccionando su enfoque, nuestros expertos le proporcionarán orientación personalizada.
Recursos para empezar
Revelado: Cómo define el sector cibernético la seguridad por diseño
En nuestro último libro blanco, nuestros cofundadores, Pieter Danhieux y el doctor Matias Madou, se sentaron con más de veinte líderes de seguridad empresarial, incluidos CISO, líderes de AppSec y profesionales de la seguridad, para averiguar las piezas clave de este rompecabezas y descubrir la realidad detrás del movimiento Secure by Design. Se trata de una ambición compartida por todos los equipos de seguridad, pero no de un libro de jugadas compartido.
¿Vibe Coding va a convertir tu código en una fiesta de fraternidad?
Vibe Coding es como una fiesta de fraternidad universitaria, y la IA es la pieza central de todos los festejos, el barril. Es muy divertido dar rienda suelta a la creatividad y ver adónde te lleva tu imaginación, pero después de unas cuantas borracheras, beber (o usar IA) con moderación es, sin duda, la solución más segura a largo plazo.