expose more data and let the settings be overridden during runtime (and saved to disk)

This commit is contained in:
jrandom
2004-08-01 05:27:59 +00:00
committed by zzz
parent cf7be2d601
commit 96f9618081
2 changed files with 176 additions and 9 deletions

View File

@ -29,6 +29,10 @@ class LogLimit {
public int getLimit() {
return _limit;
}
public void setLimit(int limit) {
_limit = limit;
}
public boolean matches(Log log) {
String name = log.getName();

View File

@ -11,6 +11,7 @@ package net.i2p.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@ -19,6 +20,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import net.i2p.I2PAppContext;
@ -62,26 +64,45 @@ public class LogManager {
private I2PAppContext _context;
private Log _log;
/** when was the config file last read (or -1 if never) */
private long _configLastRead;
/** filename of the config file */
private String _location;
/** Ordered list of LogRecord elements that have not been written out yet */
private List _records;
/** List of explicit overrides of log levels (LogLimit objects) */
private List _limits;
/** String (scope) to Log object */
private Map _logs;
/** who clears and writes our records */
private LogWriter _writer;
/**
* default log level for logs that aren't explicitly controlled
* through a LogLimit in _limits
*/
private int _defaultLimit;
/** Log record format string */
private char[] _format;
/** Date format instance */
private SimpleDateFormat _dateFormat;
/** Date format string (for the SimpleDateFormat instance) */
private String _dateFormatPattern;
/** log filename pattern */
private String _baseLogfilename;
/** max # bytes in the logfile before rotation */
private int _fileSize;
/** max # rotated logs */
private int _rotationLimit;
/** minimum log level to be displayed on stdout */
private int _onScreenLimit;
/** whether or not we even want to display anything on stdout */
private boolean _displayOnScreen;
/** how many records we want to buffer in the "recent logs" list */
private int _consoleBufferSize;
/** the actual "recent logs" list */
private LogConsoleBuffer _consoleBuffer;
public LogManager(I2PAppContext context) {
@ -264,7 +285,7 @@ public class LogManager {
else
_baseLogfilename = config.getProperty(PROP_FILENAME, DEFAULT_FILENAME);
_fileSize = getFilesize(config.getProperty(PROP_FILESIZE, DEFAULT_FILESIZE));
_fileSize = getFileSize(config.getProperty(PROP_FILESIZE, DEFAULT_FILESIZE));
_rotationLimit = -1;
try {
String str = config.getProperty(PROP_ROTATIONLIMIT);
@ -297,15 +318,28 @@ public class LogManager {
}
private void parseLimits(Properties config) {
parseLimits(config, PROP_RECORD_PREFIX);
}
private void parseLimits(Properties config, String recordPrefix) {
synchronized (_limits) {
_limits.clear();
}
for (Iterator iter = config.keySet().iterator(); iter.hasNext();) {
String key = (String) iter.next();
String val = config.getProperty(key);
if (key.startsWith(PROP_RECORD_PREFIX)) {
String name = key.substring(PROP_RECORD_PREFIX.length());
LogLimit lim = new LogLimit(name, Log.getLevel(val));
if (config != null) {
for (Iterator iter = config.keySet().iterator(); iter.hasNext();) {
String key = (String) iter.next();
String val = config.getProperty(key);
// if we're filtering the records (e.g. logger.record.*) then
// filter accordingly (stripping off that prefix for matches)
if (recordPrefix != null) {
if (key.startsWith(recordPrefix)) {
key = key.substring(recordPrefix.length());
} else {
continue;
}
}
LogLimit lim = new LogLimit(key, Log.getLevel(val));
//_log.debug("Limit found for " + name + " as " + val);
synchronized (_limits) {
if (!_limits.contains(lim))
@ -315,8 +349,70 @@ public class LogManager {
}
updateLimits();
}
/**
* Update the existing limit overrides
*
* @param limits mapping of prefix to log level string (not the log #)
*/
public void setLimits(Properties limits) {
parseLimits(limits, null);
}
/**
* Update the date format
*
* @return true if the format was updated, false if it was invalid
*/
public boolean setDateFormat(String format) {
if (format == null) return false;
try {
SimpleDateFormat fmt = new SimpleDateFormat(format);
_dateFormatPattern = format;
_dateFormat = fmt;
return true;
} catch (IllegalArgumentException iae) {
getLog(LogManager.class).error("Date format is invalid [" + format + "]", iae);
return false;
}
}
/**
* Update the log file size limit
*/
public void setFileSize(int numBytes) {
if (numBytes > 0)
_fileSize = numBytes;
}
public String getDefaultLimit() { return Log.toLevelString(_defaultLimit); }
public void setDefaultLimit(String lim) {
_defaultLimit = Log.getLevel(lim);
updateLimits();
}
/**
* Return a mapping of the explicit overrides - path prefix to (text
* formatted) limit.
*
*/
public Properties getLimits() {
Properties rv = new Properties();
synchronized (_limits) {
for (int i = 0; i < _limits.size(); i++) {
LogLimit lim = (LogLimit)_limits.get(i);
rv.setProperty(lim.getRootName(), Log.toLevelString(lim.getLimit()));
}
}
return rv;
}
private int getFilesize(String size) {
/**
* Determine how many bytes are in the given formatted string (5m, 60g, 100k, etc)
*
*/
public int getFileSize(String size) {
int sz = -1;
try {
String v = size;
@ -398,6 +494,10 @@ public class LogManager {
public String getBaseLogfilename() {
return _baseLogfilename;
}
public void setBaseLogfilename(String filenamePattern) {
_baseLogfilename = filenamePattern;
}
public int getFileSize() {
return _fileSize;
@ -407,6 +507,65 @@ public class LogManager {
return _rotationLimit;
}
public boolean saveConfig() {
String config = createConfig();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(_location);
fos.write(config.getBytes());
return true;
} catch (IOException ioe) {
getLog(LogManager.class).error("Error saving the config", ioe);
return false;
} finally {
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
}
}
private String createConfig() {
StringBuffer buf = new StringBuffer(8*1024);
buf.append(PROP_FORMAT).append('=').append(new String(_format)).append('\n');
buf.append(PROP_DATEFORMAT).append('=').append(_dateFormatPattern).append('\n');
buf.append(PROP_DISPLAYONSCREEN).append('=').append((_displayOnScreen ? "TRUE" : "FALSE")).append('\n');
String filenameOverride = _context.getProperty(FILENAME_OVERRIDE_PROP);
if (filenameOverride == null)
buf.append(PROP_FILENAME).append('=').append(_baseLogfilename).append('\n');
else // this isn't technically correct - this could mess with some funky scenarios
buf.append(PROP_FILENAME).append('=').append(DEFAULT_FILENAME).append('\n');
if (_fileSize >= 1024*1024)
buf.append(PROP_FILESIZE).append('=').append( (_fileSize / (1024*1024))).append("m\n");
else if (_fileSize >= 1024)
buf.append(PROP_FILESIZE).append('=').append( (_fileSize / (1024))).append("k\n");
else if (_fileSize > 0)
buf.append(PROP_FILESIZE).append('=').append(_fileSize).append('\n');
// if <= 0, dont specify
buf.append(PROP_ROTATIONLIMIT).append('=').append(_rotationLimit).append('\n');
buf.append(PROP_DEFALTLEVEL).append('=').append(Log.toLevelString(_defaultLimit)).append('\n');
buf.append(PROP_DISPLAYONSCREENLEVEL).append('=').append(Log.toLevelString(_onScreenLimit)).append('\n');
buf.append(PROP_CONSOLEBUFFERSIZE).append('=').append(_consoleBufferSize).append('\n');
buf.append("# log limit overrides:\n");
TreeMap limits = new TreeMap();
synchronized (_limits) {
for (int i = 0; i < _limits.size(); i++) {
LogLimit lim = (LogLimit)_limits.get(i);
limits.put(lim.getRootName(), Log.toLevelString(lim.getLimit()));
}
}
for (Iterator iter = limits.keySet().iterator(); iter.hasNext(); ) {
String path = (String)iter.next();
String lim = (String)limits.get(path);
buf.append(PROP_RECORD_PREFIX).append(path);
buf.append('=').append(lim).append('\n');
}
return buf.toString();
}
//List _getRecords() { return _records; }
List _removeAll() {
List vals = null;
@ -422,6 +581,10 @@ public class LogManager {
public char[] getFormat() {
return _format;
}
public void setFormat(char fmt[]) {
_format = fmt;
}
public SimpleDateFormat getDateFormat() {
return _dateFormat;