Added STDERR log level and appropriate infrastructure to capture

System.err.println().  This is reported in the debug dialog and in bug
reports.
This commit is contained in:
kruland2607 2013-05-10 12:56:42 -05:00
parent bd3c68131a
commit 9bb6a4933b
6 changed files with 53 additions and 106 deletions

View File

@ -47,6 +47,11 @@ public enum LogLevel {
*/
DEBUG,
/**
* Level at which redirected StdErr messages are logged
*/
STDERR,
/**
* Level of verbose debug logging to be used in areas which are called repeatedly,
* such as computational methods used in simulations. This level is separated to

View File

@ -56,13 +56,14 @@ public class LogbackBufferLoggerAdaptor extends AppenderBase<ILoggingEvent> {
private LogLine toLogLine(ILoggingEvent e) {
LogLevel l = toORLevel(e.getLevel());
if (SLF4JLogHelper.USER_MARKER.equals(e.getMarker()))
if (Markers.USER_MARKER.equals(e.getMarker()))
l = LogLevel.USER;
if (Markers.STDERR_MARKER.equals(e.getMarker()))
l = LogLevel.STDERR;
Throwable t = null;
if (e.getThrowableProxy() != null) {
t = ((ThrowableProxy) e.getThrowableProxy()).getThrowable();
}
return new LogLine(l, new TraceException(), e.getMessage(), t);
}
}

View File

@ -5,4 +5,5 @@ import org.slf4j.MarkerFactory;
public class Markers {
public static final Marker USER_MARKER = MarkerFactory.getMarker("User");
public static final Marker STDERR_MARKER = MarkerFactory.getMarker("StdErr");
}

View File

@ -0,0 +1,41 @@
package net.sf.openrocket.logging;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PrintStreamToSLF4J {
public static PrintStream getPrintStream(String category, PrintStream orignal) {
final Logger logger = LoggerFactory.getLogger(category);
return new PrintStream(new OutputStream() {
StringBuilder currentLine = new StringBuilder();
@Override
public synchronized void write(int b) throws IOException {
if (b == '\r' || b == '\n') {
//Line is complete, log it
if (currentLine.toString().trim().length() > 0) {
String s = currentLine.toString();
if (Character.isWhitespace(s.charAt(0))) {
logger.trace(Markers.STDERR_MARKER, currentLine.toString());
} else {
logger.debug(Markers.STDERR_MARKER, currentLine.toString());
}
}
currentLine = new StringBuilder();
} else {
//append to the line being built
currentLine.append((char) b);
}
}
});
}
}

View File

@ -1,38 +0,0 @@
package net.sf.openrocket.logging;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
public class SLF4JLogHelper extends DelegatorLogger {
private static final Logger log = LoggerFactory.getLogger(SLF4JLogHelper.class);
static final Marker USER_MARKER = MarkerFactory.getMarker("User");
@Override
public void log(LogLine line) {
super.log(line);
switch (line.getLevel()) {
case VBOSE:
log.trace(line.getMessage(), line.getCause());
break;
case DEBUG:
log.debug(line.getMessage(), line.getCause());
break;
case INFO:
log.info(line.getMessage(), line.getCause());
break;
case USER:
log.info(USER_MARKER, line.getMessage(), line.getCause());
break;
case WARN:
log.warn(line.getMessage(), line.getCause());
break;
case ERROR:
log.error(line.getMessage(), line.getCause());
break;
}
}
}

View File

@ -11,6 +11,7 @@ import net.sf.openrocket.l10n.ResourceBundleTranslator;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.LogLevel;
import net.sf.openrocket.logging.PrintStreamLogger;
import net.sf.openrocket.logging.PrintStreamToSLF4J;
import net.sf.openrocket.plugin.PluginModule;
import org.slf4j.Logger;
@ -85,79 +86,15 @@ public class GuiceStartup {
/**
* Initializes the loggins system.
* Initializes the logging system.
*/
public static void initializeLogging() {
/*DelegatorLogger delegator = new DelegatorLogger();
// Log buffer
LogLevelBufferLogger buffer = new LogLevelBufferLogger(LOG_BUFFER_LENGTH);
delegator.addLogger(buffer);
// Check whether to log to stdout/stderr
PrintStreamLogger printer = new PrintStreamLogger();
boolean logout = setLogOutput(printer, System.out, System.getProperty(LOG_STDOUT_PROPERTY), null);
boolean logerr = setLogOutput(printer, System.err, System.getProperty(LOG_STDERR_PROPERTY), LogLevel.ERROR);
if (logout || logerr) {
delegator.addLogger(printer);
}
// Set the loggers
Application.setLogger(delegator);
Application.setLogBuffer(buffer);
// Initialize the log for this class
log = Application.getLogger();
log.info("Logging subsystem initialized");
String str = "Console logging output:";
for (LogLevel l : LogLevel.values()) {
PrintStream ps = printer.getOutput(l);
str += " " + l.name() + ":";
if (ps == System.err) {
str += "stderr";
} else if (ps == System.out) {
str += "stdout";
} else {
str += "none";
}
}
str += " (" + LOG_STDOUT_PROPERTY + "=" + System.getProperty(LOG_STDOUT_PROPERTY) +
" " + LOG_STDERR_PROPERTY + "=" + System.getProperty(LOG_STDERR_PROPERTY) + ")";
log.info(str);
//Replace System.err with a PrintStream that logs lines to DEBUG, or VBOSE if they are indented.
//If debug info is not being output to the console then the data is both logged and written to
//stderr.
final boolean writeToStderr = !(printer.getOutput(LogLevel.DEBUG) == System.out || printer.getOutput(LogLevel.DEBUG) == System.err);
final PrintStream stdErr = System.err;
System.setErr(new PrintStream(new OutputStream() {
StringBuilder currentLine = new StringBuilder();
@Override
public synchronized void write(int b) throws IOException {
if (writeToStderr) {
//Write to real stderr
stdErr.write(b);
}
if (b == '\r' || b == '\n') {
//Line is complete, log it
if (currentLine.toString().trim().length() > 0) {
String s = currentLine.toString();
if (Character.isWhitespace(s.charAt(0))) {
log.verbose(currentLine.toString());
} else {
log.debug(currentLine.toString());
}
}
currentLine = new StringBuilder();
} else {
//append to the line being built
currentLine.append((char) b);
}
}
}));
*/
System.setErr(PrintStreamToSLF4J.getPrintStream("STDERR", stdErr));
}
private static boolean setLogOutput(PrintStreamLogger logger, PrintStream stream, String level, LogLevel defaultLevel) {