*   >> Leitura Educação Artigos >> science >> programação

Java: Como redirecionar Stderr E Stdout para Commons Logging, com o chamado Classe

Muitas vezes achamos que as bibliotecas 3o partido vai escrever para System.out ou System.err. Ele provavelmente deve ser mais fácil de re-direta para estes quadros registro comum, mas não é.

Abaixo, você encontrará uma classe que você pode usar para realizar exatamente isso. A classe é uma instância de PrintWriter e pode ser instanciado e usado como System.out e System.err PrintWriter. Ele irá redirecionar todas as mensagens STDOUT e STDERR para Commons Logging. Ele também irá olhar para a classe chamada e obter um logger sob o nome: com.domain.

Class (opcionalmente com um prefixo definido pelo usuário ou sufixo como: STDOUT.com.domain.Class ou com.domain.Class.STDOUT)

Para facilidade de uso que você pode usar os métodos estáticos de fábrica que registram automaticamente a classe na saída ou STDERR respectivamente. Abaixo estão alguns exemplos de utilização típicos

Algumas notas sobre como ele funciona:

  • PrintWriter é anulado, cada vez que um método é chamado a classe chamada está olhou para cima e gravadas ( métodos são sincronizados como estão em PrintWriter.


  • Quando um flush () é chamado, ou auto resplendor característica do PrintWriter libera o buffer, cada corda individualmente é escrito para Commons Logging. PrintWriter flush () 's depois de uma completa linha é impressa, uma nova linha é encontrado, ou uma matriz de bytes é escrito.

  • O método de chamada é obtido através da análise da StackTrace. Para que isso funcione, essa ação deve acontecer imediatamente após uma chamada para qualquer método PrintWriter.


  • Os javadocs incluídos explicar a maioria das funcionalidades

    Exemplo de uso: No início da sua aplicação:

    principais void (String [] args) {public static CommonsLoggingPrintStream.registerOnStdout (null "STDOUT"); CommonsLoggingPrintStream.registerOnStderr (null, "STDERR"); //...

    }

    Exemplo de uso: Na Primavera (adicione o seguinte ao seu contexto de inicialização, utiliza os métodos de fábrica assim é necessário nenhum código) :

    STDOUTSTDERR

    Código de classe (nota: você pode alterar livremente o pacote /classname, eles são usados ​​no código para anaylize o rastreamento de pilha, mas eles são procurados dinamicamente)

    pacote mycommons.logging; importação java.io.ByteArrayOutputStream; import java.io.IOException; java.io.PrintStream importação; importação java.util.Locale; importação java.util.concurrent.locks.ReentrantLock; importação org.apache.

    commons.logging.LogFactory; /** * Esta classe re-direciona todas as solicitações para PrintStream (usado por STDOUT e STDERR) * e os envia para Commons Logging. * * O método de chamada para PrintStream é determinada pela análise do rastreamento de pilha. * * Use os métodos de conveniência registerOnStdout e registerOnStderr para automaticamente * criar uma instância dessa classe e registrá-lo no fluxo para redirecionar para * commons logging. * * Exemplo de uso típico: * * * principais void (String [] args) {public static * CommonsLoggingPrintStream.

    registerOnStdout (null, "STDOUT"); * CommonsLoggingPrintStream.registerOnStderr (null, "STDERR"); * //...} * * * * Nota para os casos das aves raras: Se você fizer várias chamadas para métodos que não desencadear * um flush, como explicado no PrintWriter (por exemplo, anexar (char)) o método de chamada * será determinada apenas pela chamada final que desencadeia um flush ou chama flush () diretamente. Também note que * neste caso, você deve sincronizar o acesso a esses métodos, pois não vai ser thread-safe.

    * É geralmente aconselhados a chamar métodos únicos que geram um autoclismo automático conforme descrito * nos javadocs PrintWriter * /public class CommonsLoggingPrintStream estende PrintStream {LoggingOutputStream outputStream; bloqueio ReentrantLock privado = new ReentrantLock (); /** * Você pode usar uma nova instância para registrar todos os métodos para PrintStream Commons Logging.

    * As mensagens serão escritas para CommonsLogging quando flush () é chamado usando * as mesmas regras que PrintStream usa com autoflush = true * * @ param prependName Um nome anexado ao nome da classe (null para nenhum) como em: registerOnStdout ("STDOUT" , nulos) resulta em uma mensagem de log, tais como: INFO STDOUT.org.mydomain.MyClass - Log mensagem *param postpendName Um nome postpended ao nome da classe (null para nenhum) como em: registerOnStdout (nulos), resultados "STDOUT" em uma mensagem de log, tais como: INFO org.mydomain.MyClass.

    STDOUT -Log mensagem * /CommonsLoggingPrintStream pública (String prependName, String postpendName) {este (novo LoggingOutputStream (prependName, postpendName, CommonsLoggingPrintStream.class.getCanonicalName ())); } CommonsLoggingPrintStream privado (LoggingOutputStream los) {super (los, true); this.

    outputStream = los; } /** * Método de conveniência - Cria uma nova instância do * CommonsLoggingPrintStream e registra-lo em STDOUT * * @ param prependName Um nome anexado ao nome da classe (null para nenhum) como em: registerOnStdout ("STDOUT", null) resulta em uma mensagem de log, tais como: INFO STDOUT.org.mydomain.MyClass - Log mensagem *param postpendName Um nome postpended ao nome da classe (null para nenhum) como em: registerOnStdout (null, "STDOUT") resulta em uma mensagem de log, tais como: INFO org.mydomain.MyClass.

    STDOUT -Log mensagem *return uma referência para o objeto CommonsLoggingPrintStream criado, pode ser ignorada na maioria das situações * /public static CommonsLoggingPrintStream registerOnStdout (String prependName, String postpendName) {CommonsLoggingPrintStream ref = new CommonsLoggingPrintStream ( prependName, postpendName); System.

    setOut (Ref); retornar ref; } /** * Método de conveniência - Cria uma nova instância do * CommonsLoggingPrintStream e registra-lo em STDERR * * @ param prependName Um nome anexado ao nome da classe (null para nenhum) como em: registerOnStdout ("STDERR", null) resulta em uma mensagem de log, tais como: INFO STDERR.org.mydomain.MyClass - Log mensagem *param postpendName Um nome postpended ao nome da classe (null para nenhum) como em: registerOnStdout (null, "STDERR") resulta em uma mensagem de log, tais como: INFO org.mydomain.MyClass.

    STDERR -Log mensagem *return uma referência para o objeto CommonsLoggingPrintStream criado, pode ser ignorada na maioria das situações * /public static CommonsLoggingPrintStream registerOnStderr (String prependName, String postpendName) {CommonsLoggingPrintStream ref = new CommonsLoggingPrintStream ( prependName, postpendName); System.setErr (Ref); retornar ref; } /** * Esta classe é necessária, a fim de fazer uso de PrintWriters * garantir que nivelado será chamada no momento apropriado.

    Nós postar dados para * Commons Loggging somente após flush () é chamado no envolto fluxo de saída * por PrintWriter. * * /Private LoggingOutputStream classe estática estende ByteArrayOutputStream {currentCallerName private String; prependName private String = null; postpendName private String = null; private String outerClassName = null; //Este é gerada dinamicamente para que as alterações para o pacote ou nome da classe não afetam a funcionalidade LoggingOutputStream pública (String prependName, String postpendName, String outerClassName) {this.

    prependName = (prependName! = Null &&! PrependName.isEmpty ()) ? prependName + "." : ""; this.postpendName = (postpendName! = null &&! postpendName.isEmpty ())? "." + PostpendName: ""; this.outerClassName = outerClassName; Rubor vazio}Override pública () lança IOException {super.flush (); //Log resultante bytes após flush () é chamado. Podemos contar com isso porque //criamos o PrintStream com a opção autoflush ligado. //Se um array de bytes é escrito pode conter múltiplas linhas String [] = LogMessages this.toString () split ("\\ n."); for (String message: LogMessages) {LogFactory.

    getLog (currentCallerName) .info (message.trim ()); }} SetNameOfCaller void () {boolean reachedCallToOutterClass = false; StackTraceElement [] = pilha Thread.currentThread () getStackTrace (.); //Faz um loop através de elementos-traço de pilha até encontrar "java.io.PrintStream" //e retornar a primeira-classe-nome completo após as chamadas para PrintStream para (StackTraceElement e: pilha) {if (e.getClassName () .equals (outerClassName)) {reachedCallToOutterClass = true; continuar; } else if (reachedCallToOutterClass) {this.currentCallerName = prependName + e.

    getClassName () + postpendName; Retorna; }} This.currentCallerName = "unknown.classname"; //Código inacessível (ou assim teoria sustenta)}} /** * passa a chamada para outputStream.setNameOfCaller () só * se o bloqueio sincronizado nesta é de propriedade uma vez. Se for * possuíam mais de uma vez, então este é um retorno de chamada de dentro * PrintWriter, uma situação que irá tornar mais difícil * /impossível determinar o método de chamada, e não é necessário uma vez que * a primeira chamada para setNameOfCaller () é tudo o que era * necessários para determinar o método de chamada.

    * /SetNameOfCaller private void (bloqueio ReentrantLock) {if (lock.getHoldCount ()>

    Page   <<       [1] [2] [3] [4] [5] [6] >>
  • Copyright © 2008 - 2016 Leitura Educação Artigos,https://artigos.nmjjxx.com All rights reserved.