forked from I2P_Developers/i2p.i2p
* LogManager: Concurrent
This commit is contained in:
@@ -167,7 +167,9 @@ public class Log {
|
|||||||
return _name;
|
return _name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return the LogScope (private class) */
|
||||||
public Object getScope() { return _scope; }
|
public Object getScope() { return _scope; }
|
||||||
|
|
||||||
static String getScope(String name, Class cls) {
|
static String getScope(String name, Class cls) {
|
||||||
if ( (name == null) && (cls == null) ) return "f00";
|
if ( (name == null) && (cls == null) ) return "f00";
|
||||||
if (cls == null) return name;
|
if (cls == null) return name;
|
||||||
|
@@ -39,4 +39,16 @@ class LogLimit {
|
|||||||
if (name == null) return false;
|
if (name == null) return false;
|
||||||
return name.startsWith(_rootName);
|
return name.startsWith(_rootName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return _rootName.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == null || !(o instanceof LogLimit))
|
||||||
|
return false;
|
||||||
|
return _rootName.equals(((LogLimit) o).getRootName());
|
||||||
|
}
|
||||||
}
|
}
|
@@ -17,10 +17,14 @@ import java.text.SimpleDateFormat;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
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.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
|
|
||||||
@@ -70,11 +74,11 @@ public class LogManager {
|
|||||||
/** the config file */
|
/** the config file */
|
||||||
private File _locationFile;
|
private File _locationFile;
|
||||||
/** Ordered list of LogRecord elements that have not been written out yet */
|
/** Ordered list of LogRecord elements that have not been written out yet */
|
||||||
private /* FIXME final FIXME */ List _records;
|
private LinkedBlockingQueue<LogRecord> _records;
|
||||||
/** List of explicit overrides of log levels (LogLimit objects) */
|
/** List of explicit overrides of log levels (LogLimit objects) */
|
||||||
private /* FIXME final FIXME */ List _limits;
|
private Set<LogLimit> _limits;
|
||||||
/** String (scope) to Log object */
|
/** String (scope) or Log.LogScope to Log object */
|
||||||
private /* FIXME final FIXME */ Map _logs;
|
private ConcurrentHashMap<Object, Log> _logs;
|
||||||
/** who clears and writes our records */
|
/** who clears and writes our records */
|
||||||
private LogWriter _writer;
|
private LogWriter _writer;
|
||||||
|
|
||||||
@@ -110,9 +114,9 @@ public class LogManager {
|
|||||||
public LogManager(I2PAppContext context) {
|
public LogManager(I2PAppContext context) {
|
||||||
_displayOnScreen = true;
|
_displayOnScreen = true;
|
||||||
_alreadyNoticedMissingConfig = false;
|
_alreadyNoticedMissingConfig = false;
|
||||||
_records = new ArrayList();
|
_records = new LinkedBlockingQueue();
|
||||||
_limits = new ArrayList(128);
|
_limits = new ConcurrentHashSet();
|
||||||
_logs = new HashMap(128);
|
_logs = new ConcurrentHashMap(128);
|
||||||
_defaultLimit = Log.ERROR;
|
_defaultLimit = Log.ERROR;
|
||||||
_configLastRead = 0;
|
_configLastRead = 0;
|
||||||
_context = context;
|
_context = context;
|
||||||
@@ -139,33 +143,26 @@ public class LogManager {
|
|||||||
public Log getLog(Class cls) { return getLog(cls, null); }
|
public Log getLog(Class cls) { return getLog(cls, null); }
|
||||||
public Log getLog(String name) { return getLog(null, name); }
|
public Log getLog(String name) { return getLog(null, name); }
|
||||||
public Log getLog(Class cls, String name) {
|
public Log getLog(Class cls, String name) {
|
||||||
Log rv = null;
|
|
||||||
String scope = Log.getScope(name, cls);
|
String scope = Log.getScope(name, cls);
|
||||||
boolean isNew = false;
|
boolean isNew = false;
|
||||||
synchronized (_logs) {
|
Log rv = _logs.get(scope);
|
||||||
rv = (Log)_logs.get(scope);
|
|
||||||
if (rv == null) {
|
if (rv == null) {
|
||||||
rv = new Log(this, cls, name);
|
rv = new Log(this, cls, name);
|
||||||
_logs.put(scope, rv);
|
_logs.putIfAbsent(scope, rv);
|
||||||
isNew = true;
|
isNew = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (isNew)
|
if (isNew)
|
||||||
updateLimit(rv);
|
updateLimit(rv);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
public List getLogs() {
|
|
||||||
List rv = null;
|
/** @deprecated unused */
|
||||||
synchronized (_logs) {
|
public List<Log> getLogs() {
|
||||||
rv = new ArrayList(_logs.values());
|
return new ArrayList(_logs.values());
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addLog(Log log) {
|
void addLog(Log log) {
|
||||||
synchronized (_logs) {
|
_logs.putIfAbsent(log.getScope(), log);
|
||||||
if (!_logs.containsKey(log.getScope()))
|
|
||||||
_logs.put(log.getScope(), log);
|
|
||||||
}
|
|
||||||
updateLimit(log);
|
updateLimit(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,11 +208,8 @@ public class LogManager {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void addRecord(LogRecord record) {
|
void addRecord(LogRecord record) {
|
||||||
int numRecords = 0;
|
_records.offer(record);
|
||||||
synchronized (_records) {
|
int numRecords = _records.size();
|
||||||
_records.add(record);
|
|
||||||
numRecords = _records.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numRecords > 100) {
|
if (numRecords > 100) {
|
||||||
// the writer waits 10 seconds *or* until we tell them to wake up
|
// the writer waits 10 seconds *or* until we tell them to wake up
|
||||||
@@ -339,9 +333,7 @@ public class LogManager {
|
|||||||
parseLimits(config, PROP_RECORD_PREFIX);
|
parseLimits(config, PROP_RECORD_PREFIX);
|
||||||
}
|
}
|
||||||
private void parseLimits(Properties config, String recordPrefix) {
|
private void parseLimits(Properties config, String recordPrefix) {
|
||||||
synchronized (_limits) {
|
|
||||||
_limits.clear();
|
_limits.clear();
|
||||||
}
|
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
for (Iterator iter = config.keySet().iterator(); iter.hasNext();) {
|
for (Iterator iter = config.keySet().iterator(); iter.hasNext();) {
|
||||||
String key = (String) iter.next();
|
String key = (String) iter.next();
|
||||||
@@ -359,12 +351,10 @@ public class LogManager {
|
|||||||
|
|
||||||
LogLimit lim = new LogLimit(key, Log.getLevel(val));
|
LogLimit lim = new LogLimit(key, Log.getLevel(val));
|
||||||
//_log.debug("Limit found for " + name + " as " + val);
|
//_log.debug("Limit found for " + name + " as " + val);
|
||||||
synchronized (_limits) {
|
|
||||||
if (!_limits.contains(lim))
|
if (!_limits.contains(lim))
|
||||||
_limits.add(lim);
|
_limits.add(lim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
updateLimits();
|
updateLimits();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,12 +407,9 @@ public class LogManager {
|
|||||||
*/
|
*/
|
||||||
public Properties getLimits() {
|
public Properties getLimits() {
|
||||||
Properties rv = new Properties();
|
Properties rv = new Properties();
|
||||||
synchronized (_limits) {
|
for (LogLimit lim : _limits) {
|
||||||
for (int i = 0; i < _limits.size(); i++) {
|
|
||||||
LogLimit lim = (LogLimit)_limits.get(i);
|
|
||||||
rv.setProperty(lim.getRootName(), Log.toLevelString(lim.getLimit()));
|
rv.setProperty(lim.getRootName(), Log.toLevelString(lim.getLimit()));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,23 +447,17 @@ public class LogManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateLimits() {
|
private void updateLimits() {
|
||||||
Map logs = null;
|
for (Log log : _logs.values()) {
|
||||||
synchronized (_logs) {
|
|
||||||
logs = new HashMap(_logs);
|
|
||||||
}
|
|
||||||
for (Iterator iter = logs.values().iterator(); iter.hasNext();) {
|
|
||||||
Log log = (Log) iter.next();
|
|
||||||
updateLimit(log);
|
updateLimit(log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLimit(Log log) {
|
private void updateLimit(Log log) {
|
||||||
List limits = getLimits(log);
|
List<LogLimit> limits = getLimits(log);
|
||||||
LogLimit max = null;
|
LogLimit max = null;
|
||||||
LogLimit notMax = null;
|
LogLimit notMax = null;
|
||||||
if (limits != null) {
|
if (limits != null) {
|
||||||
for (int i = 0; i < limits.size(); i++) {
|
for (LogLimit cur : limits) {
|
||||||
LogLimit cur = (LogLimit) limits.get(i);
|
|
||||||
if (max == null)
|
if (max == null)
|
||||||
max = cur;
|
max = cur;
|
||||||
else {
|
else {
|
||||||
@@ -496,18 +477,16 @@ public class LogManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List getLimits(Log log) {
|
/** @return null if no matches */
|
||||||
ArrayList limits = null; // new ArrayList(4);
|
private List<LogLimit> getLimits(Log log) {
|
||||||
synchronized (_limits) {
|
ArrayList<LogLimit> limits = null; // new ArrayList(4);
|
||||||
for (int i = 0; i < _limits.size(); i++) {
|
for (LogLimit limit : _limits) {
|
||||||
LogLimit limit = (LogLimit)_limits.get(i);
|
|
||||||
if (limit.matches(log)) {
|
if (limit.matches(log)) {
|
||||||
if (limits == null)
|
if (limits == null)
|
||||||
limits = new ArrayList(4);
|
limits = new ArrayList(4);
|
||||||
limits.add(limit);
|
limits.add(limit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return limits;
|
return limits;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,12 +551,9 @@ public class LogManager {
|
|||||||
buf.append("# log limit overrides:\n");
|
buf.append("# log limit overrides:\n");
|
||||||
|
|
||||||
TreeMap limits = new TreeMap();
|
TreeMap limits = new TreeMap();
|
||||||
synchronized (_limits) {
|
for (LogLimit lim : _limits) {
|
||||||
for (int i = 0; i < _limits.size(); i++) {
|
|
||||||
LogLimit lim = (LogLimit)_limits.get(i);
|
|
||||||
limits.put(lim.getRootName(), Log.toLevelString(lim.getLimit()));
|
limits.put(lim.getRootName(), Log.toLevelString(lim.getLimit()));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (Iterator iter = limits.entrySet().iterator(); iter.hasNext(); ) {
|
for (Iterator iter = limits.entrySet().iterator(); iter.hasNext(); ) {
|
||||||
Map.Entry entry = (Map.Entry)iter.next();
|
Map.Entry entry = (Map.Entry)iter.next();
|
||||||
String path = (String)entry.getKey();
|
String path = (String)entry.getKey();
|
||||||
@@ -589,16 +565,9 @@ public class LogManager {
|
|||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<LogRecord> _removeAll() {
|
||||||
//List _getRecords() { return _records; }
|
List<LogRecord> vals = new LinkedList();
|
||||||
List _removeAll() {
|
_records.drainTo(vals);
|
||||||
List vals = null;
|
|
||||||
synchronized (_records) {
|
|
||||||
if (_records.size() <= 0)
|
|
||||||
return null;
|
|
||||||
vals = new ArrayList(_records);
|
|
||||||
_records.clear();
|
|
||||||
}
|
|
||||||
return vals;
|
return vals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -70,13 +70,12 @@ class LogWriter implements Runnable {
|
|||||||
public void flushRecords() { flushRecords(true); }
|
public void flushRecords() { flushRecords(true); }
|
||||||
public void flushRecords(boolean shouldWait) {
|
public void flushRecords(boolean shouldWait) {
|
||||||
try {
|
try {
|
||||||
List records = _manager._removeAll();
|
List<LogRecord> records = _manager._removeAll();
|
||||||
if (records == null) return;
|
if (records == null) return;
|
||||||
for (int i = 0; i < records.size(); i++) {
|
for (LogRecord rec : records) {
|
||||||
LogRecord rec = (LogRecord) records.get(i);
|
|
||||||
writeRecord(rec);
|
writeRecord(rec);
|
||||||
}
|
}
|
||||||
if (records.size() > 0) {
|
if (!records.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
_currentOut.flush();
|
_currentOut.flush();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
|
Reference in New Issue
Block a user