*   >> Lectura Educación Artículos >> science >> programación

Java: Cómo redirigir Stderr Y Stdout de Commons Logging, With The Calling Class

Muchas veces nos encontramos con que las bibliotecas 3 ª parte escribirán a System.out o System.err. Probablemente debería ser más fácil para volver a dirigir a estos marcos de registro comunes, pero no lo es.

A continuación encontrará una clase que puede utilizar para llevar a cabo exactamente esto. La clase es una instancia de PrintWriter y se pueden crear instancias y se utiliza como System.out y System.err PrintWriter. Será volver a dirigir todos los mensajes STDOUT y STDERR a Commons Registro.

También buscará la clase llamada y obtener un registrador con el nombre: com.domain.Class (opcionalmente con un prefijo definido por el usuario o un sufijo, tales como: STDOUT.com.domain.Class o com.domain.Class.STDOUT)

Para facilitar el uso que usted puede utilizar los métodos de fábrica estáticos que registran automáticamente la clase en STDOUT o STDERR respectivamente.

A continuación se presentan un par de ejemplos típicos de uso

Algunas notas acerca de cómo funciona:

  • PrintWriter se overriden, cada vez que un método se llama la clase llamada se busca y grabado ( métodos se sincronizan como lo son en PrintWriter.

  • Cuando un flush () se llama, o auto función ras de PrintWriter vacía el búfer, cada cadena individual se escribe en los Comunes Registro. ras PrintWriter () 's después de una completa línea se imprime, se encuentra un salto de línea, o una matriz de bytes se escribe.


  • El método de llamada se obtiene mediante el análisis de la StackTrace. Para que esto funcione, esta acción debe ocurrir inmediatamente después de llamar a cualquier método PrintWriter.

  • Las javadocs incluidos explican la mayor funcionalidad

    Ejemplo de uso: Al comienzo de su aplicación:

    principales (String [] args) {static void públicas CommonsLoggingPrintStream.registerOnStdout (null "STDOUT"); CommonsLoggingPrintStream.registerOnStderr (null, "STDERR"); //...

    }

    Ejemplo de uso: En primavera (añada lo siguiente a su contexto inicio, utiliza los métodos de fábrica por lo que no se requiere ningún código) :

    STDOUTSTDERR

    Código de Clase (nota: usted puede cambiar libremente el paquete /classname, que se utilizan en el código para anaylize el seguimiento de pila, pero se levantó de forma dinámica) paquete

    mycommons.logging; importación java.io.ByteArrayOutputStream; java.io.IOException importación; java.io.PrintStream importación, importación java.util.Locale, importación java.util.concurrent.locks.ReentrantLock; org.apache.commons.

    logging.LogFactory importación; /** * Esta clase re-dirige todas las peticiones a PrintStream (usado por stdout y stderr) * y los envía a los Comunes Registro. * * El método de llamada a PrintStream se determina mediante el análisis de la traza de la pila. * * Utilizar los métodos de conveniencia registerOnStdout y registerOnStderr automáticamente * crear una instancia de esta clase y registrarlo en la corriente para redirigir a * Commons Logging. * * Ejemplo de uso típico: * * * main (String [] args) void estáticos públicos {* CommonsLoggingPrintStream.

    registerOnStdout (null, "STDOUT"); * CommonsLoggingPrintStream.registerOnStderr (null, "STDERR"); * //...} * * * * Nota para los casos excéntricos: Si realiza varias llamadas a métodos que no activan * un color, como se explica en PrintWriter (por ejemplo, append (char)) el método de llamada * será determinado solamente por la última llamada que desencadena un color o llama a flush () directamente. También tenga en cuenta que * en este caso se debe sincronizar el acceso a estos métodos, ya que no serán seguros para subprocesos.

    * Se aconseja generalmente a sólo llamar a métodos que generan una descarga automática como se describe en los * javadocs PrintWriter * /public class CommonsLoggingPrintStream extiende PrintStream {LoggingOutputStream flujoSalida; cerradura ReentrantLock privada = new ReentrantLock (); /** * Se puede utilizar una nueva instancia para registrar todos los métodos PrintStream a Commons Registro.

    * Los mensajes se escriben en CommonsLogging cuando flush () se llama usando * las mismas reglas que utiliza PrintStream con autoFlush = true * *param prependName Un nombre antepuesto a la clase (nulo para ninguno) nombre como en: registerOnStdout ("STDOUT" , nulos) da como resultado un mensaje de registro, tales como: INFO STDOUT.org.mydomain.MyClass - Entrar mensaje *param postpendName Un nombre postpended a la clase (nulo para ninguno) nombre como en: registerOnStdout (null), resultados "STDOUT" en un mensaje de registro, tales como: el mensaje INFO org.mydomain.MyClass.

    STDOUT -Log * /CommonsLoggingPrintStream pública (String prependName, Cadena postpendName) {esta (nueva LoggingOutputStream (prependName, postpendName, CommonsLoggingPrintStream.class.getCanonicalName ())); } CommonsLoggingPrintStream privada (LoggingOutputStream los) {super (los, true); this.outputStream = los; } /** * Método Práctico - Crea una nueva instancia de * CommonsLoggingPrintStream y la registra en STDOUT * *param prependName Un nombre antepuesto a la clase (nulo para ninguno) nombre como en: registerOnStdout ("STDOUT", null) resulta en un mensaje de registro, tales como: INFO STDOUT.

    org.mydomain.MyClass - Ingresar mensaje *param postpendName Un nombre postpended a la clase (nulo para ninguno) nombre como en: registerOnStdout (null, "STDOUT") da como resultado un mensaje de registro como como: mensaje INFO org.mydomain.MyClass.STDOUT -Log *return una referencia al objeto CommonsLoggingPrintStream creado, puede ser ignorada en la mayoría de situaciones * /public static CommonsLoggingPrintStream registerOnStdout (String prependName, Cadena postpendName) {CommonsLoggingPrintStream ref = new CommonsLoggingPrintStream ( prependName, postpendName); System.

    setOut (ref); volver ref; } /** * Método Práctico - Crea una nueva instancia de * CommonsLoggingPrintStream y la registra en STDERR * *param prependName Un nombre antepuesto a la clase (nulo para ninguno) nombre como en: registerOnStdout ("STDERR", null) resultados en un mensaje de registro, tales como: INFO STDERR.org.mydomain.MyClass - Ingresar mensaje *param postpendName Un nombre postpended a la clase (nulo para ninguno) nombre como en: registerOnStdout (null, "STDERR") da como resultado un mensaje de registro como como: mensaje INFO org.mydomain.MyClass.

    STDERR -Log *return una referencia al objeto CommonsLoggingPrintStream creado, puede ser ignorada en la mayoría de situaciones * /public static CommonsLoggingPrintStream registerOnStderr (String prependName, Cadena postpendName) {CommonsLoggingPrintStream ref = new CommonsLoggingPrintStream ( prependName, postpendName); System.setErr (ref); volver ref; } /** * Esta clase es necesaria con el fin de hacer uso de PrintWriters garantiza * que ras será llamado en el momento apropiado.

    Publicamos datos a * Commons Loggging sólo después de flush () se llama en la salida * corriente envuelta por PrintWriter. * * /Private LoggingOutputStream clase estática extiende ByteArrayOutputStream {currentCallerName private String; private String prependName = null; private String postpendName = null; private String outerClassName = null; //Esta es generado dinámicamente por lo que los cambios en el paquete o el nombre de la clase no afectan a la funcionalidad LoggingOutputStream pública (String prependName, Cadena postpendName, Cadena outerClassName) {this.

    prependName = (prependName! = Null &&! PrependName.isEmpty ()) ? prependName + "." : ""; this.postpendName = (postpendName! = null &&! postpendName.isEmpty ())? "." + PostpendName: ""; this.outerClassName = outerClassName; }Override Public void flush () throws IOException {super.flush (); //Iniciar bytes resultantes después ras () se llama. Podemos confiar en esto porque //creamos el PrintStream con la opción autoFlush encendido. //Si una matriz de bytes se escribe puede contener varias líneas String [] AnotarMensajes = this.toString split () ("\\ n.

    "); for (String mensaje: AnotarMensajes) {LogFactory.getLog (currentCallerName) .info (message.trim ()); }} Void setNameOfCaller () {reachedCallToOutterClass Boolean = false; StackTraceElement [] = pila Thread.currentThread () getStackTrace (.); //Recorrer elementos traza de la pila hasta que encontremos "java.io.PrintStream" //y devolver la primera clase-nombre completo después de las llamadas a PrintStream para (e StackTraceElement: pila) {if (e.getClassName () .equals (outerClassName)) {reachedCallToOutterClass = true; continuar; } else if (reachedCallToOutterClass) {this.

    currentCallerName = prependName + e.getClassName () + postpendName; regreso; }} This.currentCallerName = "unknown.classname"; //Código inalcanzable (o eso teoría sostiene)}} /** * Pasa la llamada a outputStream.setNameOfCaller () sólo * si el bloqueo sincronizado en este es de propiedad de una vez. Si se trata de * poseía más de una vez, entonces es una devolución de llamada desde el interior * PrintWriter, situación que hará que sea difícil * /imposible determinar el método de llamada, y no es necesario, ya que * la primera llamada a setNameOfCaller () es todo lo que era * es necesario para determinar el método de llamada.

    * /Private void setNameOfCaller (bloqueo ReentrantLock) {if (lock.getHoldCount ()>

    Page   <<       [1] [2] [3] [4] [5] [6] >>
  • Copyright © 2008 - 2016 Lectura Educación Artículos,https://lectura.nmjjxx.com All rights reserved.