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("↓", "↓"); // 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";