IceInternal.LoggerAdminI Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ice-compat Show documentation
Show all versions of ice-compat Show documentation
Ice is a comprehensive RPC framework that helps you build distributed applications with minimal effort using familiar object-oriented idioms
The newest version!
//
// Copyright (c) ZeroC, Inc. All rights reserved.
//
package IceInternal;
final class LoggerAdminI extends Ice._LoggerAdminDisp
{
@Override
public void attachRemoteLogger(Ice.RemoteLoggerPrx prx, Ice.LogMessageType[] messageTypes, String[] categories,
int messageMax, Ice.Current current)
throws Ice.RemoteLoggerAlreadyAttachedException
{
if(prx == null)
{
return; // can't send this null RemoteLogger anything!
}
Ice.RemoteLoggerPrx remoteLogger = Ice.RemoteLoggerPrxHelper.uncheckedCast(prx.ice_twoway());
Filters filters = new Filters(messageTypes, categories);
java.util.List initLogMessages = null;
synchronized(this)
{
if(_sendLogCommunicator == null)
{
if(_destroyed)
{
throw new Ice.ObjectNotExistException();
}
_sendLogCommunicator =
createSendLogCommunicator(current.adapter.getCommunicator(), _logger.getLocalLogger());
}
Ice.Identity remoteLoggerId = remoteLogger.ice_getIdentity();
if(_remoteLoggerMap.containsKey(remoteLoggerId))
{
if(_traceLevel > 0)
{
_logger.trace(_traceCategory, "rejecting `" + remoteLogger.toString() +
"' with RemoteLoggerAlreadyAttachedException");
}
throw new Ice.RemoteLoggerAlreadyAttachedException();
}
_remoteLoggerMap.put(remoteLoggerId,
new RemoteLoggerData(changeCommunicator(remoteLogger, _sendLogCommunicator), filters));
if(messageMax != 0)
{
initLogMessages = new java.util.LinkedList(_queue); // copy
}
else
{
initLogMessages = new java.util.LinkedList();
}
}
if(_traceLevel > 0)
{
_logger.trace(_traceCategory, "attached `" + remoteLogger.toString() + "'");
}
if(!initLogMessages.isEmpty())
{
filterLogMessages(initLogMessages, filters.messageTypes, filters.traceCategories, messageMax);
}
final Ice.Callback initCompletedCb = new Ice.Callback()
{
@Override
public void completed(Ice.AsyncResult r)
{
Ice.RemoteLoggerPrx remoteLogger = Ice.RemoteLoggerPrxHelper.uncheckedCast(r.getProxy());
try
{
remoteLogger.end_init(r);
if(_traceLevel > 1)
{
_logger.trace(_traceCategory, r.getOperation() + " on `" + remoteLogger.toString() +
"' completed successfully");
}
}
catch(Ice.LocalException ex)
{
deadRemoteLogger(remoteLogger, _logger, ex, r.getOperation());
}
}
};
try
{
remoteLogger.begin_init(_logger.getPrefix(), initLogMessages.toArray(new Ice.LogMessage[0]),
initCompletedCb);
}
catch(Ice.LocalException ex)
{
deadRemoteLogger(remoteLogger, _logger, ex, "init");
throw ex;
}
}
@Override
public boolean detachRemoteLogger(Ice.RemoteLoggerPrx remoteLogger, Ice.Current current)
{
if(remoteLogger == null)
{
return false;
}
//
// No need to convert the proxy as we only use its identity
//
boolean found = removeRemoteLogger(remoteLogger);
if(_traceLevel > 0)
{
if(found)
{
_logger.trace(_traceCategory, "detached `" + remoteLogger.toString() + "'");
}
else
{
_logger.trace(_traceCategory, "cannot detach `" + remoteLogger.toString() + "': not found");
}
}
return found;
}
@Override
public Ice.LogMessage[] getLog(Ice.LogMessageType[] messageTypes, String[] categories, int messageMax,
Ice.StringHolder prefix, Ice.Current current)
{
java.util.List logMessages = null;
synchronized(this)
{
if(messageMax != 0)
{
logMessages = new java.util.LinkedList(_queue);
}
else
{
logMessages = new java.util.LinkedList();
}
}
prefix.value = _logger.getPrefix();
if(!logMessages.isEmpty())
{
Filters filters = new Filters(messageTypes, categories);
filterLogMessages(logMessages, filters.messageTypes, filters.traceCategories, messageMax);
}
return logMessages.toArray(new Ice.LogMessage[0]);
}
LoggerAdminI(Ice.Properties props, LoggerAdminLoggerI logger)
{
_maxLogCount = props.getPropertyAsIntWithDefault("Ice.Admin.Logger.KeepLogs", 100);
_maxTraceCount = props.getPropertyAsIntWithDefault("Ice.Admin.Logger.KeepTraces", 100);
_traceLevel = props.getPropertyAsInt("Ice.Trace.Admin.Logger");
_logger = logger;
}
void destroy()
{
Ice.Communicator sendLogCommunicator = null;
synchronized(this)
{
if(!_destroyed)
{
_destroyed = true;
sendLogCommunicator = _sendLogCommunicator;
_sendLogCommunicator = null;
}
}
//
// Destroy outside lock to avoid deadlock when there are outstanding two-way log calls sent to
// remote loggers
//
if(sendLogCommunicator != null)
{
sendLogCommunicator.destroy();
}
}
synchronized java.util.List log(Ice.LogMessage logMessage)
{
java.util.List remoteLoggers = null;
//
// Put message in _queue
//
if((logMessage.type != Ice.LogMessageType.TraceMessage && _maxLogCount > 0) ||
(logMessage.type == Ice.LogMessageType.TraceMessage && _maxTraceCount > 0))
{
_queue.add(logMessage); // add at the end
if(logMessage.type != Ice.LogMessageType.TraceMessage)
{
assert(_maxLogCount > 0);
if(_logCount == _maxLogCount)
{
//
// Need to remove the oldest log from the queue
//
assert(_oldestLog != -1);
_queue.remove(_oldestLog);
int qs = _queue.size();
while(_oldestLog < qs && _queue.get(_oldestLog).type == Ice.LogMessageType.TraceMessage)
{
_oldestLog++;
}
assert(_oldestLog < qs); // remember: we just added a log message at end
}
else
{
assert(_logCount < _maxLogCount);
_logCount++;
if(_oldestLog == -1)
{
_oldestLog = _queue.size() - 1;
}
}
}
else
{
assert(_maxTraceCount > 0);
if(_traceCount == _maxTraceCount)
{
//
// Need to remove the oldest trace from the queue
//
assert(_oldestTrace != -1);
_queue.remove(_oldestTrace);
int qs = _queue.size();
while(_oldestTrace < qs && _queue.get(_oldestTrace).type != Ice.LogMessageType.TraceMessage)
{
_oldestTrace++;
}
assert(_oldestTrace < qs); // remember: we just added a trace message at end
}
else
{
assert(_traceCount < _maxTraceCount);
_traceCount++;
if(_oldestTrace == -1)
{
_oldestTrace = _queue.size() - 1;
}
}
}
//
// Queue updated, now find which remote loggers want this message
//
for(RemoteLoggerData p : _remoteLoggerMap.values())
{
Filters filters = p.filters;
if(filters.messageTypes.isEmpty() || filters.messageTypes.contains(logMessage.type))
{
if(logMessage.type != Ice.LogMessageType.TraceMessage || filters.traceCategories.isEmpty() ||
filters.traceCategories.contains(logMessage.traceCategory))
{
if(remoteLoggers == null)
{
remoteLoggers = new java.util.ArrayList();
}
remoteLoggers.add(p.remoteLogger);
}
}
}
}
return remoteLoggers;
}
void deadRemoteLogger(Ice.RemoteLoggerPrx remoteLogger, Ice.Logger logger, Ice.LocalException ex, String operation)
{
//
// No need to convert remoteLogger as we only use its identity
//
if(removeRemoteLogger(remoteLogger))
{
if(_traceLevel > 0)
{
logger.trace(_traceCategory, "detached `" + remoteLogger.toString() + "' because "
+ operation + " raised:\n" + ex.toString());
}
}
}
int getTraceLevel()
{
return _traceLevel;
}
private synchronized boolean removeRemoteLogger(Ice.RemoteLoggerPrx remoteLogger)
{
return _remoteLoggerMap.remove(remoteLogger.ice_getIdentity()) != null;
}
private static void filterLogMessages(java.util.List logMessages,
java.util.Set messageTypes,
java.util.Set traceCategories, int messageMax)
{
assert(!logMessages.isEmpty() && messageMax != 0);
//
// Filter only if one of the 3 filters is set; messageMax < 0 means "give me all"
// that match the other filters, if any.
//
if(!messageTypes.isEmpty() || !traceCategories.isEmpty() || messageMax > 0)
{
int count = 0;
java.util.ListIterator p = logMessages.listIterator(logMessages.size());
while(p.hasPrevious())
{
boolean keepIt = false;
Ice.LogMessage msg = p.previous();
if(messageTypes.isEmpty() || messageTypes.contains(msg.type))
{
if(msg.type != Ice.LogMessageType.TraceMessage || traceCategories.isEmpty() ||
traceCategories.contains(msg.traceCategory))
{
keepIt = true;
}
}
if(keepIt)
{
++count;
if(messageMax > 0 && count >= messageMax)
{
if(p.hasPrevious())
{
int removeCount = p.previousIndex() + 1;
for(int i = 0; i < removeCount; ++i)
{
logMessages.remove(0);
}
}
break; // while
}
}
else
{
p.remove();
}
}
}
// else, don't need any filtering
}
//
// Change this proxy's communicator, while keeping its invocation timeout
//
private static Ice.RemoteLoggerPrx changeCommunicator(Ice.RemoteLoggerPrx prx, Ice.Communicator communicator)
{
if(prx == null)
{
return null;
}
Ice.ObjectPrx result = communicator.stringToProxy(prx.toString());
return Ice.RemoteLoggerPrxHelper.uncheckedCast(result.ice_invocationTimeout(prx.ice_getInvocationTimeout()));
}
private static void copyProperties(String prefix, Ice.Properties from, Ice.Properties to)
{
for(java.util.Map.Entry p : from.getPropertiesForPrefix(prefix).entrySet())
{
to.setProperty(p.getKey(), p.getValue());
}
}
private static Ice.Communicator createSendLogCommunicator(Ice.Communicator communicator, Ice.Logger logger)
{
Ice.InitializationData initData = new Ice.InitializationData();
initData.logger = logger;
initData.properties = Ice.Util.createProperties();
Ice.Properties mainProps = communicator.getProperties();
copyProperties("Ice.Default.Locator", mainProps, initData.properties);
copyProperties("Ice.Plugin.IceSSL", mainProps, initData.properties);
copyProperties("IceSSL.", mainProps, initData.properties);
String[] extraProps = mainProps.getPropertyAsList("Ice.Admin.Logger.Properties");
if(extraProps.length > 0)
{
for(int i = 0; i < extraProps.length; ++i)
{
String p = extraProps[i];
if(!p.startsWith("--"))
{
extraProps[i] = "--" + p;
}
}
initData.properties.parseCommandLineOptions("", extraProps);
}
return Ice.Util.initialize(initData);
}
private final java.util.List _queue = new java.util.LinkedList();
private int _logCount = 0; // non-trace messages
private final int _maxLogCount;
private int _traceCount = 0;
private final int _maxTraceCount;
private final int _traceLevel;
private int _oldestTrace = -1;
private int _oldestLog = -1;
private static class Filters
{
Filters(Ice.LogMessageType[] m, String[] c)
{
messageTypes = new java.util.HashSet(java.util.Arrays.asList(m));
traceCategories = new java.util.HashSet(java.util.Arrays.asList(c));
}
final java.util.Set messageTypes;
final java.util.Set traceCategories;
}
private static class RemoteLoggerData
{
RemoteLoggerData(Ice.RemoteLoggerPrx prx, Filters f)
{
remoteLogger = prx;
filters = f;
}
final Ice.RemoteLoggerPrx remoteLogger;
final Filters filters;
}
private final java.util.Map _remoteLoggerMap
= new java.util.HashMap();
private final LoggerAdminLoggerI _logger;
private Ice.Communicator _sendLogCommunicator = null;
private boolean _destroyed = false;
static private final String _traceCategory = "Admin.Logger";
}