Remove io.netty.monitor as discussed in #922

This commit is contained in:
Trustin Lee 2013-01-18 11:08:57 +09:00
parent 2c7be32393
commit 24acfe7008
32 changed files with 0 additions and 2197 deletions

View File

@ -1,82 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor;
/**
* <p>
* A simple monitor that increments and/or decrements a {@code long} value.
* </p>
* <p>
* <strong>DISCLAIMER</strong> This interface is heavily based on <a
* href="http://metrics.codahale.com/">Yammer's</a>
* {@link com.yammer.metrics.core.Counter Counter}.
* </p>
*/
public interface CounterMonitor {
/**
* Null object.
*/
CounterMonitor NOOP = new CounterMonitor() {
@Override
public void reset() {
}
@Override
public void increment(long delta) {
}
@Override
public void increment() {
}
@Override
public void decrement(long delta) {
}
@Override
public void decrement() {
}
};
/**
* Increment this counter by 1.
*/
void increment();
/**
* Increment this counter by the supplied {@code delta}.
* @param delta The delta to apply
*/
void increment(long delta);
/**
* Decrement this counter by 1.
*/
void decrement();
/**
* Decrement this counter by the supplied {@code delta}.
* @param delta The delta to apply
*/
void decrement(long delta);
/**
* Reset this counter to its initial state.
*/
void reset();
}

View File

@ -1,53 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor;
/**
* <p>
* Record the rate which an event occurs at.
* </p>
* <p>
* <strong>DISCLAIMER</strong> This interface is heavily based on <a
* href="http://metrics.codahale.com/">Yammer's</a>
* {@link com.yammer.metrics.core.Meter Meter}.
* </p>
*/
public interface EventRateMonitor {
/**
* Null object.
*/
EventRateMonitor NOOP = new EventRateMonitor() {
@Override
public void events(final long count) {
}
@Override
public void event() {
}
};
/**
* Record occurrence of one event.
*/
void event();
/**
* Record {@code count} event occurrences.
*/
void events(long count);
}

View File

@ -1,257 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor;
/**
* <p>
* Represents a {@code Monitor}'s unique name. This name is composed of
* <ol>
* <li>a {@code group}, an arbitrary name for a set of logically related
* {@code Monitors}, e.g. "network";</li>
* <li>a {@code type}, an arbitrary string identifying a {@code Monitor}'s
* {@code type}, commonly denoting the resource to be monitored, e.g.
* "client-connection";</li>
* <li>a {@code name}, an arbitrary string identifying what is actually
* monitored, e.g. "bytes-per-second"; and</li>
* <li>an {@code instance} (optional), an arbitrary string identifying the exact
* resource instance to be monitored, in case we aren't dealing with a singleton
* resource, e.g. "client-connection#67AF4".</li>
* </ol>
* </p>
* <p>
* <strong>DISCLAIMER</strong> This class is heavily based on <a
* href="http://metrics.codahale.com/">Yammer's</a>
* {@link com.yammer.metrics.core.MetricName MetricName}.
* </p>
*/
public final class MonitorName {
private final String group;
private final String type;
private final String name;
private final String instance;
/**
* Create a new {@code MonitorName}, using the supplied
* {@code monitoredClass}'s {@code package name} as its {@link #group()
* group}, the {@code monitoredClass}'s {@code simple name} as its
* {@link #type()} and the supplied {@code name} as its
* {@link #name() name}.
* @param monitoredClass The class to be monitored, i.e. a class that
* represents a resource whose statistics we are interested in
* @param name Our new {@code MonitorName}'s {@link #name() name}
* @throws NullPointerException If either {@code monitoredClass} or
* {@code name} is {@code null}
*/
public MonitorName(final Class<?> monitoredClass, final String name) {
this(monitoredClass.getPackage() != null ? monitoredClass.getPackage().getName() : "", monitoredClass
.getSimpleName().replaceAll("\\$$", ""), name, null);
}
/**
* Create a new {@code MonitorName}, using the supplied
* {@code monitoredClass}'s {@code package name} as its {@link #group()
* group}, the {@code monitoredClass}'s {@code simple name} as its
* {@link #type()}, the supplied {@code name} as its {@link #name()
* name} and the supplied {@code instance} as its {@link #instance()
* instance}.
* @param monitoredClass The class to be monitored, i.e. a class that
* represents a resource whose statistics we are interested in
* @param name Our new {@code MonitorName}'s {@link #name() name}
* @param instance Our new {@code MonitorName}'s {@link #instance()
* instance}
* @throws NullPointerException If either {@code monitoredClass} or
* {@code name} is {@code null}
*/
public MonitorName(final Class<?> monitoredClass, final String name, final String instance) {
this(monitoredClass.getPackage().getName(), monitoredClass.getSimpleName(), name, instance);
}
/**
* Create a new {@code MonitorName} out of the supplied {@code group},
* {@code type} and {@code name}.
* @param group Our new {@code MonitorName}'s {@link #group() group}
* @param type Our new {@code MonitorName}'s {@link #type() type}
* @param name Our new {@code MonitorName}'s {@link #name() name}
* @throws NullPointerException If one of {@code group}, {@code type} and
* {@code name} is {@code null}
*/
public MonitorName(final String group, final String type, final String name) {
this(group, type, name, null);
}
/**
* Create a new {@code MonitorName} out of the supplied {@code group},
* {@code type}, {@code name} and {@code instance}
* @param group Our new {@code MonitorName}'s {@link #group() group}
* @param type Our new {@code MonitorName}'s {@link #type() type}
* @param name Our new {@code MonitorName}'s {@link #name() name}
* @param instance Our new {@code MonitorName}'s {@link #instance()
* instance}
* @throws NullPointerException If one of {@code group}, {@code type} and
* {@code name} is {@code null}
*/
public MonitorName(final String group, final String type, final String name, final String instance) {
if (group == null) {
throw new NullPointerException("group");
}
if (type == null) {
throw new NullPointerException("type");
}
if (name == null) {
throw new NullPointerException("name");
}
this.group = group;
this.type = type;
this.name = name;
this.instance = instance;
}
/**
* Returns a copy of this {@code MonitorName} with its
* {@link #instance() instance} field replaced by the supplied
* {@code instance}. Serves to support a poor man's templating mechanism for
* {@code MonitorNames}.
* @param instance The instance to be used in the {@code MonitorName}
* returned by this method
* @return A copy of this {@code MonitorName} with its
* {@link #instance() instance} field replaced by the supplied
* {@code instance}
* @throws NullPointerException If {@code instance} is {@code null}
*/
public MonitorName ofInstance(final String instance) {
if (instance == null) {
throw new NullPointerException("instance");
}
if (instance.equals(this.instance)) {
return this;
}
return new MonitorName(group, type, name, instance);
}
/**
* This {@code MonitorName}'s {@code group}, an arbitrary name for a set of
* logically related {@code Monitors}, e.g. "network".
* @return The group, an arbitrary name for a set of logically related
* {@code Monitors}
*/
public String group() {
return group;
}
/**
* This {@code MonitorName}'s {@code type}, an arbitrary string identifying
* a {@code Monitor}'s {@code type}, commonly denoting the resource to be
* monitored, e.g. "client-connection".
* @return The type, an arbitrary string identifying a {@code Monitor}'s
* {@code type}, commonly denoting the resource to be monitored
*/
public String type() {
return type;
}
/**
* This {@code MonitorName}'s {@code name}, an arbitrary string identifying
* what is actually monitored, e.g. "bytes-per-second".
* @return The name, an arbitrary string identifying what is actually
* monitored
*/
public String name() {
return name;
}
/**
* This {@code MonitorName}'s {@code instance} (optional), an arbitrary
* string identifying the exact resource instance to be monitored, in case
* we aren't dealing with a singleton resource, e.g.
* "client-connection#67AF4".
* @return The instance (optional), an arbitrary string identifying the
* exact resource instance to be monitored, in case we aren't
* dealing with a singleton resource
*/
public String instance() {
return instance;
}
/**
* @see Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (group == null ? 0 : group.hashCode());
result = prime * result + (instance == null ? 0 : instance.hashCode());
result = prime * result + (name == null ? 0 : name.hashCode());
result = prime * result + (type == null ? 0 : type.hashCode());
return result;
}
/**
* @see Object#equals(Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final MonitorName other = (MonitorName) obj;
if (group == null) {
if (other.group != null) {
return false;
}
} else if (!group.equals(other.group)) {
return false;
}
if (instance == null) {
if (other.instance != null) {
return false;
}
} else if (!instance.equals(other.instance)) {
return false;
}
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
if (type == null) {
if (other.type != null) {
return false;
}
} else if (!type.equals(other.type)) {
return false;
}
return true;
}
/**
* @see Object#toString()
*/
@Override
public String toString() {
return instance != null ? "Monitor(" + group + '/' + type + '/' + name + '/' + instance + ')' : "Monitor("
+ group + '/' + type + '/' + name + ')';
}
}

View File

@ -1,176 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor;
import io.netty.logging.InternalLogger;
import io.netty.logging.InternalLoggerFactory;
import io.netty.monitor.spi.MonitorProvider;
import io.netty.monitor.spi.MonitorRegistryFactory;
import java.util.Iterator;
import java.util.ServiceLoader;
/**
* <p>
* Represents all {@link MonitorRegistry MonitorRegistries} that can be
* constructed by {@link MonitorRegistryFactory MonitorRegistryFactories} loaded
* using Java 6's {@link ServiceLoader}.
* </p>
* <p>
* A {@code MonitorRegistryFactory} that wishes to contribute a
* {@code MonitorRegistry} via {@code MonitorRegistries} needs to
* <ol>
* <li>have a no-args default constructor, and</li>
* <li>register itself - its fully qualified class name - in
* {@code META-INF/services/io.netty.monitor.spi.MonitorRegistryFactory}.</li>
* </ol>
* </p>
*/
public final class MonitorRegistries implements Iterable<MonitorRegistry> {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(MonitorRegistries.class);
//set of initialization states
private static final int UNINITIALIZED = 0;
private static final int ONGOING_INITIALIZATION = 1;
private static final int SUCCESSFUL_INITIALIZATION = 2;
private static final int NOP_FALLBACK_INITIALIZATION = 3;
@SuppressWarnings("RedundantFieldInitialization")
private static int initState = UNINITIALIZED;
private static MonitorRegistry selectedRegistry;
/**
* Return <em>the</em> singleton {@code MonitorRegistries} instance.
*
* @return <em>The</em> singleton {@code MonitorRegistries} instance
*/
public static MonitorRegistries instance() {
return Holder.INSTANCE;
}
private interface Holder {
MonitorRegistries INSTANCE = new MonitorRegistries();
}
private static final ServiceLoader<MonitorRegistryFactory> FACTORIES = ServiceLoader
.load(MonitorRegistryFactory.class);
/**
* Create a new {@link MonitorRegistry} that supports the supplied
* {@link MonitorProvider provider}.
*
* @param provider The {@link MonitorProvider provider} we are interested in
* @return A {@link MonitorRegistry} implemented by the supplied
* {@link MonitorProvider provider}
* @throws NullPointerException If {@code provider} is {@code null}
* @throws IllegalArgumentException If no {@code MonitorRegistry} matching
* the given {@link MonitorProvider provider} could be found
*/
public static MonitorRegistry forProvider(final MonitorProvider provider) {
if (provider == null) {
throw new NullPointerException("provider");
}
for (final MonitorRegistryFactory candidate : FACTORIES) {
if (candidate.provider().equals(provider)) {
return candidate.newMonitorRegistry();
}
}
throw new IllegalArgumentException("Could not find MonitorRegistryFactory by provider " + provider
+ " among the set of registered MonitorRegistryFactories");
}
/**
* <p>
* Look up and return <em>the</em> a uniquely determined
* {@link MonitorRegistry} implementation. This method will select
* exactly one {@link MonitorRegistryFactory} from those registered in
* {@code META-INF/services/io.netty.monitor.spi.MonitorRegistryFactory}.
* if no implementation is found then a NOOP registry is returned.
* If multiple implementations are found then the first one returned by
* {@link #iterator()} is used and a message is logged to say which one is
* selected.
* </p>
*
* @return <em>the</em> uniquely determined {@link MonitorRegistry}
* implementation
*/
public MonitorRegistry unique() {
//Implementation based on SLF4J's
if (initState == UNINITIALIZED) {
initState = ONGOING_INITIALIZATION;
performInitialization();
}
switch (initState) {
case SUCCESSFUL_INITIALIZATION:
return selectedRegistry;
case NOP_FALLBACK_INITIALIZATION:
case ONGOING_INITIALIZATION:
default:
return MonitorRegistry.NOOP;
}
}
private void performInitialization() {
final Iterator<MonitorRegistry> registries = iterator();
if (registries.hasNext()) {
selectedRegistry = registries.next();
initState = SUCCESSFUL_INITIALIZATION;
}
if (selectedRegistry != null && registries.hasNext()) {
logger.warn(String.format("Multiple metrics implementations found. " +
"Selected %s, ignoring other implementations", selectedRegistry.getClass().getName()));
}
if (selectedRegistry == null) {
initState = NOP_FALLBACK_INITIALIZATION;
logger.debug("No metrics implementation found on the classpath.");
}
}
/**
* @see Iterable#iterator()
*/
@Override
public Iterator<MonitorRegistry> iterator() {
return new MonitorRegistryIterator(FACTORIES.iterator());
}
private static final class MonitorRegistryIterator implements Iterator<MonitorRegistry> {
private final Iterator<MonitorRegistryFactory> factories;
private MonitorRegistryIterator(final Iterator<MonitorRegistryFactory> factories) {
this.factories = factories;
}
@Override
public boolean hasNext() {
return factories.hasNext();
}
@Override
public MonitorRegistry next() {
return factories.next().newMonitorRegistry();
}
@Override
public void remove() {
throw new UnsupportedOperationException("Removing a MonitorRegistry is not supported");
}
}
private MonitorRegistries() {
// Singleton
}
}

View File

@ -1,73 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor;
import java.util.concurrent.TimeUnit;
/**
* <p>
* A factory for {@code Monitors}. Implementations are expected to keep a
* reference to each created {@code Monitor} in order to provide additional
* services, e.g. publish metrics fed by those {@code Monitors} via {@code JMX},
* {@code HTTP}.
* </p>
*/
public interface MonitorRegistry {
/**
* Null object.
*/
MonitorRegistry NOOP = NoopMonitorRegistry.INSTANCE;
/**
* Create a new {@link ValueDistributionMonitor} having the supplied
* {@link MonitorName monitorName}.
* @param monitorName The new {@link ValueDistributionMonitor}'s
* {@link MonitorName}
* @return A new {@link ValueDistributionMonitor} having the supplied
* {@link MonitorName monitorName}
*/
ValueDistributionMonitor newValueDistributionMonitor(MonitorName monitorName);
/**
* Create a new {@link EventRateMonitor} having the supplied
* {@link MonitorName monitorName}.
* @param monitorName The new {@link EventRateMonitor}'s {@link MonitorName}
* @param rateUnit The {@link TimeUnit resolution} to measure our event rate
* at
* @return A new {@link EventRateMonitor} having the supplied
* {@link MonitorName monitorName} and {@link TimeUnit rateUnit}
*/
EventRateMonitor newEventRateMonitor(MonitorName monitorName, TimeUnit rateUnit);
/**
* Register a new {@link ValueMonitor} for a datum of type {@code T}, having
* the supplied {@link MonitorName monitorName}.
* @param monitorName The new {@link ValueMonitor}'s {@link MonitorName}
* @param valueMonitor The {@link ValueMonitor} to register
* @return The {@link ValueMonitor} passed in
*/
<T> ValueMonitor<T> registerValueMonitor(MonitorName monitorName, ValueMonitor<T> valueMonitor);
/**
* Create a new {@link CounterMonitor} having the supplied
* {@link MonitorName monitorName}.
* @param monitorName The new {@link CounterMonitor}'s {@link MonitorName}
* @return A new {@link CounterMonitor} having the supplied
* {@link MonitorName monitorName}
*/
CounterMonitor newCounterMonitor(MonitorName monitorName);
}

View File

@ -1,67 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor;
import java.util.concurrent.TimeUnit;
/**
* <p>
* A {@link MonitorRegistry} that creates noop {@code Monitors}. Serves as a <a
* href="http://en.wikipedia.org/wiki/Null_Object_pattern">Null Object</a>.
* </p>
*/
final class NoopMonitorRegistry implements MonitorRegistry {
static final NoopMonitorRegistry INSTANCE = new NoopMonitorRegistry();
/**
* @see MonitorRegistry#newValueDistributionMonitor(MonitorName)
*/
@Override
public ValueDistributionMonitor newValueDistributionMonitor(final MonitorName monitorName) {
return ValueDistributionMonitor.NOOP;
}
/**
* @see MonitorRegistry#newEventRateMonitor(MonitorName,
* TimeUnit)
*/
@Override
public EventRateMonitor newEventRateMonitor(final MonitorName monitorName, final TimeUnit rateUnit) {
return EventRateMonitor.NOOP;
}
/**
* @see MonitorRegistry#registerValueMonitor(MonitorName,
* ValueMonitor)
*/
@Override
public <T> ValueMonitor<T> registerValueMonitor(final MonitorName monitorName, final ValueMonitor<T> valueMonitor) {
return valueMonitor;
}
/**
* @see MonitorRegistry#newCounterMonitor(MonitorName)
*/
@Override
public CounterMonitor newCounterMonitor(final MonitorName monitorName) {
return CounterMonitor.NOOP;
}
private NoopMonitorRegistry() {
// Singleton
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor;
/**
* <p>
* A monitor that tracks a value's distribution. The value to track is
* represented by a {@code long}.
* </p>
* <p>
* <strong>DISCLAIMER</strong> This interface is heavily based on <a
* href="http://metrics.codahale.com/">Yammer's</a>
* {@link com.yammer.metrics.core.Histogram Histogram}.
* </p>
*/
public interface ValueDistributionMonitor {
/**
* Null object.
*/
ValueDistributionMonitor NOOP = new ValueDistributionMonitor() {
@Override
public void update(final long value) {
}
@Override
public void reset() {
}
};
/**
* Clear this monitor, resetting it to its base state.
*/
void reset();
/**
* Record {@code value}.
*/
void update(long value);
}

View File

@ -1,36 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor;
/**
* <p>
* A monitor that tracks a datum's value. The datum to track may be of arbitrary
* type.
* </p>
* <p>
* <strong>DISCLAIMER</strong> This interface is heavily based on <a
* href="http://metrics.codahale.com/">Yammer's</a>
* {@link com.yammer.metrics.core.Gauge Gauge}.
* </p>
*/
public interface ValueMonitor<T> {
/**
* Return our monitored datum's current value.
* @return Our monitored datum's current value
*/
T currentValue();
}

View File

@ -1,165 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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.
*/
/**
* <h2>Monitoring support in Netty</h2>
* <p>
* <h3>Introduction</h3> <br/>
* In this package, Netty provides a small framework for gathering statistics -
* simple counters, gauges, histograms - on how various Netty components
* perform. Note that this package focuses on <em>gathering</em> measurements.
* The task of actually <em>aggregating</em> those measurements into meaningful
* statistics is left to pluggable {@link io.netty.monitor.spi.MonitorProvider
* MonitorProviders}.
* </p>
* <p>
* <h3>Supported Monitors</h3> <br/>
* In its current incarnation, Netty's monitoring framework supports
* <ul>
* <li>
* {@link io.netty.monitor.CounterMonitor CounterMonitors} - increment and
* decrement a {@code long} value, e.g. <em>total number of bytes received on a
* {@link io.netty.channel.Channel Channel}</em>;</li>
* <li>
* {@link io.netty.monitor.ValueMonitor ValueMonitors} - record an arbitrary
* datum's current value, e.g. <em>overall number of
* {@link io.netty.channel.Channel Channels}</em>;</li>
* <li>
* {@link io.netty.monitor.ValueDistributionMonitor
* ValueDistributionMonitors} - track a value's distribution, e.g.
* <em>size in bytes of incoming PDUs</em>;</li>
* <li>
* {@link io.netty.monitor.EventRateMonitor EventRateMonitors} - track the
* rate which an event occurs at, e.g. <em>incoming PDUs per second</em>.</li>
* </ul>
* </p>
* <p>
* <h3>Netty resources providing monitoring support</h3> <br/>
* As of today, the following Netty resources offer monitoring support out of
* the box:
* <ul>
* <li>
* {@link io.netty.util.HashedWheelTimer HashedWheelTimer}
* <ul>
* <li>track distribution of deviation between scheduled and actual
* {@link io.netty.util.Timeout Timeout} execution time, i.e. how accurate
* {@code HashedWheelTimer} is;</li>
* <li>track number of {@link io.netty.util.Timeout Timeout}s executed per
* second, i.e. {@code HashedWheelTimer}'s throughput.</li>
* </ul>
* </li>
* </ul>
* This list is expected to expand over time.
* </p>
* <p>
* <h3>Design</h3> <br/>
* As a rule, Netty refrains from introducing dependencies on third-party
* libraries as much as possible. When designing its monitoring support we
* therefore faced the choice between either implementing our own fully-fledged
* metrics subsystem, capable of efficiently computing histograms and related
* statistics, or to provide an abstraction layer over third-party libraries.
* Given (a) that writing an <em>efficient</em> - especially in terms of memory
* consumption - statistics library is a non-trivial task and (b) that many
* organizations standardize on a specific statistics library, integrating it
* into their tool chain, we chose the latter option. Essentially, arbitrary
* statistics libraries may be <em>plugged in</em>.
* </p>
* <p>
* To that end, Netty's monitoring subsystem defines an
* {@link io.netty.monitor.spi <em>SPI</em>} - <strong>S</strong>ervice
* <strong>P</strong>rovider <strong>I</strong>nterface - that needs to be
* implemented by each concrete statistics provider. Netty ships with a
* {@link io.netty.monitor.yammer default implementation} based on the excellent
* <a href="http://metrics.codahale.com">Yammer Metrics</a> library. Central to
* this <em>SPI</em> is the interface
* {@link io.netty.monitor.spi.MonitorRegistryFactory MonitorRegistryFactory},
* an implementation of which has to be provided by each metrics provider. It is
* responsible for creating a {@link io.netty.monitor.MonitorRegistry
* MonitorRegistry}, your entry point into Netty's monitoring support.
* </p>
* <p>
* <h3>Usage</h3> <br/>
* When utilizing Netty's monitoring support, you need to obtain a reference to
* a {@link io.netty.monitor.MonitorRegistry MonitorRegistry}. It is through
* this that you - either directly or, in the case of e.g.
* {@link io.netty.util.HashedWheelTimer HashedWheelTimer}, indirectly - create
* one or several of the supported monitors, e.g.
* {@link io.netty.monitor.ValueMonitor ValueMonitor}.
* </p>
* <p>
* So how do you obtain a reference to a {@code MonitorRegistry}? In one of two
* ways:
* </p>
* <p>
* <h4>1. Using Java's Service Loader support</h4> <br/>
* This approach works whenever our desired monitoring provider registers its
* {@link io.netty.montior.spi.MonitorRegistryFactory MonitorRegistryFactory}
* implementation in a file called
* {@code META-INF/services/io.netty.monitor.spi.MonitorRegistryFactory} located
* on the classpath, typically within a jar containing the implementation
* proper. In this case Java 6's {@link java.util.ServiceLoader ServiceLoader}
* will be able to instantiate that {@code MonitorRegistryFactory}, which in
* turn creates your {@code MonitorRegistry}. It goes without saying that
* Netty's {@code Yammer}-based default monitoring provider supports this
* approach.
* </p>
* <p>
* To ease this process Netty provides
* {@link io.netty.monitor.MonitorRegistries MonitorRegistries}, a convenience
* class that locates all {@code MonitorRegistryFactories} on the classpath and
* which may be asked for a {@code MonitorRegistry}. In the standard case where
* only one such provider exists, this amounts to:
*
* <pre>
* final MonitorRegistry myMonitorRegistry =
* MonitorRegistries.instance().{@link io.netty.monitor.MonitorRegistries#unique() unique()};
* final {@link io.netty.monitor.ValueMonitor ValueMonitor} overallNumberOfChannels =
* myMonitorRegistry.newValueDistributionMonitor(monitorName);
* ...
* </pre>
*
* This approach may be the most easy to use. As a downside, you relinquish
* control over how to instantiate your {@code MonitorRegistry}. Some use cases
* may not be amenable to this approach.
* </p>
* <p>
* <h4>2. Directly instantiating a {@code MonitorRegistry}</h4> <br/>
* Of course, nothing keeps you from directly instantiating your desired
* {@code MonitorRegistry}, and this may well be the most flexible approach:
*
* <pre>
* final MyMetricsProvider myMetricsProvider = new MyMetricsProvider();
* final MonitorRegistry myMonitorRegistry = new MyGrandMonitorRegistry(myMetricsProvider);
* final {@link io.netty.monitor.ValueMonitor ValueMonitor} overallNumberOfChannels =
* myMonitorRegistry.newValueDistributionMonitor(monitorName);
* ...
* </pre>
*
* Obviously, instantiating your {@code MonitorRegistry} may thus be delegated
* to your DI-container of choice, i.e. <a
* href="http://www.springsource.org/spring-framework">Spring</a>, <a
* href="http://code.google.com/p/google-guice/">Guice</a> or <a
* href="http://seamframework.org/Weld">Weld</a>.
* </p>
* <p>
* <strong>DISCLAIMER</strong> It should be noted that Netty's monitoring support
* was heavily inspired by <a href="http://codahale.com/">Coda Hale's</a>
* excellent <a href="http://metrics.codahale.com">Yammer Metrics</a> library.
* </p>
* @apiviz.hidden
*/
package io.netty.monitor;

View File

@ -1,112 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor.spi;
import java.io.Serializable;
/**
* <p>
* Simple value class that identifies a monitoring/metrics provider like e.g. <a
* href="">Yammer</a> by name.
* </p>
*/
public final class MonitorProvider implements Serializable, Comparable<MonitorProvider> {
private static final long serialVersionUID = -6549490566242173389L;
/**
* Create a new {@code MonitorProvider} instance having the supplied
* {@code name}.
* @param name The new {@code MonitorProvider}'s {@link #name() name}.
* @return A new {@code MonitorProvider} instance having the supplied
* {@code name}
*/
public static MonitorProvider named(final String name) {
return new MonitorProvider(name);
}
private final String name;
private MonitorProvider(final String name) {
if (name == null) {
throw new NullPointerException("name");
}
if (name.length() < 1) {
throw new IllegalArgumentException("Argument 'name' must not be blank");
}
this.name = name;
}
/**
* This {@code MonitorProvider}'s unique name.
* @return This {@code MonitorProvider}'s unique name
*/
public String name() {
return name;
}
/**
* @see Comparable#compareTo(Object)
*/
@Override
public int compareTo(final MonitorProvider o) {
return name.compareTo(o.name);
}
/**
* @see Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (name == null ? 0 : name.hashCode());
return result;
}
/**
* @see Object#equals(Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final MonitorProvider other = (MonitorProvider) obj;
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}
/**
* @see Object#toString()
*/
@Override
public String toString() {
return "MonitorProvider(" + name + ')';
}
}

View File

@ -1,40 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor.spi;
import io.netty.monitor.MonitorRegistry;
/**
* <p>
* A {@link MonitorProvider provider}-specific factory for
* {@link MonitorRegistry MonitorRegistries}.
* </p>
*/
public interface MonitorRegistryFactory {
/**
* This {@code MonitorRegistryFactory}'s {@link MonitorProvider provider}.
* @return This {@code MonitorRegistryFactory}'s {@link MonitorProvider
* provider}
*/
MonitorProvider provider();
/**
* Create a new {@link MonitorRegistry}.
* @return A new {@link MonitorRegistry}
*/
MonitorRegistry newMonitorRegistry();
}

View File

@ -1,26 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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.
*/
/**
* <p>
* Defines an <em>SPI</em> - <em>S</em>ervice <em>P</em>rovider <em>I</em>nterface - for
* {@link io.netty.monitor.spi.MonitorProvider MonitorProviders}.
* </p>
*
* @apiviz.hidden
*/
package io.netty.monitor.spi;

View File

@ -17,10 +17,6 @@ package io.netty.util;
import io.netty.logging.InternalLogger;
import io.netty.logging.InternalLoggerFactory;
import io.netty.monitor.EventRateMonitor;
import io.netty.monitor.MonitorName;
import io.netty.monitor.MonitorRegistry;
import io.netty.monitor.ValueDistributionMonitor;
import io.netty.util.internal.PlatformDependent;
import java.util.ArrayList;
@ -87,11 +83,6 @@ public class HashedWheelTimer implements Timer {
new ResourceLeakDetector<HashedWheelTimer>(
HashedWheelTimer.class, 1, Runtime.getRuntime().availableProcessors() * 4);
private static final MonitorName TIMEOUT_EXPIRATION_TIME_DEVIATION_MN = new MonitorName(HashedWheelTimer.class,
"timeout-expiration-time-deviation");
private static final MonitorName TIMEOUTS_PER_SECOND_MN = new MonitorName(HashedWheelTimer.class,
"timeouts-per-second");
private final ResourceLeak leak = leakDetector.open(this);
private final Worker worker = new Worker();
final Thread workerThread;
@ -104,10 +95,6 @@ public class HashedWheelTimer implements Timer {
final ReadWriteLock lock = new ReentrantReadWriteLock();
volatile int wheelCursor;
// Monitoring this instance
final ValueDistributionMonitor timeoutExpirationTimeDeviation;
final EventRateMonitor timeoutsPerSecond;
/**
* Creates a new timer with the default thread factory
* ({@link Executors#defaultThreadFactory()}), default tick duration, and
@ -189,81 +176,6 @@ public class HashedWheelTimer implements Timer {
public HashedWheelTimer(
ThreadFactory threadFactory,
long tickDuration, TimeUnit unit, int ticksPerWheel) {
this(threadFactory, tickDuration, unit, ticksPerWheel, MonitorRegistry.NOOP);
}
/**
* Creates a new timer with {@link io.netty.monitor monitoring support}
* enabled. The new timer instance will monitor
* <ul>
* <li>
* the distribution of deviation between scheduled and actual
* {@link Timeout timeout} execution, i.e. how accurate this timer is; and
* </li>
* <li>
* the rate of {@link Timeout timeout} executions per second.
* </li>
* </ul>
*
* @param threadFactory a {@link ThreadFactory} that creates a
* background {@link Thread} which is dedicated to
* {@link TimerTask} execution.
* @param tickDuration the duration between tick
* @param unit the time unit of the {@code tickDuration}
* @param ticksPerWheel the size of the wheel
* @param monitorRegistry the {@link MonitorRegistry} to use
* @throws NullPointerException
* if either of {@code threadFactory} and {@code unit}
* is {@code null}
* @throws IllegalArgumentException
* if either of {@code tickDuration} and {@code ticksPerWheel} is <= 0
*/
public HashedWheelTimer(ThreadFactory threadFactory, long tickDuration, TimeUnit unit, int ticksPerWheel,
MonitorRegistry monitorRegistry) {
this(threadFactory, tickDuration, unit, ticksPerWheel, monitorRegistry,
TIMEOUT_EXPIRATION_TIME_DEVIATION_MN, TIMEOUTS_PER_SECOND_MN);
}
/**
* Creates a new timer with {@link io.netty.monitor monitoring support}
* enabled. The new timer instance will monitor
* <ul>
* <li>
* the distribution of deviation between scheduled and actual
* {@link Timeout timeout} execution, i.e. how accurate this timer is; and
* </li>
* <li>
* the rate of {@link Timeout timeout} executions per second.
* </li>
* </ul>
*
* @param threadFactory a {@link ThreadFactory} that creates a
* background {@link Thread} which is dedicated to
* {@link TimerTask} execution.
* @param tickDuration the duration between tick
* @param unit the time unit of the {@code tickDuration}
* @param ticksPerWheel the size of the wheel
* @param monitorRegistry the {@link MonitorRegistry} to use
* @param timeoutExpirationTimeDeviationMonitorName
* the {@link MonitorName name} to use for the
* {@code Monitor} that tracks the distribution of
* deviation between scheduled and actual timeout
* execution
* @param timeoutsPerSecondMonitorName
* the {@link MonitorName name} to use for the
* {@code Monitor} that tracks the rate of timeout
* executions per second
* @throws NullPointerException
* if either of {@code threadFactory}, {@code unit},
* {@code monitorRegistry},
* {@code timeoutExpirationTimeDeviationMonitorName} and
* {@code timeoutsPerSecondMonitorName} is {@code null}
* @throws IllegalArgumentException
* if either of {@code tickDuration} and {@code ticksPerWheel} is <= 0
*/
public HashedWheelTimer(ThreadFactory threadFactory, long tickDuration, TimeUnit unit, int ticksPerWheel,
MonitorRegistry monitorRegistry, MonitorName timeoutExpirationTimeDeviationMonitorName,
MonitorName timeoutsPerSecondMonitorName) {
if (threadFactory == null) {
throw new NullPointerException("threadFactory");
@ -271,15 +183,6 @@ public class HashedWheelTimer implements Timer {
if (unit == null) {
throw new NullPointerException("unit");
}
if (monitorRegistry == null) {
throw new NullPointerException("monitorRegistry");
}
if (timeoutExpirationTimeDeviationMonitorName == null) {
throw new NullPointerException("timeoutExpirationTimeDeviationMonitorName");
}
if (timeoutsPerSecondMonitorName == null) {
throw new NullPointerException("timeoutsPerSecondMonitorName");
}
if (tickDuration <= 0) {
throw new IllegalArgumentException("tickDuration must be greater than 0: " + tickDuration);
}
@ -302,11 +205,6 @@ public class HashedWheelTimer implements Timer {
roundDuration = tickDuration * wheel.length;
workerThread = threadFactory.newThread(worker);
timeoutExpirationTimeDeviation =
monitorRegistry.newValueDistributionMonitor(timeoutExpirationTimeDeviationMonitorName);
timeoutsPerSecond =
monitorRegistry.newEventRateMonitor(timeoutsPerSecondMonitorName, TimeUnit.SECONDS);
}
@SuppressWarnings("unchecked")
@ -622,8 +520,6 @@ public class HashedWheelTimer implements Timer {
}
try {
timeoutsPerSecond.event();
timeoutExpirationTimeDeviation.update(System.currentTimeMillis() - deadline);
task.run(this);
} catch (Throwable t) {
if (logger.isWarnEnabled()) {

View File

@ -1,58 +0,0 @@
/*
* Copyright 2013 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor;
import io.netty.monitor.support.SampleMonitorRegistryFactory;
import org.junit.Test;
import static org.junit.Assert.*;
public class MonitorRegistriesTest {
@Test
public final void instanceShouldNotReturnNull() {
assertNotNull("instance() should NEVER return null",
MonitorRegistries.instance());
}
@Test
public final void instanceShouldAlwaysReturnTheSameInstance() {
final MonitorRegistries firstInstance = MonitorRegistries.instance();
final MonitorRegistries secondInstance = MonitorRegistries.instance();
assertSame("instance() should always return the same instance",
firstInstance, secondInstance);
}
@Test
public final void forProviderShouldReturnMonitorRegistryMatchingTheSuppliedProvider() {
final MonitorRegistries objectUnderTest = MonitorRegistries.instance();
final MonitorRegistry registry = MonitorRegistries.forProvider(SampleMonitorRegistryFactory.PROVIDER);
assertSame("forProvider(" + SampleMonitorRegistryFactory.PROVIDER
+ ") should return a MonitorRegistry by the supplied provider",
SampleMonitorRegistryFactory.SampleMonitorRegistry.class,
registry.getClass());
}
@Test
public final void uniqueShouldThrowIllegalStateExceptionIfMoreThanOneProviderIsRegistered() {
final MonitorRegistries objectUnderTest = MonitorRegistries.instance();
objectUnderTest.unique();
}
}

View File

@ -1,102 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor.support;
import io.netty.monitor.CounterMonitor;
import io.netty.monitor.EventRateMonitor;
import io.netty.monitor.MonitorName;
import io.netty.monitor.MonitorRegistry;
import io.netty.monitor.ValueDistributionMonitor;
import io.netty.monitor.ValueMonitor;
import io.netty.monitor.spi.MonitorProvider;
import io.netty.monitor.spi.MonitorRegistryFactory;
import java.util.concurrent.TimeUnit;
public class AnotherSampleMonitorRegistryFactory implements MonitorRegistryFactory {
public static final MonitorProvider PROVIDER = MonitorProvider.named("ANOTHER_SAMPLE");
@Override
public MonitorProvider provider() {
return PROVIDER;
}
@Override
public MonitorRegistry newMonitorRegistry() {
return new AnotherSampleMonitorRegistry();
}
public static final class AnotherSampleMonitorRegistry implements MonitorRegistry {
@Override
public ValueDistributionMonitor newValueDistributionMonitor(final MonitorName monitorName) {
return new ValueDistributionMonitor() {
@Override
public void update(final long value) {
}
@Override
public void reset() {
}
};
}
@Override
public EventRateMonitor newEventRateMonitor(final MonitorName monitorName, final TimeUnit rateUnit) {
return new EventRateMonitor() {
@Override
public void events(final long count) {
}
@Override
public void event() {
}
};
}
@Override
public <T> ValueMonitor<T> registerValueMonitor(MonitorName monitorName, ValueMonitor<T> valueMonitor) {
return valueMonitor;
}
@Override
public CounterMonitor newCounterMonitor(MonitorName monitorName) {
return new CounterMonitor() {
@Override
public void reset() {
}
@Override
public void increment(long delta) {
}
@Override
public void increment() {
}
@Override
public void decrement(long delta) {
}
@Override
public void decrement() {
}
};
}
}
}

View File

@ -1,102 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor.support;
import io.netty.monitor.CounterMonitor;
import io.netty.monitor.EventRateMonitor;
import io.netty.monitor.MonitorName;
import io.netty.monitor.MonitorRegistry;
import io.netty.monitor.ValueDistributionMonitor;
import io.netty.monitor.ValueMonitor;
import io.netty.monitor.spi.MonitorProvider;
import io.netty.monitor.spi.MonitorRegistryFactory;
import java.util.concurrent.TimeUnit;
public class SampleMonitorRegistryFactory implements MonitorRegistryFactory {
public static final MonitorProvider PROVIDER = MonitorProvider.named("SAMPLE");
@Override
public MonitorProvider provider() {
return PROVIDER;
}
@Override
public MonitorRegistry newMonitorRegistry() {
return new SampleMonitorRegistry();
}
public static final class SampleMonitorRegistry implements MonitorRegistry {
@Override
public ValueDistributionMonitor newValueDistributionMonitor(final MonitorName monitorName) {
return new ValueDistributionMonitor() {
@Override
public void update(final long value) {
}
@Override
public void reset() {
}
};
}
@Override
public EventRateMonitor newEventRateMonitor(final MonitorName monitorName, final TimeUnit rateUnit) {
return new EventRateMonitor() {
@Override
public void events(final long count) {
}
@Override
public void event() {
}
};
}
@Override
public <T> ValueMonitor<T> registerValueMonitor(MonitorName monitorName, ValueMonitor<T> valueMonitor) {
return valueMonitor;
}
@Override
public CounterMonitor newCounterMonitor(MonitorName monitorName) {
return new CounterMonitor() {
@Override
public void reset() {
}
@Override
public void increment(long delta) {
}
@Override
public void increment() {
}
@Override
public void decrement(long delta) {
}
@Override
public void decrement() {
}
};
}
}
}

View File

@ -1,145 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.util;
import io.netty.monitor.CounterMonitor;
import io.netty.monitor.EventRateMonitor;
import io.netty.monitor.MonitorName;
import io.netty.monitor.MonitorRegistry;
import io.netty.monitor.ValueDistributionMonitor;
import io.netty.monitor.ValueMonitor;
import org.junit.Test;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.*;
public class HashedWheelTimerMonitorTest {
@Test
public final void shouldCallValueDistributionMonitorWhenTimeoutExpires() throws InterruptedException {
final CountDownLatch eventDistributionCalled = new CountDownLatch(1);
final ValueDistributionMonitor eventDistributionRecorder = new ValueDistributionMonitor() {
@Override
public void update(final long value) {
eventDistributionCalled.countDown();
}
@Override
public void reset() {
}
};
final RecordingMonitorRegistry recordingMonitorRegistry = new RecordingMonitorRegistry(
eventDistributionRecorder, EventRateMonitor.NOOP);
final HashedWheelTimer objectUnderTest = new HashedWheelTimer(Executors.defaultThreadFactory(), 100,
TimeUnit.MILLISECONDS, 512, recordingMonitorRegistry);
objectUnderTest.newTimeout(new TimerTask() {
@Override
public void run(final Timeout timeout) throws Exception {
}
}, 1, TimeUnit.MILLISECONDS);
assertTrue("HashedWheelTimer should have called ValueDistributionMonitor when Timeout expired",
eventDistributionCalled.await(200, TimeUnit.MILLISECONDS));
}
private static class RecordingMonitorRegistry implements MonitorRegistry {
private final ValueDistributionMonitor eventDistributionMonitor;
private final EventRateMonitor eventRateMonitor;
RecordingMonitorRegistry(final ValueDistributionMonitor eventDistributionMonitor,
final EventRateMonitor eventRateMonitor) {
this.eventDistributionMonitor = eventDistributionMonitor;
this.eventRateMonitor = eventRateMonitor;
}
@Override
public ValueDistributionMonitor newValueDistributionMonitor(final MonitorName monitorName) {
return eventDistributionMonitor;
}
@Override
public EventRateMonitor newEventRateMonitor(final MonitorName monitorName, final TimeUnit rateUnit) {
return eventRateMonitor;
}
@Override
public <T> ValueMonitor<T> registerValueMonitor(MonitorName monitorName, ValueMonitor<T> valueMonitor) {
return valueMonitor;
}
@Override
public CounterMonitor newCounterMonitor(MonitorName monitorName) {
return new CounterMonitor() {
@Override
public void reset() {
}
@Override
public void increment(long delta) {
}
@Override
public void increment() {
}
@Override
public void decrement(long delta) {
}
@Override
public void decrement() {
}
};
}
}
@Test
public final void shouldCallEventRateMonitorWhenTimeoutExpires() throws InterruptedException {
final CountDownLatch eventRateCalled = new CountDownLatch(1);
final EventRateMonitor eventRateRecorder = new EventRateMonitor() {
@Override
public void events(final long count) {
}
@Override
public void event() {
eventRateCalled.countDown();
}
};
final RecordingMonitorRegistry recordingMonitorRegistry = new RecordingMonitorRegistry(
ValueDistributionMonitor.NOOP, eventRateRecorder);
final HashedWheelTimer objectUnderTest = new HashedWheelTimer(Executors.defaultThreadFactory(), 100,
TimeUnit.MILLISECONDS, 512, recordingMonitorRegistry);
objectUnderTest.newTimeout(new TimerTask() {
@Override
public void run(final Timeout timeout) throws Exception {
}
}, 1, TimeUnit.MILLISECONDS);
assertTrue("HashedWheelTimer should have called EventRateMonitor when Timeout expired",
eventRateCalled.await(200, TimeUnit.MILLISECONDS));
}
}

View File

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2012 The Netty Project
~
~ The Netty Project licenses this file to you 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.netty</groupId>
<artifactId>netty-parent</artifactId>
<version>4.0.0.Beta1-SNAPSHOT</version>
</parent>
<artifactId>netty-metrics-yammer</artifactId>
<packaging>jar</packaging>
<name>Netty/Yammer Metrics Provider</name>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yammer.metrics</groupId>
<artifactId>metrics-core</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,36 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor.yammer;
import com.yammer.metrics.core.MetricName;
import io.netty.monitor.MonitorName;
/**
* <p>
* Static helper methods.
* </p>
*/
final class Utils {
static MetricName toMetricName(final MonitorName monitorName) {
return new MetricName(monitorName.group(), monitorName.type(), monitorName.name(),
monitorName.instance());
}
private Utils() {
// Unused
}
}

View File

@ -1,67 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor.yammer;
import com.yammer.metrics.core.Counter;
import io.netty.monitor.CounterMonitor;
/**
* <p>
* An {@link CounterMonitor} that delegates to a <a
* href="http://metrics.codahale.com/">Yammer</a> {@link Counter}.
* </p>
*/
class YammerCounterMonitor implements CounterMonitor {
private final Counter delegate;
YammerCounterMonitor(final Counter delegate) {
if (delegate == null) {
throw new NullPointerException("delegate");
}
this.delegate = delegate;
}
@Override
public void increment() {
delegate.inc();
}
@Override
public void increment(final long delta) {
delegate.inc(delta);
}
@Override
public void decrement() {
delegate.dec();
}
@Override
public void decrement(final long delta) {
delegate.dec(delta);
}
@Override
public void reset() {
delegate.clear();
}
@Override
public String toString() {
return "YammerCounterMonitor(delegate=" + delegate + ')';
}
}

View File

@ -1,58 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor.yammer;
import com.yammer.metrics.core.Meter;
import io.netty.monitor.EventRateMonitor;
/**
* <p>
* An {@link EventRateMonitor} that delegates to a <a
* href="http://metrics.codahale.com/">Yammer</a> {@link Meter}.
* </p>
*/
class YammerEventRateMonitor implements EventRateMonitor {
private final Meter delegate;
YammerEventRateMonitor(final Meter delegate) {
if (delegate == null) {
throw new NullPointerException("delegate");
}
this.delegate = delegate;
}
/**
* @see Meter#mark()
*/
@Override
public void event() {
delegate.mark();
}
/**
* @see Meter#mark(long)
*/
@Override
public void events(final long count) {
delegate.mark(count);
}
@Override
public String toString() {
return "YammerEventRateMonitor(delegate=" + delegate + ')';
}
}

View File

@ -1,121 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor.yammer;
import com.yammer.metrics.Metrics;
import com.yammer.metrics.core.Counter;
import com.yammer.metrics.core.Gauge;
import com.yammer.metrics.core.Histogram;
import com.yammer.metrics.core.Meter;
import com.yammer.metrics.core.MetricsRegistry;
import io.netty.monitor.CounterMonitor;
import io.netty.monitor.EventRateMonitor;
import io.netty.monitor.MonitorName;
import io.netty.monitor.MonitorRegistry;
import io.netty.monitor.ValueDistributionMonitor;
import io.netty.monitor.ValueMonitor;
import java.util.concurrent.TimeUnit;
/**
* <p>
* A {@link MonitorRegistry} that delegates to a <a
* href="http://metrics.codahale.com/">Yammer</a> {@link MetricsRegistry}.
* </p>
*/
public final class YammerMonitorRegistry implements MonitorRegistry {
private final MetricsRegistry delegate;
/**
* Constructs a {@code YammerMonitorRegistry} that delegates to
* {@code Yammer}'s {@link Metrics#defaultRegistry() default registry}.
*/
public YammerMonitorRegistry() {
this(Metrics.defaultRegistry());
}
/**
* Constructs a {@code YammerMonitorRegistry} that delegates to the supplied
* {@code Yammer} {@link MetricsRegistry delegate}.
* @param delegate The {@code Yammer} {@link MetricsRegistry} to delegate to
*/
public YammerMonitorRegistry(final MetricsRegistry delegate) {
if (delegate == null) {
throw new NullPointerException("delegate");
}
this.delegate = delegate;
}
/**
* Create a new {@link ValueDistributionMonitor} that is backed by a
* {@code Yammer} {@link Histogram}.
* @see MonitorRegistry#newValueDistributionMonitor(MonitorName)
*/
@Override
public ValueDistributionMonitor newValueDistributionMonitor(final MonitorName monitorName) {
final Histogram histogram = delegate.newHistogram(Utils.toMetricName(monitorName), true);
return new YammerValueDistributionMonitor(histogram);
}
/**
* Create a new {@link EventRateMonitor} that is backed by a {@code Yammer}
* {@link Meter}.
* @see MonitorRegistry#newEventRateMonitor(MonitorName,
* TimeUnit)
*/
@Override
public EventRateMonitor newEventRateMonitor(final MonitorName monitorName, final TimeUnit rateUnit) {
final Meter meter = delegate.newMeter(Utils.toMetricName(monitorName), monitorName.name(), rateUnit);
return new YammerEventRateMonitor(meter);
}
/**
* Register the supplied {@link ValueMonitor valueMonitor}, using it
* internally to create a {@code Yammer} {@link Gauge}.
* @see MonitorRegistry#registerValueMonitor(MonitorName,
* ValueMonitor)
*/
@Override
public <T> ValueMonitor<T> registerValueMonitor(final MonitorName monitorName, final ValueMonitor<T> valueMonitor) {
delegate.newGauge(Utils.toMetricName(monitorName), new Gauge<T>() {
@Override
public T value() {
return valueMonitor.currentValue();
}
});
return valueMonitor;
}
/**
* Create a new {@link CounterMonitor} that is backed by a {@code Yammer}
* {@link Counter}.
* @see MonitorRegistry#newCounterMonitor(MonitorName)
*/
@Override
public CounterMonitor newCounterMonitor(MonitorName monitorName) {
final Counter counter = delegate.newCounter(Utils.toMetricName(monitorName));
return new YammerCounterMonitor(counter);
}
/**
* @see Object#toString()
*/
@Override
public String toString() {
return "YammerMonitorRegistry(delegate=" + delegate + ')';
}
}

View File

@ -1,28 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor.yammer;
import io.netty.monitor.spi.MonitorProvider;
public final class YammerProvider {
public static final MonitorProvider PROVIDER = MonitorProvider
.named("YAMMER");
private YammerProvider() {
// Unused
}
}

View File

@ -1,52 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor.yammer;
import com.yammer.metrics.core.Histogram;
import io.netty.monitor.ValueDistributionMonitor;
/**
* <p>
* An {@link ValueDistributionMonitor} that delegates to a <a
* href="http://metrics.codahale.com/">Yammer</a> {@link Histogram}.
* </p>
*/
final class YammerValueDistributionMonitor implements ValueDistributionMonitor {
private final Histogram delegate;
YammerValueDistributionMonitor(final Histogram delegate) {
if (delegate == null) {
throw new NullPointerException("delegate");
}
this.delegate = delegate;
}
@Override
public void reset() {
delegate.clear();
}
@Override
public void update(final long value) {
delegate.update(value);
}
@Override
public String toString() {
return "YammerEventDistributionMonitor(delegate=" + delegate + ')';
}
}

View File

@ -1,26 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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.
*/
/**
* <p>
* Provides {@link io.netty.monitor Monitor} implementations backed by
* <a href="http://metrics.codahale.com/">Yammer Metrics</a>.
* </p>
*
* @apiviz.hidden
*/
package io.netty.monitor.yammer;

View File

@ -1,61 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.monitor.yammer.spi;
import com.yammer.metrics.Metrics;
import com.yammer.metrics.core.MetricsRegistry;
import io.netty.monitor.MonitorRegistry;
import io.netty.monitor.spi.MonitorProvider;
import io.netty.monitor.spi.MonitorRegistryFactory;
import io.netty.monitor.yammer.YammerMonitorRegistry;
import io.netty.monitor.yammer.YammerProvider;
/**
* <p>
* A {@link MonitorRegistryFactory} that produces {@link YammerMonitorRegistry
* YammerMonitorRegistries}.
* </p>
*/
public class YammerMonitorRegistryFactory implements MonitorRegistryFactory {
private final MetricsRegistry metricsRegistry;
public YammerMonitorRegistryFactory() {
this(Metrics.defaultRegistry());
}
public YammerMonitorRegistryFactory(final MetricsRegistry metricsRegistry) {
if (metricsRegistry == null) {
throw new NullPointerException("metricsRegistry");
}
this.metricsRegistry = metricsRegistry;
}
@Override
public MonitorProvider provider() {
return YammerProvider.PROVIDER;
}
@Override
public MonitorRegistry newMonitorRegistry() {
return new YammerMonitorRegistry(metricsRegistry);
}
@Override
public String toString() {
return "YammerMonitorRegistryFactory(metricsRegistry=" + metricsRegistry + ')';
}
}

View File

@ -1,26 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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.
*/
/**
* <p>
* Provides a {@link io.netty.monitor.spi.MonitorRegistryFactory MonitorRegistryFactory}
* that produces {@link YammerMonitorRegistry YammerMonitorRegistries}.
* </p>
*
* @apiviz.hidden
*/
package io.netty.monitor.yammer.spi;

View File

@ -1 +0,0 @@
io.netty.monitor.yammer.spi.YammerMonitorRegistryFactory

View File

@ -82,7 +82,6 @@
<module>transport-sctp</module>
<module>transport-udt</module>
<module>handler</module>
<module>metrics-yammer</module>
<module>example</module>
<module>testsuite</module>
<module>all</module>

View File

@ -22,9 +22,6 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import io.netty.monitor.CounterMonitor;
import io.netty.monitor.MonitorName;
import io.netty.monitor.MonitorRegistries;
/**
* Abstract base class for {@link EventExecutorGroup} implementations that handles their tasks with multiple threads at
* the same time.
@ -33,8 +30,6 @@ public abstract class MultithreadEventExecutorGroup implements EventExecutorGrou
public static final int DEFAULT_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2;
private static final AtomicInteger poolId = new AtomicInteger();
private final CounterMonitor threadCounter = MonitorRegistries.instance()
.unique().newCounterMonitor(new MonitorName(getClass(), "total-threads"));
final ChannelTaskScheduler scheduler;
private final EventExecutor[] children;
@ -62,7 +57,6 @@ public abstract class MultithreadEventExecutorGroup implements EventExecutorGrou
if (threadFactory == null) {
threadFactory = new DefaultThreadFactory();
}
threadCounter.increment(nThreads);
scheduler = new ChannelTaskScheduler(threadFactory);

View File

@ -15,10 +15,6 @@
*/
package io.netty.channel;
import io.netty.monitor.CounterMonitor;
import io.netty.monitor.MonitorName;
import io.netty.monitor.MonitorRegistries;
import java.util.concurrent.ThreadFactory;
/**
@ -26,8 +22,6 @@ import java.util.concurrent.ThreadFactory;
*
*/
public abstract class SingleThreadEventLoop extends SingleThreadEventExecutor implements EventLoop {
protected final CounterMonitor channelCounter = MonitorRegistries.instance()
.unique().newCounterMonitor(new MonitorName(getClass(), "total-channels-registered"));
/**
*
@ -75,7 +69,6 @@ public abstract class SingleThreadEventLoop extends SingleThreadEventExecutor im
});
}
channelCounter.increment();
return promise;
}
}

View File

@ -24,9 +24,6 @@ import io.netty.channel.SingleThreadEventLoop;
import io.netty.channel.socket.nio.AbstractNioChannel.NioUnsafe;
import io.netty.logging.InternalLogger;
import io.netty.logging.InternalLoggerFactory;
import io.netty.monitor.CounterMonitor;
import io.netty.monitor.MonitorName;
import io.netty.monitor.MonitorRegistries;
import java.io.IOException;
import java.nio.channels.CancelledKeyException;
@ -42,7 +39,6 @@ import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@ -51,8 +47,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
*
*/
public final class NioEventLoop extends SingleThreadEventLoop {
private final CounterMonitor selectorWokeUpBeforeTime = MonitorRegistries.instance()
.unique().newCounterMonitor(new MonitorName(getClass(), "Selector.select-early-wake-up"));
/**
* Internal Netty logger.
@ -239,13 +233,6 @@ public final class NioEventLoop extends SingleThreadEventLoop {
long beforeSelect = System.nanoTime();
int selected = SelectorUtil.select(selector);
//measure how long select took & convert nano time to milliseconds
long totalSelectTime = System.nanoTime() - beforeSelect;
long selectTime = TimeUnit.MILLISECONDS.convert(totalSelectTime, TimeUnit.NANOSECONDS);
if (selectTime < SelectorUtil.SELECT_TIMEOUT) {
selectorWokeUpBeforeTime.increment();
}
if (SelectorUtil.EPOLL_BUG_WORKAROUND) {
if (selected == 0) {
long timeBlocked = System.nanoTime() - beforeSelect;