Merge pull request #682 from obergner/issue_65
Add SPI to monitor netty. Also add stats for HashedWheelTimer to show how it can be used. See #65
This commit is contained in:
commit
e5319b6600
14
all/pom.xml
14
all/pom.xml
@ -54,7 +54,7 @@
|
|||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- The example depends on all modules either directly or transitively -->
|
<!-- The example depends on (almost) all modules either directly or transitively -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>netty-example</artifactId>
|
<artifactId>netty-example</artifactId>
|
||||||
@ -62,6 +62,14 @@
|
|||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- The only module netty-example does NOT depend on -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-metrics-yammer</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
<!-- Add optional dependencies explicitly to avoid Javadoc warnings and errors. -->
|
<!-- Add optional dependencies explicitly to avoid Javadoc warnings and errors. -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.protobuf</groupId>
|
<groupId>com.google.protobuf</groupId>
|
||||||
@ -296,12 +304,14 @@
|
|||||||
-link http://www.slf4j.org/apidocs/
|
-link http://www.slf4j.org/apidocs/
|
||||||
-link http://commons.apache.org/logging/commons-logging-1.1.1/apidocs/
|
-link http://commons.apache.org/logging/commons-logging-1.1.1/apidocs/
|
||||||
-link http://logging.apache.org/log4j/1.2/apidocs/
|
-link http://logging.apache.org/log4j/1.2/apidocs/
|
||||||
|
-link http://metrics.codahale.com/maven/apidocs/
|
||||||
|
|
||||||
-group "Low-level data representation" io.netty.buffer*
|
-group "Low-level data representation" io.netty.buffer*
|
||||||
-group "Central interface for all I/O operations" io.netty.channel*
|
-group "Central interface for all I/O operations" io.netty.channel*
|
||||||
-group "Client & Server bootstrapping utilities" io.netty.bootstrap*
|
-group "Client & Server bootstrapping utilities" io.netty.bootstrap*
|
||||||
-group "Reusable I/O event interceptors" io.netty.handler*
|
-group "Reusable I/O event interceptors" io.netty.handler*
|
||||||
-group "Miscellaneous" io.netty.logging*:io.netty.util*
|
-group "Miscellaneous" io.netty.logging*:io.netty.util*:io.netty.monitor:io.netty.monitor.spi
|
||||||
|
-group "Yammer monitoring support" io.netty.monitor.yammer*
|
||||||
|
|
||||||
-sourceclasspath ${project.build.outputDirectory}
|
-sourceclasspath ${project.build.outputDirectory}
|
||||||
-nopackagediagram
|
-nopackagediagram
|
||||||
|
82
common/src/main/java/io/netty/monitor/CounterMonitor.java
Normal file
82
common/src/main/java/io/netty/monitor/CounterMonitor.java
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* 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 inc(long delta) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inc() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decr(long delta) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decr() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment this counter by 1.
|
||||||
|
*/
|
||||||
|
void inc();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment this counter by the supplied {@code delta}.
|
||||||
|
* @param delta The delta to apply
|
||||||
|
*/
|
||||||
|
void inc(long delta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement this counter by 1.
|
||||||
|
*/
|
||||||
|
void decr();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement this counter by the supplied {@code delta}.
|
||||||
|
* @param delta The delta to apply
|
||||||
|
*/
|
||||||
|
void decr(long delta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset this counter to its initial state.
|
||||||
|
*/
|
||||||
|
void reset();
|
||||||
|
}
|
54
common/src/main/java/io/netty/monitor/EventRateMonitor.java
Normal file
54
common/src/main/java/io/netty/monitor/EventRateMonitor.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
* @param count
|
||||||
|
*/
|
||||||
|
void events(long count);
|
||||||
|
}
|
257
common/src/main/java/io/netty/monitor/MonitorName.java
Normal file
257
common/src/main/java/io/netty/monitor/MonitorName.java
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
/*
|
||||||
|
* 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 #getGroup()
|
||||||
|
* group}, the {@code monitoredClass}'s {@code simple name} as its
|
||||||
|
* {@link #getType()} and the supplied {@code name} as its
|
||||||
|
* {@link #getName() 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 #getName() 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 #getGroup()
|
||||||
|
* group}, the {@code monitoredClass}'s {@code simple name} as its
|
||||||
|
* {@link #getType()}, the supplied {@code name} as its {@link #getName()
|
||||||
|
* name} and the supplied {@code instance} as its {@link #getInstance()
|
||||||
|
* 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 #getName() name}
|
||||||
|
* @param instance Our new {@code MonitorName}'s {@link #getInstance()
|
||||||
|
* 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 #getGroup() group}
|
||||||
|
* @param type Our new {@code MonitorName}'s {@link #getType() type}
|
||||||
|
* @param name Our new {@code MonitorName}'s {@link #getName() 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 #getGroup() group}
|
||||||
|
* @param type Our new {@code MonitorName}'s {@link #getType() type}
|
||||||
|
* @param name Our new {@code MonitorName}'s {@link #getName() name}
|
||||||
|
* @param instance Our new {@code MonitorName}'s {@link #getInstance()
|
||||||
|
* 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 #getInstance() 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 #getInstance() 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(this.group, this.type, this.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 getGroup() {
|
||||||
|
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 getType() {
|
||||||
|
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 getName() {
|
||||||
|
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 getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.lang.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 java.lang.Object#equals(java.lang.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 java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.instance != null ? "Monitor(" + group + "/" + type + "/" + name + "/" + instance + ")" : "Monitor("
|
||||||
|
+ group + "/" + type + "/" + name + ")";
|
||||||
|
}
|
||||||
|
}
|
148
common/src/main/java/io/netty/monitor/MonitorRegistries.java
Normal file
148
common/src/main/java/io/netty/monitor/MonitorRegistries.java
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* 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.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> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return <em>the</em> singleton {@code MonitorRegistries} instance.
|
||||||
|
* @return <em>The</em> singleton {@code MonitorRegistries} instance
|
||||||
|
*/
|
||||||
|
public static MonitorRegistries instance() {
|
||||||
|
return Holder.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class Holder {
|
||||||
|
private static final 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 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> uniquely determined
|
||||||
|
* {@link MonitorRegistry} implementation. This method will work in the
|
||||||
|
* standard situation where exactly one {@link MonitorRegistryFactory} is
|
||||||
|
* registered in
|
||||||
|
* {@code META-INF/services/io.netty.monitor.spi.MonitorRegistryFactory}.
|
||||||
|
* Otherwise, if either none or more than one such provider is found on the
|
||||||
|
* classpath, it will throw an {@code IllegalStateException}.
|
||||||
|
* </p>
|
||||||
|
* @return <em>The</em> uniquely determined {@link MonitorRegistry}
|
||||||
|
* implementation
|
||||||
|
* @throws IllegalStateException If either none or more that one
|
||||||
|
* {@link MonitorRegistryFactor} provider was found on the
|
||||||
|
* classpath
|
||||||
|
*/
|
||||||
|
public MonitorRegistry unique() {
|
||||||
|
final Iterator<MonitorRegistry> registries = iterator();
|
||||||
|
if (!registries.hasNext()) {
|
||||||
|
throw new IllegalStateException("Could not find any MonitorRegistryFactories on the classpath - "
|
||||||
|
+ "implementations need to be registered in META-INF/services/"
|
||||||
|
+ MonitorRegistryFactory.class.getName());
|
||||||
|
}
|
||||||
|
final MonitorRegistry candidate = registries.next();
|
||||||
|
if (registries.hasNext()) {
|
||||||
|
throw new IllegalStateException("Found more than one MonitorRegistryFactory on the classpath - "
|
||||||
|
+ "check if there is more than one implementation registered in META-INF/services/"
|
||||||
|
+ MonitorRegistryFactory.class.getName());
|
||||||
|
}
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.lang.Iterable#iterator()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Iterator<MonitorRegistry> iterator() {
|
||||||
|
return new MonitorRegistryIterator(FACTORIES.iterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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 this.factories.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MonitorRegistry next() {
|
||||||
|
return this.factories.next().newMonitorRegistry();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException("Removing a MonitorRegistry is not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private MonitorRegistries() {
|
||||||
|
// Singleton
|
||||||
|
}
|
||||||
|
}
|
73
common/src/main/java/io/netty/monitor/MonitorRegistry.java
Normal file
73
common/src/main/java/io/netty/monitor/MonitorRegistry.java
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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 io.netty.monitor.MonitorRegistry#newValueDistributionMonitor(io.netty.monitor.MonitorName)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ValueDistributionMonitor newValueDistributionMonitor(final MonitorName monitorName) {
|
||||||
|
return ValueDistributionMonitor.NOOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.MonitorRegistry#newEventRateMonitor(io.netty.monitor.MonitorName,
|
||||||
|
* java.util.concurrent.TimeUnit)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public EventRateMonitor newEventRateMonitor(final MonitorName monitorName, final TimeUnit rateUnit) {
|
||||||
|
return EventRateMonitor.NOOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.MonitorRegistry#registerValueMonitor(io.netty.monitor.MonitorName,
|
||||||
|
* io.netty.monitor.ValueMonitor)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> ValueMonitor<T> registerValueMonitor(final MonitorName monitorName, final ValueMonitor<T> valueMonitor) {
|
||||||
|
return valueMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.MonitorRegistry#newCounterMonitor(io.netty.monitor.MonitorName)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CounterMonitor newCounterMonitor(final MonitorName monitorName) {
|
||||||
|
return CounterMonitor.NOOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NoopMonitorRegistry() {
|
||||||
|
// Singleton
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* 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}.
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
void update(long value);
|
||||||
|
}
|
36
common/src/main/java/io/netty/monitor/ValueMonitor.java
Normal file
36
common/src/main/java/io/netty/monitor/ValueMonitor.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
165
common/src/main/java/io/netty/monitor/package-info.java
Normal file
165
common/src/main/java/io/netty/monitor/package-info.java
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
112
common/src/main/java/io/netty/monitor/spi/MonitorProvider.java
Normal file
112
common/src/main/java/io/netty/monitor/spi/MonitorProvider.java
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* 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 #getName() 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 getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int compareTo(final MonitorProvider o) {
|
||||||
|
return this.name.compareTo(o.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.lang.Object#hashCode()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.lang.Object#equals(java.lang.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 java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "MonitorProvider(" + name + ")";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
26
common/src/main/java/io/netty/monitor/spi/package-info.java
Normal file
26
common/src/main/java/io/netty/monitor/spi/package-info.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
@ -17,6 +17,10 @@ package io.netty.util;
|
|||||||
|
|
||||||
import io.netty.logging.InternalLogger;
|
import io.netty.logging.InternalLogger;
|
||||||
import io.netty.logging.InternalLoggerFactory;
|
import io.netty.logging.InternalLoggerFactory;
|
||||||
|
import io.netty.monitor.ValueDistributionMonitor;
|
||||||
|
import io.netty.monitor.EventRateMonitor;
|
||||||
|
import io.netty.monitor.MonitorName;
|
||||||
|
import io.netty.monitor.MonitorRegistry;
|
||||||
import io.netty.util.internal.DetectionUtil;
|
import io.netty.util.internal.DetectionUtil;
|
||||||
import io.netty.util.internal.SharedResourceMisuseDetector;
|
import io.netty.util.internal.SharedResourceMisuseDetector;
|
||||||
|
|
||||||
@ -83,6 +87,11 @@ public class HashedWheelTimer implements Timer {
|
|||||||
private static final SharedResourceMisuseDetector misuseDetector =
|
private static final SharedResourceMisuseDetector misuseDetector =
|
||||||
new SharedResourceMisuseDetector(HashedWheelTimer.class);
|
new SharedResourceMisuseDetector(HashedWheelTimer.class);
|
||||||
|
|
||||||
|
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 Worker worker = new Worker();
|
private final Worker worker = new Worker();
|
||||||
final Thread workerThread;
|
final Thread workerThread;
|
||||||
final AtomicInteger workerState = new AtomicInteger(); // 0 - init, 1 - started, 2 - shut down
|
final AtomicInteger workerState = new AtomicInteger(); // 0 - init, 1 - started, 2 - shut down
|
||||||
@ -94,6 +103,10 @@ public class HashedWheelTimer implements Timer {
|
|||||||
final ReadWriteLock lock = new ReentrantReadWriteLock();
|
final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||||
volatile int wheelCursor;
|
volatile int wheelCursor;
|
||||||
|
|
||||||
|
// Monitoring this instance
|
||||||
|
final ValueDistributionMonitor timeoutExpirationTimeDeviation;
|
||||||
|
final EventRateMonitor timeoutsPerSecond;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new timer with the default thread factory
|
* Creates a new timer with the default thread factory
|
||||||
* ({@link Executors#defaultThreadFactory()}), default tick duration, and
|
* ({@link Executors#defaultThreadFactory()}), default tick duration, and
|
||||||
@ -110,6 +123,8 @@ public class HashedWheelTimer implements Timer {
|
|||||||
*
|
*
|
||||||
* @param tickDuration the duration between tick
|
* @param tickDuration the duration between tick
|
||||||
* @param unit the time unit of the {@code tickDuration}
|
* @param unit the time unit of the {@code tickDuration}
|
||||||
|
* @throws NullPointerException if {@code unit} is {@code null}
|
||||||
|
* @throws IllegalArgumentException if {@code tickDuration} is <= 0
|
||||||
*/
|
*/
|
||||||
public HashedWheelTimer(long tickDuration, TimeUnit unit) {
|
public HashedWheelTimer(long tickDuration, TimeUnit unit) {
|
||||||
this(Executors.defaultThreadFactory(), tickDuration, unit);
|
this(Executors.defaultThreadFactory(), tickDuration, unit);
|
||||||
@ -122,6 +137,8 @@ public class HashedWheelTimer implements Timer {
|
|||||||
* @param tickDuration the duration between tick
|
* @param tickDuration the duration between tick
|
||||||
* @param unit the time unit of the {@code tickDuration}
|
* @param unit the time unit of the {@code tickDuration}
|
||||||
* @param ticksPerWheel the size of the wheel
|
* @param ticksPerWheel the size of the wheel
|
||||||
|
* @throws NullPointerException if {@code unit} is {@code null}
|
||||||
|
* @throws IllegalArgumentException if either of {@code tickDuration} and {@code ticksPerWheel} is <= 0
|
||||||
*/
|
*/
|
||||||
public HashedWheelTimer(long tickDuration, TimeUnit unit, int ticksPerWheel) {
|
public HashedWheelTimer(long tickDuration, TimeUnit unit, int ticksPerWheel) {
|
||||||
this(Executors.defaultThreadFactory(), tickDuration, unit, ticksPerWheel);
|
this(Executors.defaultThreadFactory(), tickDuration, unit, ticksPerWheel);
|
||||||
@ -134,6 +151,7 @@ public class HashedWheelTimer implements Timer {
|
|||||||
* @param threadFactory a {@link ThreadFactory} that creates a
|
* @param threadFactory a {@link ThreadFactory} that creates a
|
||||||
* background {@link Thread} which is dedicated to
|
* background {@link Thread} which is dedicated to
|
||||||
* {@link TimerTask} execution.
|
* {@link TimerTask} execution.
|
||||||
|
* @throws NullPointerException if {@code threadFactory} is {@code null}
|
||||||
*/
|
*/
|
||||||
public HashedWheelTimer(ThreadFactory threadFactory) {
|
public HashedWheelTimer(ThreadFactory threadFactory) {
|
||||||
this(threadFactory, 100, TimeUnit.MILLISECONDS);
|
this(threadFactory, 100, TimeUnit.MILLISECONDS);
|
||||||
@ -147,6 +165,8 @@ public class HashedWheelTimer implements Timer {
|
|||||||
* {@link TimerTask} execution.
|
* {@link TimerTask} execution.
|
||||||
* @param tickDuration the duration between tick
|
* @param tickDuration the duration between tick
|
||||||
* @param unit the time unit of the {@code tickDuration}
|
* @param unit the time unit of the {@code tickDuration}
|
||||||
|
* @throws NullPointerException if either of {@code threadFactory} and {@code unit} is {@code null}
|
||||||
|
* @throws IllegalArgumentException if {@code tickDuration} is <= 0
|
||||||
*/
|
*/
|
||||||
public HashedWheelTimer(
|
public HashedWheelTimer(
|
||||||
ThreadFactory threadFactory, long tickDuration, TimeUnit unit) {
|
ThreadFactory threadFactory, long tickDuration, TimeUnit unit) {
|
||||||
@ -162,10 +182,87 @@ public class HashedWheelTimer implements Timer {
|
|||||||
* @param tickDuration the duration between tick
|
* @param tickDuration the duration between tick
|
||||||
* @param unit the time unit of the {@code tickDuration}
|
* @param unit the time unit of the {@code tickDuration}
|
||||||
* @param ticksPerWheel the size of the wheel
|
* @param ticksPerWheel the size of the wheel
|
||||||
|
* @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(
|
public HashedWheelTimer(
|
||||||
ThreadFactory threadFactory,
|
ThreadFactory threadFactory,
|
||||||
long tickDuration, TimeUnit unit, int ticksPerWheel) {
|
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) {
|
if (threadFactory == null) {
|
||||||
throw new NullPointerException("threadFactory");
|
throw new NullPointerException("threadFactory");
|
||||||
@ -173,13 +270,20 @@ public class HashedWheelTimer implements Timer {
|
|||||||
if (unit == null) {
|
if (unit == null) {
|
||||||
throw new NullPointerException("unit");
|
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) {
|
if (tickDuration <= 0) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("tickDuration must be greater than 0: " + tickDuration);
|
||||||
"tickDuration must be greater than 0: " + tickDuration);
|
|
||||||
}
|
}
|
||||||
if (ticksPerWheel <= 0) {
|
if (ticksPerWheel <= 0) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("ticksPerWheel must be greater than 0: " + ticksPerWheel);
|
||||||
"ticksPerWheel must be greater than 0: " + ticksPerWheel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize ticksPerWheel to power of two and initialize the wheel.
|
// Normalize ticksPerWheel to power of two and initialize the wheel.
|
||||||
@ -190,17 +294,19 @@ public class HashedWheelTimer implements Timer {
|
|||||||
this.tickDuration = tickDuration = unit.toMillis(tickDuration);
|
this.tickDuration = tickDuration = unit.toMillis(tickDuration);
|
||||||
|
|
||||||
// Prevent overflow.
|
// Prevent overflow.
|
||||||
if (tickDuration == Long.MAX_VALUE ||
|
if (tickDuration == Long.MAX_VALUE || tickDuration >= Long.MAX_VALUE / wheel.length) {
|
||||||
tickDuration >= Long.MAX_VALUE / wheel.length) {
|
throw new IllegalArgumentException("tickDuration is too long: " + tickDuration + ' ' + unit);
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"tickDuration is too long: " +
|
|
||||||
tickDuration + ' ' + unit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
roundDuration = tickDuration * wheel.length;
|
roundDuration = tickDuration * wheel.length;
|
||||||
|
|
||||||
workerThread = threadFactory.newThread(worker);
|
workerThread = threadFactory.newThread(worker);
|
||||||
|
|
||||||
|
timeoutExpirationTimeDeviation =
|
||||||
|
monitorRegistry.newValueDistributionMonitor(timeoutExpirationTimeDeviationMonitorName);
|
||||||
|
timeoutsPerSecond =
|
||||||
|
monitorRegistry.newEventRateMonitor(timeoutsPerSecondMonitorName, TimeUnit.SECONDS);
|
||||||
|
|
||||||
// Misuse check
|
// Misuse check
|
||||||
misuseDetector.increase();
|
misuseDetector.increase();
|
||||||
}
|
}
|
||||||
@ -518,6 +624,8 @@ public class HashedWheelTimer implements Timer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
timeoutsPerSecond.event();
|
||||||
|
timeoutExpirationTimeDeviation.update(System.currentTimeMillis() - deadline);
|
||||||
task.run(this);
|
task.run(this);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
if (logger.isWarnEnabled()) {
|
if (logger.isWarnEnabled()) {
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
package io.netty.monitor;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
import io.netty.monitor.support.SampleMonitorRegistryFactory;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
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 = objectUnderTest
|
||||||
|
.forProvider(SampleMonitorRegistryFactory.PROVIDER);
|
||||||
|
|
||||||
|
assertSame("forProvider(" + SampleMonitorRegistryFactory.PROVIDER
|
||||||
|
+ ") should return a MonitorRegistry by the supplied provider",
|
||||||
|
SampleMonitorRegistryFactory.SampleMonitorRegistry.class,
|
||||||
|
registry.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public final void uniqueShouldThrowIllegalStateExceptionIfMoreThanOneProviderIsRegistered() {
|
||||||
|
final MonitorRegistries objectUnderTest = MonitorRegistries.instance();
|
||||||
|
|
||||||
|
objectUnderTest.unique();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
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 inc(long delta) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inc() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decr(long delta) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decr() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
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 inc(long delta) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inc() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decr(long delta) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decr() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,133 @@
|
|||||||
|
package io.netty.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
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.CountDownLatch;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param eventDistributionMonitor
|
||||||
|
* @param eventRateMonitor
|
||||||
|
*/
|
||||||
|
RecordingMonitorRegistry(final ValueDistributionMonitor eventDistributionMonitor,
|
||||||
|
final EventRateMonitor eventRateMonitor) {
|
||||||
|
this.eventDistributionMonitor = eventDistributionMonitor;
|
||||||
|
this.eventRateMonitor = eventRateMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValueDistributionMonitor newValueDistributionMonitor(final MonitorName monitorName) {
|
||||||
|
return this.eventDistributionMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EventRateMonitor newEventRateMonitor(final MonitorName monitorName, final TimeUnit rateUnit) {
|
||||||
|
return this.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 inc(long delta) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inc() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decr(long delta) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decr() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
io.netty.monitor.support.SampleMonitorRegistryFactory
|
||||||
|
io.netty.monitor.support.AnotherSampleMonitorRegistryFactory
|
45
metrics-yammer/pom.xml
Normal file
45
metrics-yammer/pom.xml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?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.Alpha6-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>
|
||||||
|
<scope>compile</scope>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.yammer.metrics</groupId>
|
||||||
|
<artifactId>metrics-core</artifactId>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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.MonitorName;
|
||||||
|
|
||||||
|
import com.yammer.metrics.core.MetricName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Static helper methods.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
final class Utils {
|
||||||
|
|
||||||
|
static MetricName toMetricName(final MonitorName monitorName) {
|
||||||
|
return new MetricName(monitorName.getGroup(), monitorName.getType(), monitorName.getName(),
|
||||||
|
monitorName.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Utils() {
|
||||||
|
// Unused
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* 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.CounterMonitor;
|
||||||
|
|
||||||
|
import com.yammer.metrics.core.Counter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param delegate
|
||||||
|
*/
|
||||||
|
YammerCounterMonitor(final Counter delegate) {
|
||||||
|
if (delegate == null) {
|
||||||
|
throw new NullPointerException("delegate");
|
||||||
|
}
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.CounterMonitor#inc()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void inc() {
|
||||||
|
this.delegate.inc();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.CounterMonitor#inc(long)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void inc(final long delta) {
|
||||||
|
this.delegate.inc(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.CounterMonitor#decr()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void decr() {
|
||||||
|
this.delegate.dec();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.CounterMonitor#decr(long)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void decr(final long delta) {
|
||||||
|
this.delegate.dec(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.CounterMonitor#reset()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
this.delegate.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "YammerCounterMonitor(delegate=" + delegate + ")";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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.EventRateMonitor;
|
||||||
|
|
||||||
|
import com.yammer.metrics.core.Meter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param delegate
|
||||||
|
*/
|
||||||
|
YammerEventRateMonitor(final Meter delegate) {
|
||||||
|
if (delegate == null) {
|
||||||
|
throw new NullPointerException("delegate");
|
||||||
|
}
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.EventRateMonitor#event()
|
||||||
|
* @see com.yammer.metrics.core.Meter#mark()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void event() {
|
||||||
|
this.delegate.mark();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.EventRateMonitor#events(long)
|
||||||
|
* @see com.yammer.metrics.core.Meter#mark(long)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void events(final long count) {
|
||||||
|
this.delegate.mark(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "YammerEventRateMonitor(delegate=" + delegate + ")";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* 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.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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <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 Histrogram}.
|
||||||
|
* @see io.netty.monitor.MonitorRegistry#newValueDistributionMonitor(io.netty.monitor.MonitorName)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ValueDistributionMonitor newValueDistributionMonitor(final MonitorName monitorName) {
|
||||||
|
final Histogram histogram = this.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 io.netty.monitor.MonitorRegistry#newEventRateMonitor(io.netty.monitor.MonitorName,
|
||||||
|
* java.util.concurrent.TimeUnit)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public EventRateMonitor newEventRateMonitor(final MonitorName monitorName, final TimeUnit rateUnit) {
|
||||||
|
final Meter meter = this.delegate.newMeter(Utils.toMetricName(monitorName), monitorName.getName(), rateUnit);
|
||||||
|
return new YammerEventRateMonitor(meter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the supplied {@link ValueMonitor valueMonitor}, using it
|
||||||
|
* internally to create a {@code Yammer} {@link Gauge}.
|
||||||
|
* @see io.netty.monitor.MonitorRegistry#registerValueMonitor(io.netty.monitor.MonitorName,
|
||||||
|
* io.netty.monitor.ValueMonitor)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> ValueMonitor<T> registerValueMonitor(final MonitorName monitorName, final ValueMonitor<T> valueMonitor) {
|
||||||
|
this.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 io.netty.monitor.MonitorRegistry#newCounterMonitor(io.netty.monitor.MonitorName)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CounterMonitor newCounterMonitor(MonitorName monitorName) {
|
||||||
|
final Counter counter = this.delegate.newCounter(Utils.toMetricName(monitorName));
|
||||||
|
return new YammerCounterMonitor(counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "YammerMonitorRegistry(delegate=" + delegate + ")";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* 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.ValueDistributionMonitor;
|
||||||
|
|
||||||
|
import com.yammer.metrics.core.Histogram;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param delegate
|
||||||
|
*/
|
||||||
|
YammerValueDistributionMonitor(final Histogram delegate) {
|
||||||
|
if (delegate == null) {
|
||||||
|
throw new NullPointerException("delegate");
|
||||||
|
}
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.EventDistributionMonitor#reset()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
this.delegate.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.EventDistributionMonitor#update(long)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void update(final long value) {
|
||||||
|
this.delegate.update(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "YammerEventDistributionMonitor(delegate=" + delegate + ")";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* 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 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;
|
||||||
|
|
||||||
|
import com.yammer.metrics.Metrics;
|
||||||
|
import com.yammer.metrics.core.MetricsRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* A {@link MonitorRegistryFactory} that produces {@link YammerMonitorRegistry
|
||||||
|
* YammerMonitorRegistries}.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public class YammerMonitorRegistryFactory implements MonitorRegistryFactory {
|
||||||
|
|
||||||
|
private final MetricsRegistry metricsRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public YammerMonitorRegistryFactory() {
|
||||||
|
this(Metrics.defaultRegistry());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param metricsRegistry
|
||||||
|
*/
|
||||||
|
public YammerMonitorRegistryFactory(final MetricsRegistry metricsRegistry) {
|
||||||
|
if (metricsRegistry == null) {
|
||||||
|
throw new NullPointerException("metricsRegistry");
|
||||||
|
}
|
||||||
|
this.metricsRegistry = metricsRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.spi.MonitorRegistryFactory#provider()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public MonitorProvider provider() {
|
||||||
|
return YammerProvider.PROVIDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see io.netty.monitor.spi.MonitorRegistryFactory#newMonitorRegistry()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public MonitorRegistry newMonitorRegistry() {
|
||||||
|
return new YammerMonitorRegistry(metricsRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "YammerMonitorRegistryFactory(metricsRegistry=" + metricsRegistry + ")";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
io.netty.monitor.yammer.spi.YammerMonitorRegistryFactory
|
10
pom.xml
10
pom.xml
@ -69,6 +69,7 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<jboss.marshalling.version>1.3.14.GA</jboss.marshalling.version>
|
<jboss.marshalling.version>1.3.14.GA</jboss.marshalling.version>
|
||||||
|
<yammer.metrics.version>2.1.2</yammer.metrics.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
@ -78,6 +79,7 @@
|
|||||||
<module>codec-http</module>
|
<module>codec-http</module>
|
||||||
<module>transport</module>
|
<module>transport</module>
|
||||||
<module>handler</module>
|
<module>handler</module>
|
||||||
|
<module>metrics-yammer</module>
|
||||||
<module>example</module>
|
<module>example</module>
|
||||||
<module>testsuite</module>
|
<module>testsuite</module>
|
||||||
<module>all</module>
|
<module>all</module>
|
||||||
@ -163,6 +165,14 @@
|
|||||||
</exclusions>
|
</exclusions>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Metrics providers -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.yammer.metrics</groupId>
|
||||||
|
<artifactId>metrics-core</artifactId>
|
||||||
|
<version>${yammer.metrics.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Test dependencies for jboss marshalling encoder/decoder -->
|
<!-- Test dependencies for jboss marshalling encoder/decoder -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jboss.marshalling</groupId>
|
<groupId>org.jboss.marshalling</groupId>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user