System.out/err.printlnの出力をslf4jにリダイレクトする必要がありました。System.outとSystem.errをslf4jにリダイレクト
は、私は、これは適切をログ行う方法ではないことを知っているが、私はlog4jのためLoggingOutputStreamを使用して問題を解決し
System.out/err.printlnの出力をslf4jにリダイレクトする必要がありました。System.outとSystem.errをslf4jにリダイレクト
は、私は、これは適切をログ行う方法ではないことを知っているが、私はlog4jのためLoggingOutputStreamを使用して問題を解決し
(OpenEJBの起動時から)次のようになります。
SYSOUTオーバーSLF4Jモジュールは、ユーザがその中のSystem.out.printlnは(完全修飾されたクラスの名前で定義されたSLF4JロガーにSystem.outおよびSystem.errにすべてのコールをリダイレクトすることができまたは類似の)呼が構成可能なレベルで行われた。
あなたはMavenを使用してない、download瓶とあなたのクラスパスに追加がある場合。アプリケーションの起動時に次に
<dependency>
<groupId>uk.org.lidalia</groupId>
<artifactId>sysout-over-slf4j</artifactId>
<version>1.0.2</version>
</dependency>
、call:
また、Mavenの依存関係として追加
SysOutOverSLF4J.sendSystemOutAndErrToSLF4J();
そのことに
System.outにログインする外部ライブラリは、そこにあり、それを少し修正しましたslf4jのビット。
import java.io.IOException;
import java.io.PrintStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SysStreamsLogger {
private static Logger sysOutLogger = LoggerFactory.getLogger("SYSOUT");
private static Logger sysErrLogger = LoggerFactory.getLogger("SYSERR");
public static final PrintStream sysout = System.out;
public static final PrintStream syserr = System.err;
protected static final String LINE_SEPERATOR = System.getProperty("line.separator");
public static void bindSystemStreams() {
// Enable autoflush
System.setOut(new PrintStream(new LoggingOutputStream(sysOutLogger, false), true));
System.setErr(new PrintStream(new LoggingOutputStream(sysErrLogger, true), true));
}
public static void unbindSystemStreams() {
System.setOut(sysout);
System.setErr(syserr);
}
private static class LoggingOutputStream extends java.io.OutputStream {
protected Logger log;
protected boolean isError;
/**
* 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;
private LoggingOutputStream() {
// illegal
}
/**
* Creates the LoggingOutputStream to flush to the given Category.
*
* @param log
* the Logger to write to
*
* @param isError
* the if true write to error, else info
*
* @exception IllegalArgumentException
* if cat == null or priority == null
*/
public LoggingOutputStream(Logger log, boolean isError) throws IllegalArgumentException {
if (log == null) {
throw new IllegalArgumentException("log == null");
}
this.isError = isError;
this.log = log;
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.
*/
@Override
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
*/
@Override
public void write(final int b) throws IOException {
if (hasBeenClosed) {
throw new IOException("The stream has been closed.");
}
// don't log nulls
if (b == 0) {
return;
}
// 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.
*/
@Override
public void flush() {
if (count == 0) {
return;
}
// don't print out blank lines; flushing from PrintStream puts out
// these
if (count == LINE_SEPERATOR.length()) {
if (((char) buf[0]) == LINE_SEPERATOR.charAt(0) && ((count == 1) || // <-
// Unix
// &
// Mac,
// ->
// Windows
((count == 2) && ((char) buf[1]) == LINE_SEPERATOR.charAt(1)))) {
reset();
return;
}
}
final byte[] theBytes = new byte[count];
System.arraycopy(buf, 0, theBytes, 0, count);
if (isError) {
log.error(new String(theBytes));
} else {
log.info(new String(theBytes));
}
reset();
}
private void reset() {
// not resetting the buffer -- assuming that if it grew that it
// will likely grow similarly again
count = 0;
}
}
}
今では、アプリケーションの初めにSysStreamsLogger.bindSystemStreams()
を呼び出すことによってSytem.out/ERRをリダイレクトすることが可能です。あなたはsysout-over-slf4jを使用することができます
ログ出力が
2012-06-27 13:44:12,792 INFO [main:] SYSOUT:181 - Apache OpenEJB 3.1.4 build: 20101112-03:32
2012-06-27 13:44:12,793 INFO [main:] SYSOUT:181 - http://openejb.apache.org/
クイックグーグルでは、私にあなたの答えだけでなく、面白いと思われるこのリンクを与えました: http://projects.lidalia.org.uk/sysout-over-slf4j/index.html – remi