*   >> Lezen Onderwijs artikelen >> science >> programming

Java: Hoe Redirect STDERR En Stdout naar Commons Logging, With The Calling Class

Vele malen hebben wij vinden dat 3rd party bibliotheken schrijven System.out of System.err. Het zou waarschijnlijk gemakkelijker zijn om deze gemeenschappelijke logging kaders-direct weer, maar is het niet.

Hieronder vindt u een klasse die u kunt gebruiken om precies dit te bereiken zal vinden. De klasse is een instantie van PrintWriter en kan worden geïnstantieerd en gebruikt als de System.out en System.err PrintWriter. Het zal opnieuw direct alle STDOUT en STDERR berichten naar Commons Logging.

Het zal ook kijken op de roeping klasse en het verkrijgen van een logger onder de naam: com.domain.Class (eventueel met een door de gebruiker gedefinieerde voor- of achtervoegsel zoals: STDOUT.com.domain.Class of com.domain.Class.STDOUT)

Voor het gebruiksgemak kunt u de statische fabriek methoden die automatisch de klasse te registreren op STDOUT of STDERR respectievelijk gebruiken.

Hieronder zijn een paar typische voorbeelden van het gebruik

Een paar opmerkingen over hoe het werkt:

  • PrintWriter wordt overschreven, elke keer dat een methode is de roeping klasse met de naam wordt opgezocht en vastgelegd ( methoden worden gesynchroniseerd als ze in PrintWriter.

  • Wanneer een flush () wordt aangeroepen, of PrintWriter auto-flush functie spoelt de buffer, elke individuele String is geschreven Commons Logging. PrintWriter flush () 's na een volledige lijn wordt afgedrukt, een nieuwe regel wordt aangetroffen, of een byte array geschreven.


  • De roeping methode wordt verkregen door het analyseren van de StackTrace. Om dit te laten werken, moet deze actie na een oproep aan een PrintWriter methode onmiddellijk gebeuren.

  • De meegeleverde javadocs verklaren de meeste functionaliteit

    Gebruik bijvoorbeeld: Aan het begin van uw aanvraag:

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

    }

    Gebruik voorbeeld: In het voorjaar (het volgende toevoegen aan uw opstarten context, maakt gebruik van de fabriek methoden zodat er geen code is vereist) :

    STDOUTSTDERR

    Class code (let op: u kunt vrijelijk te veranderen het pakket /classname, worden ze gebruikt in de code om de stack trace anaylize, maar ze worden opgezocht dynamisch)

    pakket 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; /** * Deze klasse re-regisseert alle verzoeken om PrintStream (gebruikt door STDOUT en STDERR) * en stuurt ze naar Commons Logging. * * De roeping methode om PrintStream wordt bepaald door het analyseren van de stack trace. * * Gebruik het gemak methoden registerOnStdout en registerOnStderr automatisch * een instantie van deze klasse en registreer deze op de stroom om te leiden naar * Commons Logging. * Voorbeeld van typische gebruik: * * * public static void main (String [] args) {* CommonsLoggingPrintStream.registerOnStdout (null, "STDOUT"); * CommonsLoggingPrintStream.

    registerOnStderr (null, "STDERR"); * //...} * * * * Noot voor de excentrieke gevallen: Als u meerdere oproepen van methoden die niet leiden * een flush, zoals uitgelegd in PrintWriter (bijvoorbeeld, voegen (char)) de roeping methode * wordt alleen bepaald door de laatste oproep die een flush triggers of oproepen flush () direct. ook rekening mee dat * in dit geval moet u de toegang tot deze methoden te synchroniseren als ze niet worden thread safe.

    * Het is meestal aangeraden om alleen bellen methoden die een automatische spoeling te genereren, zoals beschreven * in de PrintWriter javadocs * /public class CommonsLoggingPrintStream breidt PrintStream {LoggingOutputStream OutputStream; private ReentrantLock slot = new ReentrantLock (); /** * U kunt een nieuwe instantie gebruiken om alle PrintStream methoden om Commons Logging loggen.

    * Berichten worden geschreven om CommonsLogging wanneer flush () wordt aangeroepen met * dezelfde regels als PrintStream gebruikt met automatische spoeling = true * *param prependName Een naam toegevoegd aan de klasse (null voor geen) naam als in: registerOnStdout ("STDOUT" , null) resulteert in een logboek bericht zoals: INFO STDOUT.org.mydomain.MyClass - Inloggen bericht *param postpendName Een naam postpended tot de klasse (null voor geen) naam als in: registerOnStdout (null, "STDOUT") resultaten in een logboek bericht zoals: INFO org.mydomain.MyClass.

    STDOUT -Log bericht * /public CommonsLoggingPrintStream (String prependName, String postpendName) {dit (nieuwe LoggingOutputStream (prependName, postpendName, CommonsLoggingPrintStream.class.getCanonicalName ())); } Private CommonsLoggingPrintStream (LoggingOutputStream los) {super (los, true); this.

    outputStream = los; } /** * Gemak methode - Maakt een nieuw exemplaar van * CommonsLoggingPrintStream en registreert deze op STDOUT * *param prependName Een naam toegevoegd aan de klasse (null voor geen) naam als in: registerOnStdout ("STDOUT", null) resulteert in een log boodschap zoals: INFO STDOUT.org.mydomain.MyClass - Inloggen bericht *param postpendName Een naam postpended tot de klasse (null voor geen) naam als in: registerOnStdout (null, "STDOUT") resulteert in een logboek bericht zoals als: INFO org.mydomain.MyClass.

    STDOUT -Log bericht *return een verwijzing naar het CommonsLoggingPrintStream object gemaakt, kunnen worden genegeerd in de meeste situaties * /public static CommonsLoggingPrintStream registerOnStdout (String prependName, String postpendName) {CommonsLoggingPrintStream ref = new CommonsLoggingPrintStream ( prependName, postpendName); System.

    setOut (ref); terug ref; } /** * Gemak methode - Maakt een nieuw exemplaar van * CommonsLoggingPrintStream en registreert deze op STDERR * *param prependName Een naam toegevoegd aan de klasse (null voor geen) naam als in: registerOnStdout ("STDERR", null) resulteert in een log boodschap zoals: INFO STDERR.org.mydomain.MyClass - Inloggen bericht *param postpendName Een naam postpended tot de klasse (null voor geen) naam als in: registerOnStdout (null, "STDERR") resulteert in een logboek bericht zoals als: INFO org.mydomain.MyClass.

    STDERR -Log bericht *return een verwijzing naar het CommonsLoggingPrintStream object gemaakt, kunnen worden genegeerd in de meeste situaties * /public static CommonsLoggingPrintStream registerOnStderr (String prependName, String postpendName) {CommonsLoggingPrintStream ref = new CommonsLoggingPrintStream ( prependName, postpendName); System.setErr (ref); terug ref; } /** * Deze klasse is nodig om gebruik te maken van PrintWriters garanderen * dat de flush zal op het juiste moment worden opgeroepen.

    We plaatsen gegevens * Commons Loggging pas na flush () wordt aangeroepen op het verpakte uitgang * stroom door PrintWriter. * * /Private static class LoggingOutputStream breidt ByteArrayOutputStream {private String currentCallerName; private String prependName = null; private String postpendName = null; private String outerClassName = null; //Dit wordt dynamisch gegenereerd, zodat wijzigingen in het pakket of de naam van de klasse hebben geen invloed op de functionaliteit openbare 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 () gooit IOException {super.flush (); //Inloggen resulterende bytes na flush () wordt aangeroepen. We kunnen vertrouwen op dit omdat //hebben we de PrintStream met de optie automatische spoeling ingeschakeld. //Als een bytearray geschreven kan meerdere regels bevatten String [] logMessages = this.toString () split ("\\ n.

    "); voor (String bericht: logMessages) {LogFactory.getLog (currentCallerName) .info (message.trim ()); }} Leegte setNameOfCaller () {boolean reachedCallToOutterClass = false; StackTraceElement [] stack = Thread.currentThread () getStackTrace ().; //Loop door de stack sporenelementen totdat we "java.io.PrintStream" //en de terugkeer van de eerste volledig gekwalificeerde-class-name na de oproepen om PrintStream voor (StackTraceElement e: stack) {if (e.getClassName () .equals (outerClassName)) {reachedCallToOutterClass = true; voort te zetten; } else if (reachedCallToOutterClass) {this.

    currentCallerName = prependName + e.getClassName () + postpendName; terug; }} This.currentCallerName = "unknown.classname"; //Onbereikbaar code (of zo theorie houdt)}} /** * Passes de oproep aan outputStream.setNameOfCaller () * Alleen wanneer de gesynchroniseerde slot op deze ene keer is eigendom. Als het * Meer dan een keer dan is dit een callback vanuit * PrintWriter, een situatie die het moeilijk /onmogelijk * aan de roeping methode te bepalen zal in handen, en is niet nodig, omdat * de eerste oproep om setNameOfCaller () is alles wat was * nodig belmethode bepalen.

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

    Page   <<       [1] [2] [3] [4] [5] [6] >>
  • Copyright © 2008 - 2016 Lezen Onderwijs artikelen,https://onderwijs.nmjjxx.com All rights reserved.