Hello all:
I implemented the LoggingOutputStream class from Jim Moore. It works fine
except that the logging includes a lot of invisible characters. One error
(see attached log file) and a few info logs create a 120 KB file (I deleted
most of the rows, because I got the mail bounced back). Is there a way to
get rid of these characters?
This is my implementation code:
//This is a test to redirect System.err to log4j:
// 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));
Is there anything I have to watch out for?
TIA
Gunter
Following the code for the class:
List: log4j-user
Subject: RE: Capturing System.err
From: Jim Moore <[EMAIL PROTECTED]>
Date: 2001-01-31 21:29:38
[Download message RAW]
I got it working, with a twist to your suggestion. For anybody that wants
to do it also, here's the code:
import java.io.*;
import org.apache.log4j.*;
/**
* An OutputStream that flushes out to a Category.<p>
*
* Note that no data is written out to the Category until the stream is
* flushed or closed.<p>
*
* Example:<pre>
* // 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));
* </pre>
*
* @see Category
* @author <a href="mailto:[EMAIL PROTECTED]">Jim Moore</a>
*/
public class LoggingOutputStream extends OutputStream {
/**
* Used to maintain the contract of {@link #close()}.
*/
protected boolean hasBeenClosed = false;
/**
* The internal buffer where data is stored.
*/
protected byte[] buf;
/**
* The number of valid bytes in the buffer. This value is always
* in the range <tt>0</tt> through <tt>buf.length</tt>; elements
* <tt>buf[0]</tt> through <tt>buf[count-1]</tt> contain valid
* byte data.
*/
protected int count;
/**
* Remembers the size of the buffer for speed.
*/
private int bufLength;
/**
* The default number of bytes in the buffer. =2048
*/
public static final int DEFAULT_BUFFER_LENGTH = 2048;
/**
* The category to write to.
*/
protected Category category;
/**
* The priority to use when writing to the Category.
*/
protected Priority priority;
private LoggingOutputStream() {
// illegal
}
/**
* Creates the LoggingOutputStream to flush to the given Category.
*
* @param cat the Category to write to
*
* @param priority the Priority to use when writing to the Category
*
* @exception IllegalArgumentException
* if cat == null or priority == null
*/
public LoggingOutputStream(Category cat, Priority priority)
throws IllegalArgumentException {
if (cat == null) {
throw new IllegalArgumentException("cat == null");
}
if (priority == null) {
throw new IllegalArgumentException("priority == null");
}
this.priority = priority;
category = cat;
bufLength = DEFAULT_BUFFER_LENGTH;
buf = new byte[DEFAULT_BUFFER_LENGTH];
count = 0;
}
/**
* Closes this output stream and releases any system resources
* associated with this stream. The general contract of
<code>close</code>
* is that it closes the output stream. A closed stream cannot perform
* output operations and cannot be reopened.
*/
public void close() {
flush();
hasBeenClosed = true;
}
/**
* Writes the specified byte to this output stream. The general
* contract for <code>write</code> is that one byte is written
* to the output stream. The byte to be written is the eight
* low-order bits of the argument <code>b</code>. The 24
* high-order bits of <code>b</code> are ignored.
*
* @param b the <code>byte</code> to write
*
* @exception IOException
* if an I/O error occurs. In particular,
* an <code>IOException</code> may be thrown if the
* output stream has been closed.
*/
public void write(final int b) throws IOException {
if (hasBeenClosed) {
throw new IOException("The stream has been closed.");
}
// would this be writing past the buffer?
if (count == bufLength) {
// grow the buffer
final int newBufLength = bufLength+DEFAULT_BUFFER_LENGTH;
final byte[] newBuf = new byte[newBufLength];
System.arraycopy(buf, 0, newBuf, 0, bufLength);
buf = newBuf;
bufLength = newBufLength;
}
buf[count] = (byte)b;
count++;
}
/**
* Flushes this output stream and forces any buffered output bytes
* to be written out. The general contract of <code>flush</code> is
* that calling it is an indication that, if any bytes previously
* written have been buffered by the implementation of the output
* stream, such bytes should immediately be written to their
* intended destination.
*/
public void flush() {
if (count == 0) {
return;
}
// don't print out blank lines; flushing from PrintStream puts out these
if (count == 1 && ((char)buf[0]) == '\n') {
reset();
return;
}
final byte[] theBytes = new byte[buf.length];
System.arraycopy(buf, 0, theBytes, 0, count);
category.log(priority, new String(theBytes));
reset();
}
private void reset() {
// not resetting the buffer -- assuming that if it grew then it
// will likely grow similarly again
count = 0;
}
}
Works perfectly.
-Jim Moore
-----Original Message-----
From: Ceki Gülcü [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, January 30, 2001 12:28 PM
To: LOG4J Users Mailing List
Subject: Re: Capturing System.err
Jim,
How about creating a PrintStream, say X, that captures System.err. You can
do this by invoking System.setErr(x) where x is an instance of X.
The print(String s) and println(String s) methods of X would then redirect
to log4j by calling root.info(s) where root is the root category. I have not
tried this but the idea has been suggested by a number of log4j users. Do
you think that would work? Ceki
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
Test-20010906-deleted.log
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]