IceInternal.MetricsMap 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
//
// Copyright (c) ZeroC, Inc. All rights reserved.
//
package IceInternal;
public class MetricsMap
{
public class Entry
{
Entry(T obj)
{
_object = obj;
}
public void
failed(String exceptionName)
{
synchronized(MetricsMap.this)
{
++_object.failures;
if(_failures == null)
{
_failures = new java.util.HashMap();
}
Integer count = _failures.get(exceptionName);
_failures.put(exceptionName, Integer.valueOf(count == null ? 1 : count + 1));
}
}
@SuppressWarnings("unchecked")
public MetricsMap.Entry
getMatching(String mapName, IceMX.MetricsHelper helper, Class cl)
{
SubMap m;
synchronized(MetricsMap.this)
{
m = _subMaps != null ? (SubMap)_subMaps.get(mapName) : null;
if(m == null)
{
m = createSubMap(mapName, cl);
if(m == null)
{
return null;
}
if(_subMaps == null)
{
_subMaps = new java.util.HashMap>();
}
_subMaps.put(mapName, m);
}
}
return m.getMatching(helper);
}
public void
detach(long lifetime)
{
synchronized(MetricsMap.this)
{
_object.totalLifetime += lifetime;
if(--_object.current == 0)
{
detached(this);
}
}
}
public void
execute(IceMX.Observer.MetricsUpdate func)
{
synchronized(MetricsMap.this)
{
func.update(_object);
}
}
public MetricsMap>
getMap()
{
return MetricsMap.this;
}
private IceMX.MetricsFailures
getFailures()
{
if(_failures == null)
{
return null;
}
IceMX.MetricsFailures f = new IceMX.MetricsFailures();
f.id = _object.id;
f.failures = new java.util.HashMap(_failures);
return f;
}
private void
attach(IceMX.MetricsHelper helper)
{
++_object.total;
++_object.current;
helper.initMetrics(_object);
}
private boolean
isDetached()
{
return _object.current == 0;
}
@Override
@SuppressWarnings("unchecked")
public IceMX.Metrics
clone()
{
T metrics = (T)_object.clone();
if(_subMaps != null)
{
for(SubMap> s : _subMaps.values())
{
s.addSubMapToMetrics(metrics);
}
}
return metrics;
}
private T _object;
private java.util.Map _failures;
private java.util.Map> _subMaps;
}
static class SubMap
{
public
SubMap(MetricsMap map, java.lang.reflect.Field field)
{
_map = map;
_field = field;
}
public MetricsMap.Entry
getMatching(IceMX.MetricsHelper helper)
{
return _map.getMatching(helper, null);
}
public void
addSubMapToMetrics(IceMX.Metrics metrics)
{
try
{
_field.set(metrics, _map.getMetrics());
}
catch(Exception ex)
{
assert(false);
}
}
final private MetricsMap _map;
final private java.lang.reflect.Field _field;
}
static class SubMapCloneFactory
{
public SubMapCloneFactory(MetricsMap map, java.lang.reflect.Field field)
{
_map = map;
_field = field;
}
public SubMap
create()
{
return new SubMap(new MetricsMap(_map), _field);
}
final private MetricsMap _map;
final private java.lang.reflect.Field _field;
}
static class SubMapFactory
{
SubMapFactory(Class cl, java.lang.reflect.Field field)
{
_class = cl;
_field = field;
}
SubMapCloneFactory
createCloneFactory(String subMapPrefix, Ice.Properties properties)
{
return new SubMapCloneFactory(new MetricsMap(subMapPrefix, _class, properties, null), _field);
}
final private Class _class;
final private java.lang.reflect.Field _field;
}
MetricsMap(String mapPrefix, Class cl, Ice.Properties props, java.util.Map> subMaps)
{
MetricsAdminI.validateProperties(mapPrefix, props);
_properties = props.getPropertiesForPrefix(mapPrefix);
_retain = props.getPropertyAsIntWithDefault(mapPrefix + "RetainDetached", 10);
_accept = parseRule(props, mapPrefix + "Accept");
_reject = parseRule(props, mapPrefix + "Reject");
_groupByAttributes = new java.util.ArrayList();
_groupBySeparators = new java.util.ArrayList();
_class = cl;
String groupBy = props.getPropertyWithDefault(mapPrefix + "GroupBy", "id");
if(!groupBy.isEmpty())
{
String v = "";
boolean attribute = Character.isLetter(groupBy.charAt(0)) || Character.isDigit(groupBy.charAt(0));
if(!attribute)
{
_groupByAttributes.add("");
}
for(char p : groupBy.toCharArray())
{
boolean isAlphaNum = Character.isLetter(p) || Character.isDigit(p) || p == '.';
if(attribute && !isAlphaNum)
{
_groupByAttributes.add(v);
v = "" + p;
attribute = false;
}
else if(!attribute && isAlphaNum)
{
_groupBySeparators.add(v);
v = "" + p;
attribute = true;
}
else
{
v += p;
}
}
if(attribute)
{
_groupByAttributes.add(v);
}
else
{
_groupBySeparators.add(v);
}
}
if(subMaps != null && !subMaps.isEmpty())
{
_subMaps = new java.util.HashMap>();
java.util.List subMapNames = new java.util.ArrayList();
for(java.util.Map.Entry> e : subMaps.entrySet())
{
subMapNames.add(e.getKey());
String subMapsPrefix = mapPrefix + "Map.";
String subMapPrefix = subMapsPrefix + e.getKey() + '.';
if(props.getPropertiesForPrefix(subMapPrefix).isEmpty())
{
if(props.getPropertiesForPrefix(subMapsPrefix).isEmpty())
{
subMapPrefix = mapPrefix;
}
else
{
continue; // This sub-map isn't configured.
}
}
_subMaps.put(e.getKey(), e.getValue().createCloneFactory(subMapPrefix, props));
}
}
else
{
_subMaps = null;
}
}
MetricsMap(MetricsMap map)
{
_properties = map._properties;
_groupByAttributes = map._groupByAttributes;
_groupBySeparators = map._groupBySeparators;
_retain = map._retain;
_accept = map._accept;
_reject = map._reject;
_class = map._class;
_subMaps = map._subMaps;
}
java.util.Map
getProperties()
{
return _properties;
}
synchronized IceMX.Metrics[]
getMetrics()
{
IceMX.Metrics[] metrics = new IceMX.Metrics[_objects.size()];
int i = 0;
for(Entry e : _objects.values())
{
metrics[i++] = e.clone();
}
return metrics;
}
synchronized IceMX.MetricsFailures[]
getFailures()
{
java.util.List failures = new java.util.ArrayList();
for(Entry e : _objects.values())
{
IceMX.MetricsFailures f = e.getFailures();
if(f != null)
{
failures.add(f);
}
}
return failures.toArray(new IceMX.MetricsFailures[failures.size()]);
}
synchronized IceMX.MetricsFailures
getFailures(String id)
{
Entry e = _objects.get(id);
if(e != null)
{
return e.getFailures();
}
return null;
}
@SuppressWarnings("unchecked")
public SubMap
createSubMap(String subMapName, Class cl)
{
if(_subMaps == null)
{
return null;
}
SubMapCloneFactory factory = (SubMapCloneFactory)_subMaps.get(subMapName);
if(factory != null)
{
return factory.create();
}
return null;
}
public Entry
getMatching(IceMX.MetricsHelper helper, Entry previous)
{
//
// Check the accept and reject filters.
//
for(java.util.Map.Entry e : _accept.entrySet())
{
if(!match(e.getKey(), e.getValue(), helper, false))
{
return null;
}
}
for(java.util.Map.Entry e : _reject.entrySet())
{
if(match(e.getKey(), e.getValue(), helper, true))
{
return null;
}
}
//
// Compute the key from the GroupBy property.
//
String key;
try
{
if(_groupByAttributes.size() == 1)
{
key = helper.resolve(_groupByAttributes.get(0));
}
else
{
StringBuilder os = new StringBuilder();
java.util.Iterator q = _groupBySeparators.iterator();
for(String p : _groupByAttributes)
{
os.append(helper.resolve(p));
if(q.hasNext())
{
os.append(q.next());
}
}
key = os.toString();
}
}
catch(Exception ex)
{
return null;
}
//
// Lookup the metrics object.
//
synchronized(this)
{
if(previous != null && previous._object.id.equals(key))
{
assert(_objects.get(key) == previous);
return previous;
}
Entry e = _objects.get(key);
if(e == null)
{
try
{
T t = _class.getDeclaredConstructor().newInstance();
t.id = key;
e = new Entry(t);
_objects.put(key, e);
}
catch(Exception ex)
{
assert(false);
}
}
e.attach(helper);
return e;
}
}
private void
detached(Entry entry)
{
if(_retain == 0)
{
return;
}
if(_detachedQueue == null)
{
_detachedQueue = new java.util.LinkedList();
}
assert(_detachedQueue.size() <= _retain);
// Compress the queue by removing entries which are no longer detached.
java.util.Iterator p = _detachedQueue.iterator();
while(p.hasNext())
{
Entry e = p.next();
if(e == entry || !e.isDetached())
{
p.remove();
}
}
// If there's still no room, remove the oldest entry (at the front).
if(_detachedQueue.size() == _retain)
{
_objects.remove(_detachedQueue.pollFirst()._object.id);
}
// Add the entry at the back of the queue.
_detachedQueue.add(entry);
}
private java.util.Map
parseRule(Ice.Properties properties, String name)
{
java.util.Map pats = new java.util.HashMap();
java.util.Map rules = properties.getPropertiesForPrefix(name + '.');
for(java.util.Map.Entry e : rules.entrySet())
{
pats.put(e.getKey().substring(name.length() + 1), java.util.regex.Pattern.compile(e.getValue()));
}
return pats;
}
private boolean
match(String attribute, java.util.regex.Pattern regex, IceMX.MetricsHelper helper, boolean reject)
{
String value;
try
{
value = helper.resolve(attribute);
}
catch(Exception ex)
{
return !reject;
}
return regex.matcher(value).matches();
}
final private java.util.Map _properties;
final private java.util.List _groupByAttributes;
final private java.util.List _groupBySeparators;
final private int _retain;
final private java.util.Map _accept;
final private java.util.Map _reject;
final private Class _class;
final private java.util.Map _objects = new java.util.HashMap();
final private java.util.Map> _subMaps;
private java.util.Deque _detachedQueue;
}