Antes de empezar, complete el Ejercicio 1.3: Despliegue de la sonda.
ProbeKit se puede utilizar para resolver muchos problemas reales relativos al análisis en tiempo real y la depuración. Ya ha aprendido los conceptos básicos sobre cómo escribir y desplegar sondas. En esta lección y la siguiente no se describirán las actividades, sino que se proporcionarán sugerencias para aquellas sondas que pueda escribir para investigar sus propias aplicaciones.
Supongamos que, ocasionalmente, algún método de un servlet genera una excepción. El mensaje del registro que aparece no resulta muy útil; no indica de una forma clara cuál es el problema. Para obtener más información, puede escribir una sonda que se ejecute cada vez que el método genere una excepción, y el código Java del fragmento de la sonda puede registrar el mensaje de la excepción y también los argumentos del método. Esto le ayudará a ver por qué se ha generado la excepción.
Cuando escriba y despliegue esta sonda, tenga en cuenta los puntos siguientes:
System.out.println("[Exception probe triggered!]"); for (int i = 0; i < args.length; i++) { System.out.println("Argument " + i + "=" + args[i]); }
Este ejemplo de sonda es bastante complicado. Digamos que se trata de un método del programa que normalmente se ejecuta rápidamente pero que, ocasionalmente, tarda más tiempo del debido (más de 100 mseg., por ejemplo).
Puede escribir una sonda que tome nota de las horas de entrada y salida cada vez que se ejecute el método. Cuando el tiempo de ejecución sea corto, la sonda no hará nada. Cuando el tiempo de ejecución sea largo, la sonda informará sobre los argumentos del método y demás información importante sobre el estado del programa en ese preciso instante. Esto le permite determinar las circunstancias que provocan tiempos de ejecución mayores.
Cuando escriba la sonda, tenga en cuenta los puntos siguientes:
Puede utilizar la función "fragmento del ámbito de la clase" de ProbeKit para escribir un fragmento de código Java que se compilará en la clase que se genere fuera de un método cualquiera. En este caso, el fragmento se utiliza para definir un campo estático denominado entryTime, que utilizarán tanto el fragmento de entrada como el de salida.
Para añadir este elemento a una sonda, pulse el elemento Probe en el editor de ProbeKit; el editor visualiza un campo en el que puede escribir el código Java para el fragmento del ámbito de la clase:
static long entryTime; static final long thresholdDuration = 100;
entryTime = System.currentTimeMillis();
long now = System.currentTimeMillis(); if ((now - entryTime) > thresholdDuration) { System.out.println( "[Spent a long time in " + className + "." + methodName + ": this=" + thisObject + "]"); }
En la entrada del método, esta sonda registra la hora actual. En la salida del método, la sonda compara la hora actual y la hora de entrada registrada, y si ha transcurrido una cantidad de tiempo mayor de la especificada (la cantidad que se haya especificado en "thresholdDuration"), imprime un informe, utilizando el archivo System.out.
La sonda que acabamos de explicar no funciona en aquellos métodos que sean recursivos (directa o indirectamente), y no funciona en aquellos métodos que puedan ejecutarse en varias hebras simultáneamente. Para resolver el problema recursivo, puede registrar las horas de entrada en una pila; para resolver el problema de varias hebras, puede almacenar la pila en una variable ThreadLocal.
He aquí lo que necesita para crear una versión de la sonda libre de hebras y de problemas recursivos:
static ThreadLocal tl = new ThreadLocal() { public Object initialValue() { return new Stack(); } }; static long thresholdDuration = 100; // Report if time is over 100ms
long now = System.currentTimeMillis(); Stack stk = (Stack)tl.get(); stk.push(new Long(now));
long now = System.currentTimeMillis(); Stack stk = (Stack)tl.get(); long entryTime = ((Long)stk.pop()).longValue(); if (now - entryTime > thresholdDuration) { System.out.println( "[Spent a long time in " + cName + "." + mName + ": this=" + thisObj + "]"); }
Para proseguir con la guía de aprendizaje, vaya al Ejercicio 1.5: Utilización de una biblioteca de tiempo de ejecución para obtener una lógica de sonda más compleja.