All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netflix.servo.monitor.TimedInterface Maven / Gradle / Ivy

There is a newer version: 0.13.2
Show newest version
/**
 * Copyright 2013 Netflix, Inc.
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.netflix.servo.monitor; import com.netflix.servo.tag.BasicTagList; import com.netflix.servo.tag.TagList; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * This class creates a {@link java.lang.reflect.Proxy} monitor that tracks all calls to methods * of an interface. *

*

 *   IDummy dummy = TimedInterface.newProxy(IDummy.class, new DummyImpl(), "id");
 *   DefaultMonitorRegistry.getInstance().register((CompositeMonitor)dummy);
 * 
*

*

* All calls to methods implemented by IDummy would have an associated BasicTimer with them. The * name for the {@link CompositeMonitor} is the name of the method. Additional tags are added: *

    *
  • interface interface being implemented. *
  • class simple name of the concrete class implementing the interface. *
  • id (Optional) An identifier for this particular instance. *
*

*/ public final class TimedInterface { static final String TIMED_INTERFACE = "TimedInterface"; static final String INTERFACE_TAG = "interface"; static final String CLASS_TAG = "class"; static final String ID_TAG = "id"; private static class TimedHandler implements InvocationHandler, CompositeMonitor { private final T concrete; private final Map timers; private final MonitorConfig baseConfig; private final TagList baseTagList; /** * {@inheritDoc} */ @Override public List> getMonitors() { return timers.values().stream().collect(Collectors.toList()); } @Override public Long getValue(int pollerIdx) { return (long) timers.size(); } @Override public Long getValue() { return getValue(0); } /** * {@inheritDoc} */ @Override public MonitorConfig getConfig() { return baseConfig; } TimedHandler(Class ctype, T concrete, String id) { this.concrete = concrete; BasicTagList tagList = BasicTagList.of( INTERFACE_TAG, ctype.getSimpleName(), CLASS_TAG, concrete.getClass().getSimpleName()); if (id != null) { tagList = tagList.copy(ID_TAG, id); } baseTagList = tagList; baseConfig = MonitorConfig.builder(TIMED_INTERFACE).withTags(baseTagList).build(); timers = new HashMap<>(); for (Method method : ctype.getMethods()) { final MonitorConfig config = MonitorConfig.builder(method.getName()) .withTags(baseTagList) .build(); timers.put(method.getName(), new BasicTimer(config)); } } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // if the method is one of the CompositeMonitor interface final Class declaringClass = method.getDeclaringClass(); if (declaringClass.isAssignableFrom(CompositeMonitor.class)) { return method.invoke(this, args); } final String methodName = method.getName(); final Timer timer = timers.get(methodName); final Stopwatch stopwatch = timer.start(); try { return method.invoke(concrete, args); } finally { stopwatch.stop(); } } } private TimedInterface() { } /** * Creates a new TimedInterface for a given interface ctype with a concrete class * concrete and a specific id. The id can be used to distinguish among multiple * objects with the same concrete class. */ @SuppressWarnings("unchecked") public static T newProxy(Class ctype, T concrete, String id) { final InvocationHandler handler = new TimedHandler<>(ctype, concrete, id); final Class[] types = new Class[]{ctype, CompositeMonitor.class}; return (T) Proxy.newProxyInstance(ctype.getClassLoader(), types, handler); } /** * Creates a new TimedInterface for a given interface ctype with a concrete class * concrete. */ public static T newProxy(Class ctype, T concrete) { return newProxy(ctype, concrete, null); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy