diff --git a/core/java/src/net/i2p/util/LogManager.java b/core/java/src/net/i2p/util/LogManager.java index 871037b65d5b5f72ce7f95c818b1e54f6509811d..85d948c5375f3d2b5a169a217689cd7ebda0479c 100644 --- a/core/java/src/net/i2p/util/LogManager.java +++ b/core/java/src/net/i2p/util/LogManager.java @@ -61,6 +61,8 @@ public class LogManager { private static final String PROP_DROP = "logger.dropOnOverflow"; /** @since 0.9.3 */ private static final String PROP_DUP = "logger.dropDuplicates"; + /** @since 0.9.18 */ + private static final String PROP_FLUSH = "logger.flushInterval"; public final static String PROP_RECORD_PREFIX = "logger.record."; public final static String DEFAULT_FORMAT = DATE + " " + PRIORITY + " [" + THREAD + "] " + CLASS + ": " + MESSAGE; @@ -125,6 +127,8 @@ public class LogManager { private boolean _dropOnOverflow; private boolean _dropDuplicates; private final AtomicLong _droppedRecords = new AtomicLong(); + // in seconds + private int _flushInterval = (int) (LogWriter.FLUSH_INTERVAL / 1000); private boolean _alreadyNoticedMissingConfig; @@ -160,6 +164,7 @@ public class LogManager { if (_writer != null) return; _writer = new LogWriter(this); + _writer.setFlushInterval(_flushInterval * 1000); // if you enable logging in I2PThread again, you MUST change this back to Thread Thread t = new I2PThread(_writer, "LogWriter"); t.setDaemon(true); @@ -269,6 +274,10 @@ public class LogManager { try { _records.put(record); } catch (InterruptedException ie) {} + } else if (_flushInterval <= 0) { + synchronized (_writer) { + _writer.notifyAll(); + } } } @@ -384,6 +393,17 @@ public class LogManager { _logBufferSize = Integer.parseInt(str); } catch (NumberFormatException nfe) {} + try { + String str = config.getProperty(PROP_FLUSH); + if (str != null) { + _flushInterval = Integer.parseInt(str); + synchronized(this) { + if (_writer != null) + _writer.setFlushInterval(_flushInterval * 1000); + } + } + } catch (NumberFormatException nfe) {} + _dropOnOverflow = Boolean.parseBoolean(config.getProperty(PROP_DROP)); String str = config.getProperty(PROP_DUP); _dropDuplicates = str == null || Boolean.parseBoolean(str); @@ -647,6 +667,7 @@ public class LogManager { rv.setProperty(PROP_DEFAULTLEVEL, Log.toLevelString(_defaultLimit)); rv.setProperty(PROP_DISPLAYONSCREENLEVEL, Log.toLevelString(_onScreenLimit)); rv.setProperty(PROP_CONSOLEBUFFERSIZE, Integer.toString(_consoleBufferSize)); + rv.setProperty(PROP_FLUSH, Integer.toString(_flushInterval)); for (LogLimit lim : _limits) { rv.setProperty(PROP_RECORD_PREFIX + lim.getRootName(), Log.toLevelString(lim.getLimit())); diff --git a/core/java/src/net/i2p/util/LogWriter.java b/core/java/src/net/i2p/util/LogWriter.java index 8f47b0d0e8ff6fab803433c6fb2059d329459248..1d24e34ef45138de296eb4be2df26400698c9688 100644 --- a/core/java/src/net/i2p/util/LogWriter.java +++ b/core/java/src/net/i2p/util/LogWriter.java @@ -25,7 +25,9 @@ import java.util.Queue; class LogWriter implements Runnable { /** every 10 seconds? why? Just have the gui force a reread after a change?? */ private final static long CONFIG_READ_INTERVAL = 50 * 1000; - private final static long FLUSH_INTERVAL = 29 * 1000; + final static long FLUSH_INTERVAL = 29 * 1000; + private final static long MIN_FLUSH_INTERVAL = 2*1000; + private final static long MAX_FLUSH_INTERVAL = 5*60*1000; private long _lastReadConfig; private long _numBytesInCurrentFile; // volatile as it changes on log file rotation @@ -38,6 +40,8 @@ class LogWriter implements Runnable { private static final int MAX_DISKFULL_MESSAGES = 8; private int _diskFullMessageCount; private LogRecord _last; + // ms + private volatile long _flushInterval = FLUSH_INTERVAL; public LogWriter(LogManager manager) { _manager = manager; @@ -47,6 +51,14 @@ class LogWriter implements Runnable { public void stopWriting() { _write = false; } + + /** + * @param ms + * @since 0.9.18 + */ + public void setFlushInterval(long interval) { + _flushInterval = Math.min(MAX_FLUSH_INTERVAL, Math.max(MIN_FLUSH_INTERVAL, interval)); + } public void run() { _write = true; @@ -109,7 +121,7 @@ class LogWriter implements Runnable { if (shouldWait) { try { synchronized (this) { - this.wait(FLUSH_INTERVAL); + this.wait(_flushInterval); } } catch (InterruptedException ie) { // nop }