*   >> läser Utbildning artiklar >> science >> programming

Java: Hur man omdirigera stderr och stdout till Commons Logging, med den anropande Class

Många gånger finner vi att biblioteken 3: e parts kommer att skriva till System.out eller System.err. Det bör nog vara lättare att omdirigera dessa gemensamma avverknings ramar, men det är inte. Omdömen

Nedan hittar du en klass som du kan använda för att åstadkomma just detta. Klassen är en instans av PrintWriter och kan instansieras och användas som System.out och System.err PrintWriter. Det kommer att omdirigera alla stdout och stderr meddelanden till Commons Logging. Det kommer också att leta upp den uppringande klassen och få en logger under namnet: com.domain.

Class (eventuellt med ett användardefinierat prefix eller suffix som: STDOUT.com.domain.Class eller com.domain.Class.STDOUT)

För att underlätta användning kan du använda statiska fabriks metoder som automatiskt registrerar klass på STDOUT eller STDERR respektive. Här är ett par typiska exempel användnings

Några anteckningar om hur det fungerar:

  • PrintWriter är överstyras, varje gång en metod kallas den uppringande klassen såg upp och registreras ( metoder synkroniseras som de är i PrintWriter.

    Omdömen

  • När en flush () anropas eller PrintWriter auto flush funktion tömmer bufferten är varje enskild sträng skrivit till Commons Logging. PrintWriter flush () 's efter en fullständig linje skrivs ut, en ny rad påträffas, eller en bytearrayen skrivs. Omdömen
  • anropande metoden erhålls genom att analysera stacktrace. För att detta ska fungera måste denna åtgärd ske omedelbart efter ett anrop till någon PrintWriter metod.


  • De inkluderade JavaDocs förklarar mest funktionalitet

    Användning exempel: I början av din ansökan:

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

    Användning exempel: Under våren (lägg till följande i start sammanhang använder fabriks metoder, så ingen kod krävs)

    STDOUTSTDERR

    Class kod (OBS! Du kan fritt ändra paketet /klassnamn, används de i koden för att anaylize stackspårningen, men de såg upp dynamiskt) Review paket mycommons.

    logging, import java.io.ByteArrayOutputStream, import java.io.IOException, import java.io.PrintStream, import java.util.Locale, import java.util.concurrent.locks.ReentrantLock, import org.apache.commons.logging.LogFactory; /** * Denna klass åter styr alla förfrågningar till Print (används av STDOUT och STDERR) * och skickar dem till Commons Logging. * * Den uppringande metod för Print bestäms genom att analysera stackspårningen.

    * * Använd bekvämlighet metoder registerOnStdout och registerOnStderr automatiskt * skapa en instans av den här klassen och registrera den på strömmen dirigera till * Commons Logging. * * Exempel på typisk användning: * * * public void main (String [] args) {* CommonsLoggingPrintStream.registerOnStdout (null, "STDOUT"); * CommonsLoggingPrintStream.registerOnStderr (null, "STDERR"); * //...

    *} * * * OBS för udda fall: Om du gör flera samtal till metoder som inte utlöser * en färg, såsom förklaras i PrintWriter (till exempel lägga till (char)) den uppringande metod * kommer att bestämmas enbart av den slutliga samtal som utlöser en flush eller samtal flush () direkt. också notera att * i det här fallet måste du synkronisera tillgång till dessa metoder eftersom de inte kommer att trådsäkert.

    * Det är allmänt rekommenderas att endast samtalsmetoder som ger en automatisk spolning som beskrivs * i PrintWriter JavaDocs * /public class CommonsLoggingPrintStream sträcker Print {LoggingOutputStream Output; privat ReentrantLock lås = new ReentrantLock (); /** * Du kan använda en ny instans för att logga alla Print metoder till Commons Logging.

    * Meddelanden skrivs till CommonsLogging när flush () anropas med * samma regler som Print använder med autoFlush = true * *param prependName Ett namn föregås klassen (null för ingen) namn som i: registerOnStdout ("STDOUT" , null) resulterar i ett loggmeddelande såsom: INFO STDOUT.org.mydomain.MyClass - Log meddelande *param postpendName Ett namn postpended klassen (null för ingen) namn som i: registerOnStdout (null, "STDOUT") resultat i ett loggmeddelande såsom: INFO org.mydomain.MyClass.

    STDOUT -Log meddelande * /public CommonsLoggingPrintStream (String prependName, String postpendName) {detta (nya LoggingOutputStream (prependName, postpendName, CommonsLoggingPrintStream.class.getCanonicalName ())); } Privat CommonsLoggingPrintStream (LoggingOutputStream los) {super (los, true); this.outputStream = los; } /** * Convenience metod - Skapar en ny instans av * CommonsLoggingPrintStream och registrerar det på STDOUT * *param prependName Ett namn föregås klassen (null för ingen) namn som i: registerOnStdout ("stdout", null) resulterar i ett loggmeddelande såsom: INFO STDOUT.org.

    mydomain.MyClass - Log meddelande *param postpendName Ett namn postpended klassen (null för ingen) namn som i: registerOnStdout (null, "STDOUT") resulterar i en loggmeddelande sådan som: INFO org.mydomain.MyClass.STDOUT -Log meddelande *return en hänvisning till CommonsLoggingPrintStream objekt som skapas, kan ignoreras i de flesta situationer * /public static CommonsLoggingPrintStream registerOnStdout (String prependName, String postpendName) {CommonsLoggingPrintStream ref = new CommonsLoggingPrintStream ( prependName, postpendName); System.

    setOut (ref); retur ref; } /** * Convenience metod - Skapar en ny instans av * CommonsLoggingPrintStream och registrerar det på STDERR * *param prependName Ett namn föregås klassen (null för ingen) namn som i: registerOnStdout ("STDERR", null) resulterar i ett loggmeddelande såsom: INFO STDERR.org.mydomain.MyClass - Log meddelande *param postpendName Ett namn postpended klassen (null för ingen) namn som i: registerOnStdout (null, "STDERR") resulterar i en loggmeddelande sådan som: INFO org.mydomain.MyClass.

    STDERR -Log meddelande *return en hänvisning till CommonsLoggingPrintStream objekt som skapas, kan ignoreras i de flesta situationer * /public static CommonsLoggingPrintStream registerOnStderr (String prependName, String postpendName) {CommonsLoggingPrintStream ref = new CommonsLoggingPrintStream ( prependName, postpendName); System.setErr (ref); retur ref; } /** * Denna klass krävs för att utnyttja PrintWriters garanterar * att flush kommer att kallas vid lämplig tidpunkt. Vi lägger data till * Commons Loggging först efter flush () anropas på inslagna utgång * strömmen genom PrintWriter.

    * * /Private static klass LoggingOutputStream utökar ByteArrayOutputStream {private String currentCallerName; private String prependName = null; private String postpendName = null; private String outerClassName = null; //Detta genereras dynamiskt så att ändringar i paketet eller klassnamnet inte påverkar funktionalitet offentliga LoggingOutputStream (String prependName, String postpendName, String outerClassName) {this.prependName = (prependName! = Null &&! PrependName.isEmpty ()) ? prependName + "." : ""; this.postpendName = (postpendName! = null &&! postpendName.isEmpty ())? ".

    " + PostpendName: ""; this.outerClassName = outerClassName; }Override Public void flush () kastar IOException {super.flush (); //Logg resulterande byte efter flush () anropas. Vi kan lita på detta eftersom //vi skapat Print med alternativet autoFlush påslagen. //Om en bytearray skrivs det kan innehålla flera rader String [] logMessages = this.toString () split ("\\ n"). för (String meddelande: logMessages) {LogFactory.getLog (currentCallerName) .info (message.trim ()); }} Void setNameOfCaller () {boolean reachedCallToOutterClass = false; StackTraceElement [] stapel = Thread.

    currentThread () getstacktrace ().; //Loop genom stackspårämnen tills vi hittar "java.io.PrintStream" //och returnera första fullt kvalificerad klassnamn efter samtal till Print för (StackTraceElement e: stack) {if (e.getClassName () .equals (outerClassName)) {reachedCallToOutterClass = true; fortsätta; } else if (reachedCallToOutterClass) {this.currentCallerName = prependName + e.getClassName () + postpendName; återvända; }} This.currentCallerName = "unknown.classname"; //Unreachable kod (eller så teori innehar)}} /** * Klarar uppmaningen till outputStream.

    setNameOfCaller () endast * om den synkroniserade låset på detta ägs gång. Om det * ägde mer än en gång då det är en återuppringning inifrån * PrintWriter, en situation som kommer att göra det svårt /omöjligt * att bestämma den anropande metoden, och är inte nödvändigt eftersom * det första samtalet till setNameOfCaller () är allt som var * som behövs för att bestämma den anropande metoden. * /Private void setNameOfCaller (ReentrantLock lås) {if (lock.getHoldCount ()>

    Page   <<       [1] [2] [3] [4] [5] [6] >>
  • Copyright © 2008 - 2016 läser Utbildning artiklar,https://utbildning.nmjjxx.com All rights reserved.