*   >> Lese Utdanning Artikler >> science >> programming

Java: Hvordan omdirigere stderr og standard ut til Commons Logging, With The Calling Class

Mange ganger opplever vi at 3. parts biblioteker vil skrive til System.out eller System.err. Det bør nok være lettere å omdirigere disse til felles logging rammeverk, men det er ikke.

Nedenfor finner du en klasse som du kan bruke til å oppnå akkurat dette. Klassen er en forekomst av Printwriter og kan startes og brukes som System.out og System.err Printwriter. Det vil omdirigere alle stdout og stderr meldinger til Commons Logging. Det vil også slå opp kallet klassen og få en logger under navnet: com.domain.

Class (eventuelt med en brukerdefinert prefiks eller suffiks som: STDOUT.com.domain.Class eller com.domain.Class.STDOUT)

For brukervennlighet du kan bruke de statiske fabrikk metoder som automatisk registrerer klassen på STDOUT eller STDERR hhv. Nedenfor er et par typiske bruk eksempler

Noen notater om hvordan det fungerer:

  • Printwriter er overstyrt, hver gang en metode kalles kallet klassen er så opp og registrert ( metoder blir synkronisert som de er i Printwriter.


  • Når en flush () kalles, eller Printwriter auto flush funksjonen tømmer buffer, er hver enkelt String skrevet til Commons Logging. Printwriter flush () 's etter en hel linjen er skrevet ut, et linjeskift er oppstått, eller en byte array er skrevet.

  • kall metoden oppnås ved å analysere StackTrace. For at dette skal fungere, må denne handlingen skje umiddelbart etter et kall til enhver Printwriter metode.


  • De inkluderte javadocs forklare mest funksjonalitet

    Bruks eksempel: I begynnelsen av programmet:

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

    Bruks eksempel: I Spring (legge til følgende i oppstart sammenheng, bruker fabrikk metoder så ingen kode kreves) :

    STDOUTSTDERR

    Class-kode (merk: du kan fritt endre pakken /klassenavn, blir de brukt i koden til anaylize stabelen spor, men de er så opp dynamisk)

    pakken 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; /** * Denne klassen re-dirigerer alle forespørsler til Print (brukt av STDOUT og STDERR) * og sender dem til Commons Logging. * * Kallet metoden for å Print bestemmes ved å analysere stabel spor.

    * * Bruk convenience metoder registerOnStdout og registerOnStderr til automatisk * opprette en forekomst av denne klassen og registrere den på strømmen for å omdirigere til * Commons logging. * * Eksempel på typisk bruk: * * * public static void main (String [] args) {* CommonsLoggingPrintStream.registerOnStdout (null, "STDOUT"); * CommonsLoggingPrintStream.registerOnStderr (null, "STDERR"); * //...

    *} * * * Note for de forskrudde tilfeller: Hvis du gjør flere samtaler til metoder som ikke utløser * en flush, som forklart i Printwriter (for eksempel legge til (char)) den kallende metoden * vil bli bestemt bare av den endelige samtalen som utløser en flush eller samtaler flush () direkte. også oppmerksom på at * i dette tilfellet må du synkronisere tilgangen til disse metodene som de ikke vil bli tråden trygg.

    * Det er generelt anbefalt å bare kalle metoder som genererer en automatisk flush som beskrevet * i Printwriter javadocs * /public class CommonsLoggingPrintStream strekker Print {LoggingOutputStream outputStream; privat ReentrantLock lock = new ReentrantLock (); /** * Du kan bruke en ny omgang å logge alle Print metoder til Commons Logging.

    * Meldinger vil bli skrevet til CommonsLogging når flush () kalles hjelp * de samme reglene som Print bruker med autoFlush = sant * *param prependName Et navn prepended til klassen (null for ingen) navn som i: registerOnStdout ("STDOUT" , null) resulterer i en loggmelding som: INFO STDOUT.org.mydomain.MyClass - Logg melding *param postpendName Et navn postpended til klassen (null for ingen) navn som i: registerOnStdout (null, "stdout") resultater i en loggmelding som: INFO org.mydomain.MyClass.

    STDOUT -Logg melding * /public CommonsLoggingPrintStream (String prependName, String postpendName) {dette (ny LoggingOutputStream (prependName, postpendName, CommonsLoggingPrintStream.class.getCanonicalName ())); } Private CommonsLoggingPrintStream (LoggingOutputStream los) {super (los, true); this.outputStream = los; } /** * Convenience metode - Oppretter en ny forekomst av * CommonsLoggingPrintStream og registrerer den på STDOUT * *param prependName Et navn prepended til klassen (null for ingen) navn som i: registerOnStdout ("stdout", null) resulterer i en loggmelding som: INFO STDOUT.org.

    mydomain.MyClass - Logg melding *param postpendName Et navn postpended til klassen (null for ingen) navn som i: registerOnStdout (null, "STDOUT") resulterer i en loggmelding slik som: INFO org.mydomain.MyClass.STDOUT -Logg melding *return en referanse til CommonsLoggingPrintStream objekt opprettet, kan bli ignorert i de fleste situasjoner * /public static CommonsLoggingPrintStream registerOnStdout (String prependName, String postpendName) {CommonsLoggingPrintStream ref = new CommonsLoggingPrintStream ( prependName, postpendName); System.

    setOut (ref); returnere ref; } /** * Convenience metode - Oppretter en ny forekomst av * CommonsLoggingPrintStream og registrerer den på STDERR * *param prependName Et navn prepended til klassen (null for ingen) navn som i: registerOnStdout ("STDERR", null) resultater i en loggmelding som: INFO STDERR.org.mydomain.MyClass - Logg melding *param postpendName Et navn postpended til klassen (null for ingen) navn som i: registerOnStdout (null, "STDERR") resulterer i en loggmelding slik som: INFO org.mydomain.MyClass.

    STDERR -Logg melding *return en referanse til CommonsLoggingPrintStream objekt opprettet, kan bli ignorert i de fleste situasjoner * /public static CommonsLoggingPrintStream registerOnStderr (String prependName, String postpendName) {CommonsLoggingPrintStream ref = new CommonsLoggingPrintStream ( prependName, postpendName); System.setErr (ref); returnere ref; } /* ** Denne klassen er nødvendig for å gjøre bruk av PrintWriters garantere * at spyle vil bli kalt på riktig tidspunkt. Vi legger ut data til * Commons Loggging bare etter flush () kalles på innpakket utgang * stream av Printwriter.

    * * /Private static class LoggingOutputStream strekker ByteArrayOutputStream {private String currentCallerName; private String prependName = null; private String postpendName = null; private String outerClassName = null; //Dette er dynamisk generert, slik at endringer i pakken eller klassenavnet ikke påvirker funksjonaliteten offentlig 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 () kaster IOException {super.flush (); //Logg følge bytes etter flush () kalles. Vi kan stole på dette fordi //vi skapte Print med autoFlush aktivert alternativet. //Hvis en byte array er skrevet det kan inneholde flere linjer String [] logMessages = this.toString () split ("\\ n").; for (String melding: logMessages) {LogFactory.getLog (currentCallerName) .info (message.trim ()); }} Void setNameOfCaller () {boolean reachedCallToOutterClass = false; StackTraceElement [] stack = Thread.

    currentThread () getStackTrace (.); //Loop gjennom stabelen sporstoffer før vi finner "java.io.PrintStream" //og returnere den første fullstendige-class-navnet etter samtalene til Print for (StackTraceElement e: stack) {if (e.getClassName () .equals (outerClassName)) {reachedCallToOutterClass = true; fortsette; } else if (reachedCallToOutterClass) {this.currentCallerName = prependName + e.getClassName () + postpendName; komme tilbake; }} This.currentCallerName = "unknown.classname"; //Unreachable kode (eller så teorien)}} /** * Passes samtalen på å outputStream.

    setNameOfCaller () bare * hvis den synkroniserte låsen på denne eies gang. Hvis det er * eid mer enn en gang, så dette er en tilbakeringing innenfra * Printwriter, en situasjon som vil gjøre det vanskelig /umulig * å bestemme kall metoden, og er ikke nødvendig siden * den første samtalen til setNameOfCaller () er alt som var * nødvendig for å fastslå kall metoden. * /Private void setNameOfCaller (ReentrantLock lås) {if (lock.getHoldCount ()>

    Page   <<       [1] [2] [3] [4] [5] [6] >>
  • Copyright © 2008 - 2016 Lese Utdanning Artikler,https://utdanning.nmjjxx.com All rights reserved.