* Logging:
- Use System locale and time zone for default date/time format, so it matches the wrapper log time (we can't set the wrapper log time zone). (existing installs must remove logger.dateFormat line in logger.config to get system default format) - Force RuntimeExceptions to CRIT level - Don't have log() count buffer size
This commit is contained in:
@ -24,11 +24,12 @@
|
|||||||
<b>Processor:</b> <%=net.i2p.util.NativeBigInteger.cpuModel()%> (<%=net.i2p.util.NativeBigInteger.cpuType()%>)<br>
|
<b>Processor:</b> <%=net.i2p.util.NativeBigInteger.cpuModel()%> (<%=net.i2p.util.NativeBigInteger.cpuType()%>)<br>
|
||||||
<b>Jbigi:</b> <%=net.i2p.util.NativeBigInteger.loadStatus()%><br>
|
<b>Jbigi:</b> <%=net.i2p.util.NativeBigInteger.loadStatus()%><br>
|
||||||
<b>Encoding:</b> <%=System.getProperty("file.encoding")%></p>
|
<b>Encoding:</b> <%=System.getProperty("file.encoding")%></p>
|
||||||
|
<p><%=intl._("Note that system information, log timestamps, and log messages may provide clues to your location; please review everything you include in a bug report.")%>:</p>
|
||||||
<jsp:useBean class="net.i2p.router.web.LogsHelper" id="logsHelper" scope="request" />
|
<jsp:useBean class="net.i2p.router.web.LogsHelper" id="logsHelper" scope="request" />
|
||||||
<jsp:setProperty name="logsHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
<jsp:setProperty name="logsHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||||
<h3><%=intl._("Critical Logs")%></h3><a name="criticallogs"> </a>
|
<h3><%=intl._("Critical Logs")%></h3><a name="criticallogs"> </a>
|
||||||
<jsp:getProperty name="logsHelper" property="criticalLogs" />
|
<jsp:getProperty name="logsHelper" property="criticalLogs" />
|
||||||
<h3><%=intl._("Router Logs")%> (<a href="configlogging.jsp"><%=intl._("configure")%></a>)</h3>
|
<h3><%=intl._("Router Logs")%> (<a href="configlogging"><%=intl._("configure")%></a>)</h3>
|
||||||
<jsp:getProperty name="logsHelper" property="logs" />
|
<jsp:getProperty name="logsHelper" property="logs" />
|
||||||
<h3><%=intl._("Service (Wrapper) Logs")%></h3><a name="servicelogs"> </a>
|
<h3><%=intl._("Service (Wrapper) Logs")%></h3><a name="servicelogs"> </a>
|
||||||
<jsp:getProperty name="logsHelper" property="serviceLogs" />
|
<jsp:getProperty name="logsHelper" property="serviceLogs" />
|
||||||
|
@ -107,6 +107,9 @@ public class Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void log(int priority, String msg, Throwable t) {
|
public void log(int priority, String msg, Throwable t) {
|
||||||
|
// Boost the priority of NPE and friends so they get seen and reported
|
||||||
|
if (t != null && t instanceof RuntimeException && !(t instanceof IllegalArgumentException))
|
||||||
|
priority = CRIT;
|
||||||
if (priority >= _minPriority) {
|
if (priority >= _minPriority) {
|
||||||
_manager.addRecord(new LogRecord(_class, _name,
|
_manager.addRecord(new LogRecord(_class, _name,
|
||||||
Thread.currentThread().getName(), priority,
|
Thread.currentThread().getName(), priority,
|
||||||
|
@ -13,6 +13,7 @@ import java.io.File;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.text.DateFormat;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -23,6 +24,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.TimeZone;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
@ -57,7 +59,9 @@ public class LogManager {
|
|||||||
public final static String PROP_RECORD_PREFIX = "logger.record.";
|
public final static String PROP_RECORD_PREFIX = "logger.record.";
|
||||||
|
|
||||||
public final static String DEFAULT_FORMAT = DATE + " " + PRIORITY + " [" + THREAD + "] " + CLASS + ": " + MESSAGE;
|
public final static String DEFAULT_FORMAT = DATE + " " + PRIORITY + " [" + THREAD + "] " + CLASS + ": " + MESSAGE;
|
||||||
public final static String DEFAULT_DATEFORMAT = "HH:mm:ss.SSS";
|
//public final static String DEFAULT_DATEFORMAT = "HH:mm:ss.SSS";
|
||||||
|
/** blank means default short date and medium time for the locale - see DateFormat */
|
||||||
|
public final static String DEFAULT_DATEFORMAT = "";
|
||||||
public final static String DEFAULT_FILENAME = "logs/log-#.txt";
|
public final static String DEFAULT_FILENAME = "logs/log-#.txt";
|
||||||
public final static String DEFAULT_FILESIZE = "10m";
|
public final static String DEFAULT_FILESIZE = "10m";
|
||||||
public final static boolean DEFAULT_DISPLAYONSCREEN = true;
|
public final static boolean DEFAULT_DISPLAYONSCREEN = true;
|
||||||
@ -225,6 +229,7 @@ public class LogManager {
|
|||||||
startLogWriter();
|
startLogWriter();
|
||||||
|
|
||||||
_records.offer(record);
|
_records.offer(record);
|
||||||
|
/**** don't burden the logging thread with counting
|
||||||
int numRecords = _records.size();
|
int numRecords = _records.size();
|
||||||
|
|
||||||
if (numRecords > 100) {
|
if (numRecords > 100) {
|
||||||
@ -234,6 +239,7 @@ public class LogManager {
|
|||||||
_writer.notifyAll();
|
_writer.notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
****/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -292,8 +298,7 @@ public class LogManager {
|
|||||||
_format = fmt.toCharArray();
|
_format = fmt.toCharArray();
|
||||||
|
|
||||||
String df = config.getProperty(PROP_DATEFORMAT, DEFAULT_DATEFORMAT);
|
String df = config.getProperty(PROP_DATEFORMAT, DEFAULT_DATEFORMAT);
|
||||||
_dateFormatPattern = df;
|
setDateFormat(df);
|
||||||
_dateFormat = new SimpleDateFormat(df);
|
|
||||||
|
|
||||||
String disp = config.getProperty(PROP_DISPLAYONSCREEN);
|
String disp = config.getProperty(PROP_DISPLAYONSCREEN);
|
||||||
if (disp == null)
|
if (disp == null)
|
||||||
@ -386,13 +391,24 @@ public class LogManager {
|
|||||||
/**
|
/**
|
||||||
* Update the date format
|
* Update the date format
|
||||||
*
|
*
|
||||||
|
* @param format null or empty string means use default format for the locale
|
||||||
|
* (with a SHORT date and a MEDIUM time - see DateFormat)
|
||||||
* @return true if the format was updated, false if it was invalid
|
* @return true if the format was updated, false if it was invalid
|
||||||
*/
|
*/
|
||||||
public boolean setDateFormat(String format) {
|
public boolean setDateFormat(String format) {
|
||||||
if (format == null) return false;
|
if (format == null)
|
||||||
|
format = "";
|
||||||
|
if (format.equals(_dateFormatPattern) && _dateFormat != null)
|
||||||
|
return true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SimpleDateFormat fmt = new SimpleDateFormat(format);
|
SimpleDateFormat fmt = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);
|
||||||
|
if (!format.equals(""))
|
||||||
|
fmt.applyPattern(format);
|
||||||
|
// the router sets the JVM time zone to UTC but saves the original here so we can get it
|
||||||
|
String systemTimeZone = _context.getProperty("i2p.systemTimeZone");
|
||||||
|
if (systemTimeZone != null)
|
||||||
|
fmt.setTimeZone(TimeZone.getTimeZone(systemTimeZone));
|
||||||
_dateFormatPattern = format;
|
_dateFormatPattern = format;
|
||||||
_dateFormat = fmt;
|
_dateFormat = fmt;
|
||||||
return true;
|
return true;
|
||||||
|
@ -27,7 +27,8 @@ import net.i2p.I2PAppContext;
|
|||||||
*/
|
*/
|
||||||
class LogWriter implements Runnable {
|
class LogWriter implements Runnable {
|
||||||
/** every 10 seconds? why? Just have the gui force a reread after a change?? */
|
/** every 10 seconds? why? Just have the gui force a reread after a change?? */
|
||||||
private final static long CONFIG_READ_ITERVAL = 10 * 1000;
|
private final static long CONFIG_READ_INTERVAL = 50 * 1000;
|
||||||
|
private final static long FLUSH_INTERVAL = 11 * 1000;
|
||||||
private long _lastReadConfig = 0;
|
private long _lastReadConfig = 0;
|
||||||
private long _numBytesInCurrentFile = 0;
|
private long _numBytesInCurrentFile = 0;
|
||||||
private Writer _currentOut;
|
private Writer _currentOut;
|
||||||
@ -71,14 +72,14 @@ class LogWriter implements Runnable {
|
|||||||
try {
|
try {
|
||||||
List<LogRecord> records = _manager._removeAll();
|
List<LogRecord> records = _manager._removeAll();
|
||||||
if (records == null) return;
|
if (records == null) return;
|
||||||
for (LogRecord rec : records) {
|
|
||||||
writeRecord(rec);
|
|
||||||
}
|
|
||||||
if (!records.isEmpty()) {
|
if (!records.isEmpty()) {
|
||||||
|
for (LogRecord rec : records) {
|
||||||
|
writeRecord(rec);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
_currentOut.flush();
|
_currentOut.flush();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
System.err.println("Error flushing the records");
|
System.err.println("Error writing the router log");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
@ -87,7 +88,7 @@ class LogWriter implements Runnable {
|
|||||||
if (shouldWait) {
|
if (shouldWait) {
|
||||||
try {
|
try {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
this.wait(10*1000);
|
this.wait(FLUSH_INTERVAL);
|
||||||
}
|
}
|
||||||
} catch (InterruptedException ie) { // nop
|
} catch (InterruptedException ie) { // nop
|
||||||
}
|
}
|
||||||
@ -101,7 +102,7 @@ class LogWriter implements Runnable {
|
|||||||
|
|
||||||
private void rereadConfig() {
|
private void rereadConfig() {
|
||||||
long now = Clock.getInstance().now();
|
long now = Clock.getInstance().now();
|
||||||
if (now - _lastReadConfig > CONFIG_READ_ITERVAL) {
|
if (now - _lastReadConfig > CONFIG_READ_INTERVAL) {
|
||||||
_manager.rereadConfig();
|
_manager.rereadConfig();
|
||||||
_lastReadConfig = now;
|
_lastReadConfig = now;
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,7 @@ public class Router {
|
|||||||
public final static String PROP_SHUTDOWN_IN_PROGRESS = "__shutdownInProgress";
|
public final static String PROP_SHUTDOWN_IN_PROGRESS = "__shutdownInProgress";
|
||||||
public final static String DNS_CACHE_TIME = "" + (5*60);
|
public final static String DNS_CACHE_TIME = "" + (5*60);
|
||||||
|
|
||||||
|
private static final String originalTimeZoneID;
|
||||||
static {
|
static {
|
||||||
// grumble about sun's java caching DNS entries *forever* by default
|
// grumble about sun's java caching DNS entries *forever* by default
|
||||||
// so lets just keep 'em for a short time
|
// so lets just keep 'em for a short time
|
||||||
@ -106,6 +107,8 @@ public class Router {
|
|||||||
System.setProperty("http.agent", "I2P");
|
System.setProperty("http.agent", "I2P");
|
||||||
// (no need for keepalive)
|
// (no need for keepalive)
|
||||||
System.setProperty("http.keepAlive", "false");
|
System.setProperty("http.keepAlive", "false");
|
||||||
|
// Save it for LogManager
|
||||||
|
originalTimeZoneID = TimeZone.getDefault().getID();
|
||||||
System.setProperty("user.timezone", "GMT");
|
System.setProperty("user.timezone", "GMT");
|
||||||
// just in case, lets make it explicit...
|
// just in case, lets make it explicit...
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
|
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
|
||||||
@ -180,6 +183,8 @@ public class Router {
|
|||||||
|
|
||||||
if (envProps.getProperty("i2p.dir.config") == null)
|
if (envProps.getProperty("i2p.dir.config") == null)
|
||||||
envProps.setProperty("i2p.dir.config", userDir);
|
envProps.setProperty("i2p.dir.config", userDir);
|
||||||
|
// Save this in the context for the logger and apps that need it
|
||||||
|
envProps.setProperty("i2p.systemTimeZone", originalTimeZoneID);
|
||||||
|
|
||||||
// The important thing that happens here is the directory paths are set and created
|
// The important thing that happens here is the directory paths are set and created
|
||||||
// i2p.dir.router defaults to i2p.dir.config
|
// i2p.dir.router defaults to i2p.dir.config
|
||||||
|
Reference in New Issue
Block a user