/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.sesame.proxy; import java.lang.reflect.Method; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.Timer; import com.opengamma.sesame.config.EngineUtils; /** * A proxy that measured the time taken by each method call and * sends it to the metrics repository. */ public final class MetricsProxy extends ProxyNodeDecorator { private final MetricRegistry _metricRegistry; /** * Create a metrics proxy using the specified registry to * record the timings. * * @param metricRegistry registry to record the timings in */ public MetricsProxy(MetricRegistry metricRegistry) { _metricRegistry = metricRegistry; } @Override protected boolean decorate(Class<?> interfaceType, Class<?> implementationType) { return true; } @Override protected Object invoke(Object proxy, Object delegate, Method method, Object[] args) throws Throwable { // this avoids timing calls to toString(), // hashCode() etc especially in a debugger if (method.getDeclaringClass() != Object.class) { String name = generateName(delegate, method); try (Timer.Context ignored = _metricRegistry.timer(name).time()) { return method.invoke(delegate, args); } } else { return method.invoke(delegate, args); } } private String generateName(Object delegate, Method method) { Object proxiedObject = EngineUtils.getProxiedObject(delegate); return proxiedObject.getClass().getCanonicalName() + "." + method.getName(); } @Override public boolean equals(Object o) { // We only care that the other object is also a metrics proxy in which // case nodes can safely be cached return this == o || (o != null && getClass() == o.getClass()); } @Override public int hashCode() { return getClass().hashCode(); } }