1
RegistroRegistro de de trazatraza en en JavaJava
[email protected] / [email protected]
¿…y ¿…y quéqué eses la la trazatraza??
public int suma(int a, int b)
{
log.debug(“Entrando en suma”);
int sum;
sum = a + b;
log.info(“Resultado de la suma:”+sum);
log.debug(“Saliendo de suma”);
return sum;
}<debug> Entrando en suma
<info> Resultado de la suma: X
<debug> Saliendo de suma
Veremos dentro de poco como crear el objeto “log”.
2
UtilidadUtilidad de la de la trazatraza
AyudaAyuda a a encontrarencontrar erroreserrores..AyudaAyuda a a depurardepurar programasprogramas ((multihilomultihilo, , distribuidosdistribuidos, etc…), etc…)PermitePermite mejorarmejorar el el rendimientorendimiento..
java.sql.SQLException: Table not found: TEO in statement [SELECT * FROM Teo;]at org.hsqldb.Trace.getError(Unknown Source)at org.hsqldb.jdbcResultSet.<init>(Unknown Source)at org.hsqldb.jdbcConnection.executeStandalone(Unknown Source)at org.hsqldb.jdbcConnection.execute(Unknown Source)at org.hsqldb.jdbcStatement.fetchResult(Unknown Source)at org.hsqldb.jdbcStatement.executeQuery(Unknown Source)at org.rquery.helppers.Metadata.GetFieldList(Metadata.java:115)at org.rquery.analex.ra.SQLBuilderAR.buildRelation(SQLBuilderAR.java:69)at org.rquery.analex.ra.ParserLLAR.generate(ParserLLAR.java:204)at org.rquery.analex.ra.ParserLLAR.translateQuery(ParserLLAR.java:99)at org.rquery.analex.AnalexDecorator.translateQuery(AnalexDecorator.java:36)at org.rquery.gui.RQueryAdvancedGUI$EjecutarAction.doQuery(RQueryAdvancedGUI.java:776)at org.rquery.gui.RQueryAdvancedGUI$EjecutarAction.actionPerformed(RQueryAdvancedGUI.java:755)at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(Unknown Source)at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)at javax.swing.DefaultButtonModel.setPressed(Unknown Source)at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)at java.awt.Component.processMouseEvent(Unknown Source)at java.awt.Component.processEvent(Unknown Source)at java.awt.Container.processEvent(Unknown Source)at java.awt.Component.dispatchEventImpl(Unknown Source)at java.awt.Container.dispatchEventImpl(Unknown Source)at java.awt.Component.dispatchEvent(Unknown Source)at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)at java.awt.Container.dispatchEventImpl(Unknown Source)at java.awt.Window.dispatchEventImpl(Unknown Source)at java.awt.Component.dispatchEvent(Unknown Source)at java.awt.EventQueue.dispatchEvent(Unknown Source)at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)at java.awt.EventDispatchThread.pumpEvents(Unknown Source)at java.awt.EventDispatchThread.pumpEvents(Unknown Source)at java.awt.EventDispatchThread.run(Unknown Source)
<info> GUI - Pulsado botón ejecutar.<info> Parser – Consulta recibida ‘TEO;’<info> Parser – Consulta válida ‘TEO;’<info> SQLTranslator – Consulta traducida a ‘select * from TEO;‘<info> SQLExec – Ejecutando consulta ‘select * from TEO;‘<error> SQLExec – Excepción Table not found: TEO in statement [SELECT * FROM Teo;]<debug> SQLExec – Consulta abortada<info> GUI – Consulta terminada.
¿Cuál es más útil para detectar lo que ha pasado?
1
2
3
CaracterísticasCaracterísticas de Log4jde Log4j
HabilitarHabilitar o o desabilitardesabilitar logs.logs.PriorizarPriorizar mensajesmensajes..RedirecciónRedirección de la de la salidasalida..FormatoFormato de de loslos mensajesmensajes..ConfiguraciónConfiguración porpor códigocódigo o o archivosarchivosexternosexternos..OrganizaciónOrganización jerárquizajerárquiza..
CreandoCreando un logun log
import org.apache.log4j.Logger;
public class PruebaLog {
static Logger log;
static {log =
Logger.getLogger(PruebaLog.class.getName());
}
}
Uno para todos….
El nombre de un log es el nombre de la clase y de los paquetes donde está.
Aunque hay más, de momento es suficiente.
Si no existe lo crea y si ya se creo devuelve una referencia
Todo log tiene una configuración por defecto que podemos cambiar desde el código o desde un archivo externo.
4
NivelesNiveles de de prioridadprioridadDEBUG: Mensajes de depuración.INFO: Mensajes similares al modo "verbose" en otras aplicaciones.WARN: Mensajes de alerta sobre eventos que se desea mantenerconstancia, pero que no afectan el funcionamiento del programa.ERROR: Mensajes de error de la aplicación que se desea guardar, estos eventos afectan al programa pero lo dejan seguirfuncionando.FATAL: Mensajes críticos del sistema, generalmente después de guardar el mensaje el programa abortará.
(Solo para el archivo de configuración):ALL: este es el nivel más bajo posible, habilita todos los logs.OFF: este es el nivel más alto posible, deshabilita todos los logs.
FATAL < ERROR < WARN < INFO < DEBUG
Un log Un log parapara IntercambiarIntercambiar1. public static void Intercambia(List l1, List l2) {2. Object b1=null;3. Object aux=null;4. Collections.sort(l1);5. Collections.sort(l2);6. ListIterator i1=l1.listIterator();7. while (i1.hasNext()) {8. b1=i1.next();9. int pos=Collections.binarySearch(l2,b1);10. if (pos<0) {11. if (i1.hasNext()){12. aux=i1.next();13. if (b1.equals(aux)) {14. i1.remove();15. l2.add(b1);16. Collections.sort(l2);17. }18. }19. }20. }21. }
¿En qué líneas y con qué nivel se colocaría la traza?
5
Un log Un log parapara IntercambiarIntercambiar1. public static void Intercambia(List l1, List l2) {2. Object b1=null; Object aux=null;3. log.info("LLamada a Intercambia(l1, l2);");4. if ((l1 == null) || (l2==null)) {5. log.error("Lista nula:\nl1="+l1+"\nl2="+l2+"\nOperación abortada.");6. return;7. }8. Collections.sort(l1); Collections.sort(l2);9. log.debug("Parámetros:\nl1="+l1+"\nl2="+l2);10. ListIterator i1=l1.listIterator();11. while (i1.hasNext()) {12. b1=i1.next();13. log.debug("Elemento procesado: "+b1);14. int pos=Collections.binarySearch(l2,b1);15. if (pos<0) {16. if (i1.hasNext()) {17. log.debug("Elemento no encontrado en l2");18. aux=i1.next();19. if (b1.equals(aux)) {20. log.debug("Elemento repetido encontrado en l1");21. i1.remove(); l2.add(b1);22. Collections.sort(l2);23. log.debug("Nuevo valor de l2 ="+l2);24. }25. }26. } else log.debug("Elemento encontrado en l2");27. }28. log.info("Salida de Intercambia(l1, l2);");29. }
0 [main] INFO IntercambiaConLog - LLamada a Intercambia(l1, l2);0 [main] DEBUG IntercambiaConLog - Parßmetros:l1=[1, 2, 2, 3]|l2=[4, 5, 6]
0 [main] DEBUG IntercambiaConLog - Elemento procesado: 10 [main] DEBUG IntercambiaConLog - Elemento no encontrado en l20 [main] DEBUG IntercambiaConLog - Elemento procesado: 20 [main] DEBUG IntercambiaConLog - Elemento no encontrado en l20 [main] INFO IntercambiaConLog - Salida de Intercambia(l1, l2);
Una solución
0 [main] INFO IntercambiaConLog - LLamada a Intercambia(l1, l2);16 [main] ERROR IntercambiaConLog - Lista nula:
l1=null| l2=[3, 4, 2, 6, 4]Operaci¾n abortada.
CambioCambio del del nivelnivel del log.del log.
log.setLevel(Level.INFO);
0 [main] INFO IntercambiaConLog - LLamada a Intercambia(l1, l2);0 [main] DEBUG IntercambiaConLog - Parßmetros:l1=[1, 2, 2, 3]|l2=[4, 5, 6]
0 [main] DEBUG IntercambiaConLog - Elemento procesado: 10 [main] DEBUG IntercambiaConLog - Elemento no encontrado en l20 [main] DEBUG IntercambiaConLog - Elemento procesado: 20 [main] DEBUG IntercambiaConLog - Elemento no encontrado en l20 [main] INFO IntercambiaConLog - Salida de Intercambia(l1, l2);
0 [main] INFO IntercambiaConLog - LLamada a Intercambia(l1, l2);0 [main] INFO IntercambiaConLog - Salida de Intercambia(l1, l2);
6
ConceptosConceptosDos Dos conceptosconceptos importantesimportantes::
AppenderAppender: : indicaindica queque hacerhacer con la con la informacióninformación queque reciberecibe..Layout: Layout: indicaindica el el formatoformato de la de la informacióninformación..
EjemploEjemplo anterioranteriorAppenderAppender: : mostrarlomostrarlo porpor salidasalida estándarestándar..Layout: Layout: todotodo lo lo queque añadíaañadía almensajealmensaje..
VamosVamos a a verver estosestos conceptosconceptos juntojunto con el con el archivoarchivo de de propiedadespropiedades
El El archivoarchivo de de propiedadespropiedades
log4j.logger.IntercambiaConLog=DEBUG, stdout
log4j.appender.stdout =org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %5p (%F:%L) - %m%n
Nombre del log.
Nivel del log.
Lista de appenders.
El appender “stdout” manda el mensaje a la consola.
El layout de “stdout” sige un patrón. Si no indicamos el patrón se muestra solo el mensaje.
Un posible patrón:
%p: nivel del mensaje.
%F: nombre del fichero.
%L: Núm. de línea.
%m: Mensaje.
7
Como Como usarlousarloimport org.apache.log4j.Logger;
public class PruebaLog {
static Logger log;
static {PropertyConfigurator.configure("log.prop");log = Logger.getLogger(PruebaLog.class.getName());
}
}INFO (IntercambiaConLog.java:31) - LLamada a Intercambia(l1, l2);
DEBUG (IntercambiaConLog.java:39) - Parßmetros:l1=[1, 2, 2, 3]|l2=[4, 5, 6]
DEBUG (IntercambiaConLog.java:44) - Elemento procesado: 1DEBUG (IntercambiaConLog.java:50) - Elemento no encontrado en l2DEBUG (IntercambiaConLog.java:44) - Elemento procesado: 2DEBUG (IntercambiaConLog.java:50) - Elemento no encontrado en l2INFO (IntercambiaConLog.java:65) - Salida de Intercambia(l1, l2);
OtroOtro appenderappender
log4j.logger.IntercambiaConLog=DEBUG, stdout, logfile
log4j.appender.logfile =org.apache.log4j.RollingFileAppender
log4j.appender.logfile.layout = org.apache.log4j.SimpleLayout
log4j.appender.logfile.File=log.log
log4j.appender.logfile.MaxFileSize=100KB
Ahora los mensajes irán tanto a “stdout” como a “logfile”.
El appender guarda los mensajes en ficheros del tamaño indicado.
Solo el nivel y el mensaje.
Nombre del fichero
Tamaño
8
OtroOtro ejemploejemplo1. public class Temporizador {
2. // Atributos…
3. public Temporizador(int numPruebas) { 4. if (numPruebas>0){
this.numPruebas=numPruebas;tiempos= new long [numPruebas];
5. } else {6. throw new
IllegalArgumentException();7. }8. }
9. public Temporizador() {10. this(1);11. }
12. // ….
13 }
Un fragmento del temporizador
Escribir la inicialización y los mensajes del log.
OtroOtro ejemploejemplo1. public class Temporizador {
2. // Atributos…
3. public Temporizador(int numPruebas) { 4. log.debug("Nuevo temporizador con "+numPruebas+"
pruebas"); 5. if (numPruebas>0){
this.numPruebas=numPruebas;tiempos= new long [numPruebas];
6. } else {7. log.error("Núm de pruebas invalido. Se lanza
IllegalArgumentException.");8. throw new IllegalArgumentException();9. }10. }
11. public Temporizador() {12. this(1);13. log.warn("Creado temporizador con 1 sola prueba\n"+14. "Probablemente el tiempo de ejecución sea 0.");15. }16. // ….17. }
Un fragmento del temporizador
import org.apache.log4j.Logger;
public class Temporizador {static Logger log;static {BasicConfigurator.configure();//PropertyConfigurator.configure("log.prop");log =
Logger.getLogger(PruebaLog.class.getName());
}//…..
}
9
El El problemaproblema de de loslos temporizadorestemporizadores
Escribir un archivo de propiedades para este problema.
El El problemaproblema de de loslos temporizadorestemporizadores
# Log padre de todos los demáslog4j.rootLogger=DEBUG, stdout
## Logslog4j.logger.Temporizador=DEBUG, stdoutlog4j.logger.Busqueda=DEBUG, stdout## Estas dos ya nos las dan hechas, por lo que es probable que funcionenlog4j.logger.BusquedaBinaria=ERROR, busquedaslog4j.logger.BusquedaLineal=ERROR, busquedas
# Este appener va a la consola - Salida por pantallalog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p (%F:%L) - %m%n
# Appender de las búsquedas ya implementadaslog4j.appender.busquedas=org.apache.log4j.FileAppenderlog4j.appender.busquedas.File=busquedas.log# Mostramos el número de línea, el archivo y el mensajelog4j.appender.busquedas.layout=org.apache.log4j.PatternLayoutlog4j.appender.busquedas.layout.ConversionPattern= (%L) - [%F] %m%n
10
AntAnt
¿¿QuéQué eses Ant?Ant?
UnaUna versiónversión evolucionadaevolucionada de “make”.de “make”.http://jakarta.apache.org/ant/index.htmlAnt Ant buscabusca automatizaautomatiza la la ejecuciónejecución de de tareastareas..Las Las tareastareas se se guardanguardan en un en un archivoarchivo XML.XML.
11
AlgunosAlgunos ejemplosejemplos de de tareastareasautomatizablesautomatizables..
CrearCrear la la estructuraestructura de de carpetascarpetas de de nuestronuestroproyectoproyecto..CompilaciónCompilación incrementalincrementalGenerarGenerar la la documentacióndocumentación javadocjavadoc..GenerarGenerar la la versiónversión de de distribucióndistribución..
Un Un ejemploejemplo de de ejecuciónejecución I. I. TareasTareas..
<?xml version="1.0" encoding="UTF-8"?><project name="PruebaAnt" basedir="."><target name="init"
description="o Crea la estructura de directorios"><mkdir dir="bin"> </mkdir><mkdir dir="src"> </mkdir><mkdir dir="lib"> </mkdir>
</target></project>
build.xml Nombre por defecto.
12
MásMás tareastareas..
<?xml version="1.0" encoding="UTF-8"?>
<project name="PruebaAnt" basedir=".“ default="Compile">
<target name="compile" description="o Compila el codigo"><javac destdir="bin" deprecation="true“ debug="true“
optimize="false" excludes="**/Test*"> <src> <pathelement location="src"> </pathelement></src> <classpath><fileset dir="lib"><include name="*.jar"> </include></fileset></classpath></javac></target></project>
build.xml Compila todos los .java excepto las pruebas.
DocumentaciónDocumentación sobresobre laslas tareastareas
En la En la documentacióndocumentación de ant se de ant se puedenpuedenencontrarencontrar todastodas laslas tareastareas y y sussus atributosatributos..
13
Ant + Ant + JunitJunit
<target name="test" description="o Ejecuta las pruebas"><junit printsummary="yes">
<!-- Por defecto el resultado siempre se envia a un archivo. -->
<formatter type="plain" usefile="false"/><batchtest fork="yes"><fileset dir=".">
<include name="*Test*.class"/></fileset>
</batchtest></junit>
</target>
Ejecutándo las pruebas desde ant
DependenciasDependencias entreentre tareastareas> ant crear-distribución Crea un archivo ZIP con
todo lo necesario.
> compilar Primero compila todos los fuentes.
> probar Después ejecuta las pruebas para asegurar que no hay ningún error.
> Borrar o crear directorios Borra la antigua distribución o crea los directorios si no existen.
> copiar-archivos Copia los archivos de la distribución
> crear-javadoc Crea la documentación del código
> empaquetar Empaqueta toda la distribución
Top Related