IceInternal.MetricsMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ice Show documentation
Show all versions of ice Show documentation
Ice is a comprehensive RPC framework that helps you build distributed applications with minimal effort using familiar object-oriented idioms
// **********************************************************************
//
// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
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, new Integer(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.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;
}