diff --git a/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java index aa6596a204..de9d427eea 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java @@ -24,12 +24,19 @@ public class LogsHelper extends HelperBase { return Server.getVersion(); } + /** + * Does not call logManager.flush(); call getCriticalLogs() first to flush + */ public String getLogs() { String str = formatMessages(_context.logManager().getBuffer().getMostRecentMessages()); return _("File location") + ": " + _context.logManager().currentFile() + "

" + str; } + /** + * Side effect - calls logManager.flush() + */ public String getCriticalLogs() { + _context.logManager().flush(); return formatMessages(_context.logManager().getBuffer().getMostRecentCriticalMessages()); } @@ -91,6 +98,7 @@ public class LogsHelper extends HelperBase { for (int i = msgs.size() - 1; i >= 0; i--) { String msg = msgs.get(i); msg = msg.replace("&", "&").replace("<", "<").replace(">", ">"); + msg = msg.replace("&darr;", "↓"); // hack - undo the damage (LogWriter) // remove last \n that LogRecordFormatter added if (msg.endsWith(NL)) msg = msg.substring(0, msg.length() - NL.length()); diff --git a/core/java/src/net/i2p/util/LogManager.java b/core/java/src/net/i2p/util/LogManager.java index b166aa9eae..f2f3e6dc24 100644 --- a/core/java/src/net/i2p/util/LogManager.java +++ b/core/java/src/net/i2p/util/LogManager.java @@ -693,18 +693,30 @@ public class LogManager { } *****/ + /** + * Flush any pending records to disk. + * Blocking up to 250 ms. + * @since 0.9.3 + */ + public void flush() { + if (_writer != null) { + int i = 50; + while ((!_records.isEmpty()) && i-- > 0) { + synchronized (_writer) { + _writer.notifyAll(); + } + try { + Thread.sleep(5); + } catch (InterruptedException ie) {} + } + } + } + public void shutdown() { if (_writer != null) { //_log.log(Log.WARN, "Shutting down logger"); // try to prevent out-of-order logging at shutdown - synchronized (_writer) { - _writer.notifyAll(); - } - if (!_records.isEmpty()) { - try { - Thread.sleep(250); - } catch (InterruptedException ie) {} - } + flush(); // this could generate out-of-order messages _writer.flushRecords(false); _writer.stopWriting(); diff --git a/core/java/src/net/i2p/util/LogWriter.java b/core/java/src/net/i2p/util/LogWriter.java index a8e8329d84..c3cc0170e9 100644 --- a/core/java/src/net/i2p/util/LogWriter.java +++ b/core/java/src/net/i2p/util/LogWriter.java @@ -81,15 +81,18 @@ class LogWriter implements Runnable { dupCount++; } else { if (dupCount > 0) { - writeRecord(dupMessage(dupCount, last)); + writeRecord(dupMessage(dupCount, last, false)); + _manager.getBuffer().add(dupMessage(dupCount, last, true)); dupCount = 0; } writeRecord(rec); } last = rec; } - if (dupCount > 0) - writeRecord(dupMessage(dupCount, last)); + if (dupCount > 0) { + writeRecord(dupMessage(dupCount, last, false)); + _manager.getBuffer().add(dupMessage(dupCount, last, true)); + } try { if (_currentOut != null) _currentOut.flush(); @@ -113,12 +116,13 @@ class LogWriter implements Runnable { } /** - * Write a msg with the date stamp of the last duplicate + * Return a msg with the date stamp of the last duplicate * @since 0.9.3 */ - private String dupMessage(int dupCount, LogRecord lastRecord) { - return LogRecordFormatter.getWhen(_manager, lastRecord) + " ^^^ " + - _(dupCount, "1 similar message omitted", "{0} similar messages omitted") + " ^^^\n"; + private String dupMessage(int dupCount, LogRecord lastRecord, boolean reverse) { + String arrows = reverse ? "↓↓↓" : "^^^"; + return LogRecordFormatter.getWhen(_manager, lastRecord) + ' ' + arrows + ' ' + + _(dupCount, "1 similar message omitted", "{0} similar messages omitted") + ' ' + arrows + '\n'; } private static final String BUNDLE_NAME = "net.i2p.router.web.messages";