Utilización de un registrador

El registrador de Java™ se puede usar para registrar mensajes y añadir rastreo.

Acerca de esta tarea

Java proporciona un paquete de registro y rastreo, java.util.logging, que se puede utilizar para instrumentalizar las aplicaciones. Este tema proporciona recomendaciones sobre cómo utilizar el paquete de registro y rastreo.

Procedimiento

  1. Utilice el nivel WsLevel.DETAIL y niveles superiores para los mensajes, y niveles inferiores para el rastreo. El API de extensión de WebSphere Application Server (el paquete com.ibm.websphere.logging) contiene la clase WsLevel.
    Para los mensajes, utilice:
    WsLevel.FATAL
    Level.SEVERE
    Level.WARNING
    WsLevel.AUDIT
    Level.INFO
    Level.CONFIG
    WsLevel.DETAIL
    Para el rastreo, utilice:
    Level.FINE
    Level.FINER
    Level.FINEST
  2. Utilice el método logp en lugar del método log o logrb. El método logp admite parámetros para el nombre de clase y el nombre de método. Generalmente, los métodos log y logrb intentan inferir esta información, pero la penalización del rendimiento resulta prohibitiva. En general, el método logp penaliza menos el rendimiento que los métodos log o logrb.
  3. Evite el uso del método logrb. Este método da lugar a un almacenamiento en caché ineficaz de los paquetes de recursos y a un bajo rendimiento.
  4. Utilice el método isLoggable para evitar la creación de datos en una llamada de anotación cronológica que no se anote. Por ejemplo:
    if (logger.isLoggable(Level.FINEST)) {
     	String s = dumpComponentState();	// método de computación costosa
     	logger.logp(Level.FINEST, className, methodName, "componentX state
    dump:\n{0}", s);
     }

Mensajes localizados

El siguiente ejemplo se aplica a los mensajes localizados:
// nota -
generalmente, evite utilizar los niveles FINE, FINER, FINEST para que los mensajes
sean coherentes con
// WebSphere Application Server

String componentName = "com.ibm.websphere.componentX";
String resourceBundleName = "com.ibm.websphere.componentX.Messages";
Logger logger = Logger.getLogger(componentName, resourceBundleName);

// Métodos de "comodidad" - por lo general no se recomiendan debido a la falta de
// nombres de métodos de clases
//   - no se pueden especificar parámetros de sustitución de mensajes
//   - no se pueden especificar nombres de clase y método
if (logger.isLoggable(Level.SEVERE))
	logger.severe("MSG_KEY_01");

if (logger.isLoggable(Level.WARNING))
	logger.warning("MSG_KEY_01");

if (logger.isLoggable(Level.INFO))
	logger.info("MSG_KEY_01");

if (logger.isLoggable(Level.CONFIG))
	logger.config("MSG_KEY_01");


// los métodos de registro no suelen usarse debido a la falta de nombres de
// método y clase
//   - habilita el uso de niveles específicos de WebSphere Application Server
//   - habilita el uso de parámetros de sustitución de mensajes
//   - no se pueden especificar nombres de clase y método
if (logger.isLoggable(WsLevel.FATAL))
	logger.log(WsLevel.FATAL, "MSG_KEY_01", "parameter 1");

if (logger.isLoggable(Level.SEVERE))
	logger.log(Level.SEVERE, "MSG_KEY_01", "parameter 1");

if (logger.isLoggable(Level.WARNING))
	logger.log(Level.WARNING, "MSG_KEY_01", "parameter 1");

if (logger.isLoggable(WsLevel.AUDIT))
	logger.log(WsLevel.AUDIT, "MSG_KEY_01", "parameter 1");

if (logger.isLoggable(Level.INFO))
	logger.log(Level.INFO, "MSG_KEY_01", "parameter 1");

if (logger.isLoggable(Level.CONFIG))
	logger.log(Level.CONFIG, "MSG_KEY_01", "parameter 1");

if (logger.isLoggable(WsLevel.DETAIL))
	logger.log(WsLevel.DETAIL, "MSG_KEY_01", "parameter 1");


// los métodos logp son la forma de anotar cronológicamente
//   - habilita el uso de niveles específicos de WebSphere Application Server
//   - habilita el uso de parámetros de sustitución de mensajes
//   - habilita el uso de nombres de método y clase
if (logger.isLoggable(WsLevel.FATAL))
	logger.logp(WsLevel.FATAL, className, methodName, "MSG_KEY_01",
"parameter 1");

if (logger.isLoggable(Level.SEVERE))
	logger.logp(Level.SEVERE, className, methodName, "MSG_KEY_01",
"parameter 1");

if (logger.isLoggable(Level.WARNING))
	logger.logp(Level.WARNING, className, methodName, "MSG_KEY_01",
"parameter 1");

if (logger.isLoggable(WsLevel.AUDIT))
	logger.logp(WsLevel.AUDIT, className, methodName, "MSG_KEY_01",
"parameter 1");

if (logger.isLoggable(Level.INFO))
	logger.logp(Level.INFO, className, methodName, "MSG_KEY_01",
"parameter 1");

if (logger.isLoggable(Level.CONFIG))
	logger.logp(Level.CONFIG, className, methodName, "MSG_KEY_01",
"parameter 1");

if (logger.isLoggable(WsLevel.DETAIL))
	logger.logp(WsLevel.DETAIL, className, methodName, "MSG_KEY_01",
"parameter 1");


// los métodos logrb no suelen usarse porque penalizan el rendimiento
// de la conmutación dinámica de paquetes de recursos
//   - habilita el uso de niveles específicos de WebSphere Application Server
//   - habilita el uso de parámetros de sustitución de mensajes
//   - habilita el uso de nombres de método y clase
String resourceBundleNameSpecial =
"com.ibm.websphere.componentX.MessagesSpecial";

if (logger.isLoggable(WsLevel.FATAL))
	logger.logrb(WsLevel.FATAL, className, methodName, resourceBundleNameSpecial,
"MSG_KEY_01", "parameter 1");

if (logger.isLoggable(Level.SEVERE))
	logger.logrb(Level.SEVERE, className, methodName, resourceBundleNameSpecial,
"MSG_KEY_01", "parameter 1");

if (logger.isLoggable(Level.WARNING))
	logger.logrb(Level.WARNING, className, methodName, resourceBundleNameSpecial,
"MSG_KEY_01", "parameter 1");

if (logger.isLoggable(WsLevel.AUDIT))
	logger.logrb(WsLevel.AUDIT, className, methodName, resourceBundleNameSpecial,
"MSG_KEY_01", "parameter 1");

if (logger.isLoggable(Level.INFO))
	logger.logrb(Level.INFO, className, methodName, resourceBundleNameSpecial,
"MSG_KEY_01", "parameter 1");

if (logger.isLoggable(Level.CONFIG))
	logger.logrb(Level.CONFIG, className, methodName, resourceBundleNameSpecial,
"MSG_KEY_01", "parameter 1");

if (logger.isLoggable(WsLevel.DETAIL))
	logger.logrb(WsLevel.DETAIL, className, methodName, resourceBundleNameSpecial,
"MSG_KEY_01", "parameter 1");
En el caso del rastreo o de un contenido que no esté localizado, se aplica el ejemplo siguiente:
// nota - por lo general, evite el uso de los niveles FATAL, SEVERE, WARNING, AUDIT,
// INFO, CONFIG, DETAIL en el rastreo
// para mantener la coherencia con WebSphere Application Server

String componentName = "com.ibm.websphere.componentX";
Logger logger = Logger.getLogger(componentName);

// Los métodos de entrada/salida se usan en métodos no triviales
if (logger.isLoggable(Level.FINER))
	logger.entering(className, methodName);
	
if (logger.isLoggable(Level.FINER))
	logger.entering(className, methodName, "method param1");

if (logger.isLoggable(Level.FINER))
	logger.exiting(className, methodName);

if (logger.isLoggable(Level.FINER))
	logger.exiting(className, methodName, "method result");


// El método throwing no suele usarse por falta de mensaje - use
// en su lugar logp con un parámetro throwable
if (logger.isLoggable(Level.FINER))
	logger.throwing(className, methodName, throwable);


// Los métodos de conveniencia no suelen usarse debido a la carencia de
// nombres de método de clase
//   - no se pueden especificar parámetros de sustitución de mensajes
//   - no se pueden especificar nombres de clase y método
if (logger.isLoggable(Level.FINE))
	logger.fine("Esta es mi traza");

if (logger.isLoggable(Level.FINER))
	logger.finer("Esta es mi traza");

if (logger.isLoggable(Level.FINEST))
	logger.finest("Esta es mi traza");


// los métodos log no suelen usarse por falta de nombres de clase
// y método
//   - habilita el uso de niveles específicos de WebSphere Application Server
//   - habilita el uso de parámetros de sustitución de mensajes
//   - no se pueden especificar nombres de clase y método
if (logger.isLoggable(Level.FINE))
	logger.log(Level.FINE, "Esta es mi traza", "parameter 1");

if (logger.isLoggable(Level.FINER))
	logger.log(Level.FINER, "Esta es mi traza", "parameter 1");

if (logger.isLoggable(Level.FINEST))
	logger.log(Level.FINEST, "Esta es mi traza", "parameter 1");


// los métodos logp son la forma recomendada de realizar anotaciones
//   - habilita el uso de niveles específicos de WebSphere Application Server
//   - habilita el uso de parámetros de sustitución de mensajes
//   - habilita el uso de nombres de método y clase
if (logger.isLoggable(Level.FINE))
	logger.logp(Level.FINE, className, methodName, "Esta es mi traza",
"parameter 1");

if (logger.isLoggable(Level.FINER))
	logger.logp(Level.FINER, className, methodName, "Esta es mi traza",
"parameter 1");

if (logger.isLoggable(Level.FINEST))
	logger.logp(Level.FINEST, className, methodName, "Esta es mi traza",
"parameter 1");


// los métodos logrb no se aplican en el registro de rastreo porque no hay ninguna localización
// implicada
Pueden darse casos en los que solo desee propagar registros de anotaciones cronológicas a sus propios manejadores de registros, en lugar de participar en un registro cronológico integrado. Para utilizar un manejador de registro cronológico autónomo, establezca el distintivo useParentHandlers a false en su aplicación. El mecanismo de creación de un manejador personalizado es el soporte de la clase Handler que proporciona IBM® Developer Kit, Java Technology Edition. Si no está familiarizado con la forma en que Developer Kit implementa los manejadores, puede obtener más información en diversos textos o en la documentación del API de java.util.logging. A continuación se muestra un ejemplo de manejador personalizado:
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.logging.Handler;
import java.util.logging.LogRecord;

/**
 * MyCustomHandler vuelca contenido en un archivo especificado
 */
public class MyCustomHandler extends Handler {

	FileOutputStream fileOutputStream;
	PrintWriter printWriter;

	public MyCustomHandler(String filename) {
		super();

		// se comprueba el parámetro de entrada
		if (filename == null || filename == "")
			filename = "mylogfile.txt";
		
		try {
			// se inicializa el archivo
			fileOutputStream = new FileOutputStream(filename);
			printWriter = new PrintWriter(fileOutputStream);
			 setFormatter(new SimpleFormatter());
		}
		catch (Exception e) {
			// se implementa el manejo de excepciones...
		}
	}

	/* (documentación que no es de API)
	 * @see java.util.logging.Handler#publish(java.util.logging.LogRecord)
	 */
	public void publish(LogRecord record) {
		// se garantiza que este registro de anotación sea anotado por este manejador
		if (!isLoggable(record))
			return;
		
		// Se escriben los datos formateados en el archivo
		printWriter.println(getFormatter().format(record));
	}

	/* (documentación que no es de API)
	 * @see java.util.logging.Handler#flush()
	 */
	public void flush() {
		printWriter.flush();
	}

	/* (documentación que no es de API)
	 * @see java.util.logging.Handler#close()
	 */
	public void close() throws SecurityException {
		printWriter.close();
	}
}

Un filtro personalizado proporciona un control opcional y secundario sobre lo que se anota cronológicamente, más allá del control que proporciona el nivel. El mecanismo de creación de un filtro personalizado es el soporte de la interfaz Filter que proporciona IBM Developer Kit, Java Technology Edition. Si no está familiarizado con la forma en que el kit del desarrollador implementa los filtros, puede obtener más información en diversos textos o en la documentación del API de java.util.logging.

En el ejemplo siguiente se muestra un filtro personalizado:

/**
 * Esta clase filtra todos los mensajes de registro cronológico que empiezan por SECJ022E, SECJ0373E o SECJ0350E.
 */
import java.util.logging.Filter;
import java.util.logging.Handler;
import java.util.logging.Logger;
import java.util.logging.LogRecord;

public class MyFilter implements Filter {
	public boolean isLoggable(LogRecord lr) {
		String msg = lr.getMessage();
		if (msg.startsWith("SECJ0222E") || msg.startsWith("SECJ0373E") || msg.startsWith("SECJ0350E")) {
			return false;
		}
		return true;
	}
}

// Este código registrará el filtro de registro en los manejadores del registrador raíz
// (incluyendo los registros cronológicos de sistema de WAS):
...
Logger rootLogger = Logger.getLogger("");
rootLogger.setFilter(new MyFilter());

Un formateador da formato a sucesos. Los manejadores están asociados a uno o más formateadores. El mecanismo de creación de un formateador personalizado es el soporte de la clase Formatter proporcionado por IBM Developer Kit, Java Technology Edition. Si no está familiarizado con la los formateadores implementados por kit del desarrollador, puede obtener más información en diversos textos o en la documentación del API de java.util.logging.

En el ejemplo siguiente se muestra un formateador personalizado:

import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;

/**
 * MyCustomFormatter formatea LogRecord de la manera siguiente:
 * fecha   nivel   mensaje localizado con parámetros
 */
public class MyCustomFormatter extends Formatter {

	public MyCustomFormatter() {
		super();
	}

	public String format(LogRecord record) {
		
		// Se crea un StringBuffer para que contenga el registro formateado
		// Se empieza por la fecha.
		StringBuffer sb = new StringBuffer();
		
		// Se obtiene la fecha del LogRecord y se añade al búfer
		Date date = new Date(record.getMillis());
		sb.append(date.toString());
		sb.append(" ");
		
		// Se obtiene el nombre del nivel y se añade al búfer
		sb.append(record.getLevel().getName());
		sb.append(" ");
		 
		// Se obtiene el mensaje formateado (incluye la localización
		// y la sustitución de parámetros) y se añade al búfer
		sb.append(formatMessage(record));
		sb.append("\n");

		return sb.toString();
	}
}

La adición de manejadores, filtros y formateadores permite personalizar el entorno de registro cronológico más allá de lo que lo hace la configuración de la infraestructura de registro cronológico de WebSphere Application Server de forma predeterminada. El siguiente ejemplo muestra cómo añadir un manejador nuevo para procesar peticiones al subárbol com.myCompany de los registradores cronológicos (consulte Configuración de la jerarquía de registradores). El método main de este ejemplo ilustra cómo usar el registrador recién creado.

import java.util.Vector;
import java.util.logging.Filter;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MyCustomLogging {

	public MyCustomLogging() {
		super();
	}

	public static void initializeLogging() {
		
		// Se obtiene el registrador al que se quiere adjuntar un Handler (manejador) personalizado
		String defaultResourceBundleName = "com.myCompany.Messages";
		Logger logger = Logger.getLogger("com.myCompany", defaultResourceBundleName);
		
		// Se configura un manejador personalizado (consulte el ejemplo MyCustomHandler)
		Handler handler = new MyCustomHandler("MyOutputFile.log");
		
		// Se configura un filtro personalizado (consulte el ejemplo MyCustomFilter)
		Vector acceptableLevels = new Vector();
		acceptableLevels.add(Level.INFO);
		acceptableLevels.add(Level.SEVERE);
		Filter filter = new MyCustomFilter(acceptableLevels);
		
		// Se configura un formateador personalizado (consulte el ejemplo MyCustomFormatter)
		Formatter formatter = new MyCustomFormatter();

		// Se conectan el filtro y el formateador al manejador
		handler.setFilter(filter);
		handler.setFormatter(formatter);
		
		// Se conecta el manejador al registrador
		logger.addHandler(handler);
		
		// se evita enviar a com.myCompany los mensajes registrados que aparecen en
		// los registros cronológicos de WebSphere Application Server
		logger.setUseParentHandlers(false);
				
	}

	public static void main(String[] args) {
		initializeLogging();
		
		Logger logger = Logger.getLogger("com.myCompany");
		
		logger.info("Mensaje INFO de prueba");
		logger.warning("Mensaje WARNING de prueba");
		logger.logp(Level.SEVERE, "MyCustomLogging", "main", "Mensaje SEVERE de prueba");
	}
}
Cuando se ejecuta el programa anterior, la salida del programa se escribe en el archivo MiOutputFile.log. El contenido de las anotaciones cronológicas se encuentra en el archivo de anotaciones cronológicas esperado, tal y como lo controla el manejador personalizado, y está formateado según lo determina el formateador personalizado. El mensaje de advertencia (warning) se descarta por filtrado tal y como se especifica en la configuración dle filtro personalizado. La salida es la siguiente:
C:\>type MyOutputFile.log
Sat Sep 04 11:21:19 EDT 2004 INFO Mensaje INFO de prueba
Sat Sep 04 11:21:19 EDT 2004 SEVERE Mensaje SEVERE de prueba

Icon that indicates the type of topic Task topic



Timestamp icon Last updated: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=ttrb_createloginstance
File name: ttrb_createloginstance.html