| |
| Copied from |
| http://www.mail-archive.com/log4j-user@jakarta.apache.org/msg00445.html |
| |
| -------------------------------------------------------------------------------- |
| RE: diverting System.stderr/stdout into log4j |
| -------------------------------------------------------------------------------- |
| |
| From: Michael Smith |
| Subject: RE: diverting System.stderr/stdout into log4j |
| Date: Tue, 13 Mar 2001 06:46:04 -0800 |
| |
| -------------------------------------------------------------------------------- |
| |
| There is another way! |
| |
| In LogLog, completely ignore System.err. Instead, use the following to get |
| the standard error stream: |
| |
| PrintStream err = |
| new PrintStream(new FileOutputStream(FileDescriptor.err)); |
| |
| When you use System.setErr, it changes System.err, but not |
| FileDescriptor.err, which maintains a descriptor for the original error |
| stream. |
| |
| michael |
| |
| For a sample program to test this, see below: |
| |
| import java.io.*; |
| |
| public class Stderr { |
| |
| public static void main(String[] args) { |
| |
| // create a print stream to represent a redirect |
| PrintStream nonStandardErr = |
| new PrintStream(new ByteArrayOutputStream()); |
| |
| // Redirect standard out and standard err |
| System.setOut(nonStandardErr); |
| System.setErr(nonStandardErr); |
| |
| // attempt to print something |
| System.err.println("You should *not* see this on the console!"); |
| |
| // the stuff that would appear in LogLog |
| PrintStream logLogOut = |
| new PrintStream(new FileOutputStream(FileDescriptor.err)); |
| |
| // attempt to print something |
| logLogOut.println("You *should* see this on the console!"); |
| } |
| } |
| |
| |
| |
| > -----Original Message----- |
| > From: Ceki Gülcü [mailto:cgu@qos.ch] |
| > Sent: Monday, March 12, 2001 7:18 PM |
| > To: LOG4J Users Mailing List |
| > Subject: RE: diverting System.stderr/stdout into log4j |
| > |
| > |
| > |
| > Hate to follow up on myself, but the System.setErr method |
| > reassigns the System.err variable. This can be deduced without |
| > experimentation because the user calls the System.err variable |
| > directly to print to the console, whatever it might be. Thus, the |
| > reference itself must change to allow the System.err variable to |
| > point to the new target stream. |
| > |
| > The funny part is that the err variable is declared 'public |
| > final' in the JDK source code. The setErr method makes a call to |
| > setErr0 which is declared as being 'native'. It looks like the |
| > native part is circumventing the JDK restrictions. I find this |
| > quite entertaining. Ceki |
| > |
| > At 00:58 13.03.2001 +0100, Ceki Gülcü wrote: |
| > |
| > >Running the risk of disappointing you here, although not full of |
| > bugs, log4j is not bug-free as bugs creep out regularly. They |
| > just get corrected quickly before many people are affected by them. |
| > > |
| > >The PrintStream se = System.err; LogLog.setPrintStream(see); |
| > combination is simple and rather bright. I initially overlooked |
| > the PrintStream se = System.err; part, making me think that a |
| > lot of code needed to be modified to cater for the redirected |
| > console case. The remedy looked worse than the illness. My fears |
| > are largely unfounded and the solution should work quite well if |
| > one is careful. |
| > > |
| > >Regards, Ceki |
| > > |
| > >ps: I wonder if System.err always refers to the real STDERR or |
| > if really gets reassigned with the setErr call. It's easy to find out... |
| > > |
| > >At 23:20 12.03.2001 +0000, Joseph Panico wrote: |
| > >>Of course log4j is completely bug free, but that doesn't |
| > preclude user error. For instance, I neglected to add appenders |
| > in my config file (actually I intentionally left them out, |
| > thinking that would simply turn off logging) and then log4j went |
| > into an infinite loop. The setPrintStream makes sense to me. |
| > >> |
| > >>joe |
| > >> |
| > >> |
| > >>>From: Jim Moore <jim.moore@veritas.com> |
| > >>>Reply-To: "LOG4J Users Mailing List" <log4j-user@jakarta.apache.org> |
| > >>>To: 'LOG4J Users Mailing List' <log4j-user@jakarta.apache.org> |
| > >>>Subject: RE: diverting System.stderr/stdout into log4j |
| > >>>Date: Mon, 12 Mar 2001 18:10:37 -0500 |
| > >>> |
| > >>>It doesn't. I haven't worried about it, since log4j doesn't |
| > contain any |
| > >>>bugs and therefore it would never happen... :) |
| > >>> |
| > >>>Probably the best way to handle it is to add a |
| > >>>LogLog.setPrintStream(PrintStream) method, so you can do |
| > something like: |
| > >>> |
| > >>>// remember STDERR |
| > >>>PrintStream se = System.err; |
| > >>> |
| > >>>// make sure everything sent to System.err is logged |
| > >>>System.setErr(new PrintStream(new |
| > LoggingOutputStream(Category.getRoot(), |
| > >>> Priority.WARN), true)); |
| > >>> |
| > >>>// make sure everything sent to System.out is also logged |
| > >>>System.setOut(new PrintStream(new |
| > LoggingOutputStream(Category.getRoot(), |
| > >>> Priority.INFO), true)); |
| > >>> |
| > >>>// prevent infinate recursion in LogLog |
| > >>>LogLog.setPrintStream(se); |
| > >>> |
| > >>> |
| > >>>I can't think of any other way to do it in the current version besides |
| > >>>getting extremely kludgey by checking the stack to see if it's |
| > being called |
| > >>>from LogLog and logging out the the "real" STDERR then in the |
| > >>>LoggingOutputStream. It can be done on the theory that LogLog |
| > wouldn't be |
| > >>>called very often, but still... |
| > >>> |
| > >>>-Jim Moore |
| > >>> |
| > >>> |
| > >>>-----Original Message----- |
| > >>>From: Ceki Gülcü [mailto:cgu@qos.ch] |
| > >>>Sent: Monday, March 12, 2001 5:15 PM |
| > >>>To: LOG4J Users Mailing List |
| > >>>Subject: RE: diverting System.stderr/stdout into log4j |
| > >>> |
| > >>> |
| > >>>Jim, Joseph, |
| > >>> |
| > >>>Here is a link containing Jim's code: |
| > >>> |
| > >>>http://marc.theaimsgroup.com/?l=log4j-user&m=98097669218571&w=2 |
| > >>> |
| > >>>How does this code handle the infinite recursion problem mentioned by |
| > >>>Joseph? Ceki |
| > >>> |
| > >>>At 17:03 12.03.2001 -0500, Jim Moore wrote: |
| > >>>>Go to the mailing list archives (theAimsGroup.com is the |
| > best) and search |
| > >>>>for the thread with the subject of "Capturing System.err" |
| > >>>> |
| > >>>>-Jim Moore |
| > >>>>"I think so, Brain; but if we gave peas a chance, won't the |
| > lima beans get |
| > >>>>jealous?" - Pinky |
| > >>>> |
| > >>>> |
| > >>>>-----Original Message----- |
| > >>>>From: Joseph Panico [mailto:joe_panico@hotmail.com] |
| > >>>>Sent: Monday, March 12, 2001 4:43 PM |
| > >>>>To: log4j-user@jakarta.apache.org |
| > >>>>Subject: diverting System.stderr/stdout into log4j |
| > >>>> |
| > >>>> |
| > >>>>Folks, |
| > >>>> |
| > >>>>We use a number of third-party packages that do |
| > stderr.print... at various |
| > >>>>random places in their code. I'm finding it quite useful to |
| > divert these |
| > >>>>messages into our log4j heirarchy. I do this by replacing |
| > stderr/stdout |
| > >>>with |
| > >>>> |
| > >>>>my own PrintStreams that log the lines to a special log4j |
| > Category-- as |
| > >>>>suggested on this list a while back. The only |
| > fly-in-the-ointment with this |
| > >>> |
| > >>>>scheme is LogLog. If there is a problem with log4j such that |
| > it cannot log |
| > >>>>for some reason, then log4j internals use LogLog to attempt |
| > to print an |
| > >>>>error message. This obviously leads to an infinite recursion. |
| > Has anyone |
| > >>>>else been bothered by this? Would it make sense to add |
| > interface to LogLog |
| > >>>>which would set the PrintStream it uses to log its error messages to? |
| > >>>> |
| > >>>>thanks for any ideas |
| > >>>> |
| > >>>>joe |
| |
| |