Skip to content

Commit 5a2da35

Browse files
committed
Support metrics with JMX
[#151844595] Fixes #101
1 parent dff4405 commit 5a2da35

File tree

9 files changed

+167
-11
lines changed

9 files changed

+167
-11
lines changed

pom.xml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656

5757
<rabbitmq.version>5.3.0</rabbitmq.version>
5858
<commons-cli.version>1.1</commons-cli.version>
59-
<metrics.version>4.0.3</metrics.version>
59+
<metrics.version>3.2.6</metrics.version>
6060
<micrometer.version>1.0.6</micrometer.version>
6161
<logback.version>1.2.3</logback.version>
6262
<jetty.version>9.4.11.v20180605</jetty.version>
@@ -122,14 +122,20 @@
122122
</dependency>
123123
<dependency>
124124
<groupId>io.micrometer</groupId>
125-
<artifactId>micrometer-registry-prometheus</artifactId>
125+
<artifactId>micrometer-registry-datadog</artifactId>
126126
<version>${micrometer.version}</version>
127127
</dependency>
128128
<dependency>
129129
<groupId>io.micrometer</groupId>
130-
<artifactId>micrometer-registry-datadog</artifactId>
130+
<artifactId>micrometer-registry-jmx</artifactId>
131131
<version>${micrometer.version}</version>
132132
</dependency>
133+
<dependency>
134+
<groupId>io.micrometer</groupId>
135+
<artifactId>micrometer-registry-prometheus</artifactId>
136+
<version>${micrometer.version}</version>
137+
</dependency>
138+
133139
<dependency>
134140
<groupId>ch.qos.logback</groupId>
135141
<artifactId>logback-classic</artifactId>

src/docs/asciidoc/monitoring.adoc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ for more information about tags and dimensions.
5656

5757
PerfTest builds on top https://micrometer.io[Micrometer] to report gathered metrics to various monitoring systems.
5858
Nevertheless, not all systems supported by Micrometer are actually supported by PerfTest.
59-
PerfTest currently supports https://www.datadoghq.com/[Datadog] and https://prometheus.io/[Prometheus].
59+
PerfTest currently supports https://www.datadoghq.com/[Datadog], https://en.wikipedia.org/wiki/Java_Management_Extensions[JMX],
60+
and https://prometheus.io/[Prometheus].
6061
Don't hesitate to
6162
https://github.com/rabbitmq/rabbitmq-perf-test/issues[request support for other monitoring systems].
6263

@@ -76,6 +77,15 @@ Another useful option is the step size or reporting frequency. The default value
7677
--metrics-datadog-step-size 20
7778
```
7879

80+
==== JMX
81+
82+
JMX support provides a simple way to view metrics locally. Use the `--metrics-jmx` flag to
83+
export metrics to JMX:
84+
85+
```
86+
./runjava com.rabbitmq.perf.PerfTest --metrics-jmx
87+
```
88+
7989
==== Prometheus
8090

8191
Use the `-mpr` or `--metrics-prometheus` flag to enable metrics reporting to Prometheus:

src/main/java/com/rabbitmq/perf/CompositeMetrics.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public CompositeMetrics() {
3939
metrics.add(new BaseMetrics());
4040
metrics.add(new PrometheusMetrics());
4141
metrics.add(new DatadogMetrics());
42+
metrics.add(new JmxMetrics());
4243
}
4344

4445
@Override

src/main/java/com/rabbitmq/perf/DatadogMetrics.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.rabbitmq.client.ConnectionFactory;
1919
import io.micrometer.core.instrument.Clock;
20+
import io.micrometer.core.instrument.MeterRegistry;
2021
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
2122
import io.micrometer.datadog.DatadogConfig;
2223
import io.micrometer.datadog.DatadogMeterRegistry;
@@ -36,7 +37,7 @@
3637
*/
3738
public class DatadogMetrics implements Metrics {
3839

39-
private volatile DatadogMeterRegistry registry;
40+
private volatile MeterRegistry registry;
4041

4142
public Options options() {
4243
Options options = new Options();
@@ -63,6 +64,7 @@ public void configure(CommandLineProxy cmd, CompositeMeterRegistry meterRegistry
6364
dataCfg.put("datadog.uri", strArg(cmd, "mdu", null));
6465

6566
DatadogConfig config = new DatadogConfig() {
67+
6668
@Override
6769
public Duration step() {
6870
return Duration.ofSeconds(Integer.valueOf(dataCfg.get("datadog.step")));
@@ -83,7 +85,9 @@ public String get(String k) {
8385
}
8486

8587
public void close() {
86-
registry.close();
88+
if (registry != null) {
89+
registry.close();
90+
}
8791
}
8892

8993
@Override
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright (c) 2018 Pivotal Software, Inc. All rights reserved.
2+
//
3+
// This software, the RabbitMQ Java client library, is triple-licensed under the
4+
// Mozilla Public License 1.1 ("MPL"), the GNU General Public License version 2
5+
// ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see
6+
// LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2. For the ASL,
7+
// please see LICENSE-APACHE2.
8+
//
9+
// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
10+
// either express or implied. See the LICENSE file for specific language governing
11+
// rights and limitations of this software.
12+
//
13+
// If you have any questions regarding licensing, please contact us at
14+
15+
16+
package com.rabbitmq.perf;
17+
18+
import com.rabbitmq.client.ConnectionFactory;
19+
import io.micrometer.core.instrument.Clock;
20+
import io.micrometer.core.instrument.MeterRegistry;
21+
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
22+
import io.micrometer.jmx.JmxConfig;
23+
import io.micrometer.jmx.JmxMeterRegistry;
24+
import org.apache.commons.cli.Option;
25+
import org.apache.commons.cli.Options;
26+
27+
/**
28+
*
29+
*/
30+
public class JmxMetrics implements Metrics {
31+
32+
private volatile MeterRegistry registry;
33+
34+
public Options options() {
35+
Options options = new Options();
36+
options.addOption(new Option("mjx", "metrics-jmx", false, "enable JMX metrics"));
37+
return options;
38+
}
39+
40+
public void configure(CommandLineProxy cmd, CompositeMeterRegistry meterRegistry, ConnectionFactory factory) throws Exception {
41+
if (isEnabled(cmd)) {
42+
registry = new JmxMeterRegistry(
43+
JmxConfig.DEFAULT,
44+
Clock.SYSTEM
45+
);
46+
meterRegistry.add(registry);
47+
}
48+
}
49+
50+
public void close() {
51+
if (registry!= null) {
52+
registry.close();
53+
}
54+
}
55+
56+
@Override
57+
public String toString() {
58+
return "JMX Metrics";
59+
}
60+
}

src/main/java/com/rabbitmq/perf/PrometheusMetrics.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public class PrometheusMetrics implements Metrics {
4343

4444
private volatile Server server;
4545

46+
private volatile PrometheusMeterRegistry registry;
47+
4648
public Options options() {
4749
Options options = new Options();
4850
options.addOption(new Option("mpr", "metrics-prometheus", false, "enable Prometheus metrics"));
@@ -53,7 +55,7 @@ public Options options() {
5355

5456
public void configure(CommandLineProxy cmd, CompositeMeterRegistry meterRegistry, ConnectionFactory factory) throws Exception {
5557
if (isEnabled(cmd)) {
56-
PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
58+
registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
5759
meterRegistry.add(registry);
5860
int prometheusHttpEndpointPort = intArg(cmd, "mpp", 8080);
5961
String prometheusHttpEndpoint = strArg(cmd, "mpe", "metrics");
@@ -97,6 +99,9 @@ public void close() throws Exception {
9799
if (server != null) {
98100
server.stop();
99101
}
102+
if (registry != null) {
103+
registry.close();
104+
}
100105
}
101106

102107
@Override

src/test/java/com/rabbitmq/perf/DatadogMetricsTest.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ public void tearDown() throws Exception {
7676
}
7777

7878
@Test
79-
public void datadog() throws Exception {
80-
DatadogMetrics metrics = new DatadogMetrics();
79+
public void metricsShouldBeSentToDatadogHttpEndpoint() throws Exception {
80+
metrics = new DatadogMetrics();
8181
Options options = metrics.options();
8282

8383
CommandLineParser parser = new GnuParser();
@@ -103,8 +103,6 @@ public void datadog() throws Exception {
103103
assertTrue(content.get().contains("\"metric\":\"dummy\""));
104104
assertTrue(content.get().contains("42.0"));
105105
assertTrue(content.get().contains("\"host\":\"test\""));
106-
107-
metrics.close();
108106
}
109107

110108
private Server startMockDatadogService() throws Exception {
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright (c) 2018 Pivotal Software, Inc. All rights reserved.
2+
//
3+
// This software, the RabbitMQ Java client library, is triple-licensed under the
4+
// Mozilla Public License 1.1 ("MPL"), the GNU General Public License version 2
5+
// ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see
6+
// LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2. For the ASL,
7+
// please see LICENSE-APACHE2.
8+
//
9+
// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
10+
// either express or implied. See the LICENSE file for specific language governing
11+
// rights and limitations of this software.
12+
//
13+
// If you have any questions regarding licensing, please contact us at
14+
15+
16+
package com.rabbitmq.perf;
17+
18+
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
19+
import org.apache.commons.cli.CommandLine;
20+
import org.apache.commons.cli.CommandLineParser;
21+
import org.apache.commons.cli.GnuParser;
22+
import org.apache.commons.cli.Options;
23+
import org.junit.jupiter.api.AfterEach;
24+
import org.junit.jupiter.api.Test;
25+
26+
import javax.management.MBeanInfo;
27+
import javax.management.MBeanServer;
28+
import javax.management.ObjectName;
29+
import java.lang.management.ManagementFactory;
30+
import java.util.Set;
31+
import java.util.concurrent.atomic.AtomicInteger;
32+
33+
import static org.junit.jupiter.api.Assertions.assertEquals;
34+
35+
/**
36+
*
37+
*/
38+
public class JmxMetricsTest {
39+
40+
Metrics metrics = new JmxMetrics();
41+
42+
@AfterEach
43+
public void tearDown() throws Exception {
44+
metrics.close();
45+
}
46+
47+
@Test
48+
public void metricsShouldBeExposedAsMbeans() throws Exception {
49+
Options options = metrics.options();
50+
51+
CommandLineParser parser = new GnuParser();
52+
CommandLine rawCmd = parser.parse(
53+
options,
54+
("--metrics-jmx").split(" ")
55+
);
56+
CommandLineProxy cmd = new CommandLineProxy(options, rawCmd, name -> null);
57+
CompositeMeterRegistry registry = new CompositeMeterRegistry();
58+
AtomicInteger metric = registry.gauge("dummy", new AtomicInteger(0));
59+
metric.set(42);
60+
metrics.configure(cmd, registry, null);
61+
62+
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
63+
Set<ObjectName> objectNames = server.queryNames(new ObjectName("*:name=dummy"), null);
64+
assertEquals(1, objectNames.size());
65+
ObjectName objectName = objectNames.iterator().next();
66+
MBeanInfo info = server.getMBeanInfo(objectName);
67+
Object attribute = server.getAttribute(objectName, info.getAttributes()[0].getName());
68+
assertEquals(metric.get(), Double.valueOf(attribute.toString()).intValue());
69+
}
70+
}

src/test/java/com/rabbitmq/perf/MetricsTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public void noDuplicateOptionBetweenMetrics() {
3737
Set<String> options = new HashSet<>();
3838
List<Metrics> metrics = new ArrayList<>();
3939
metrics.add(new BaseMetrics());
40+
metrics.add(new DatadogMetrics());
41+
metrics.add(new JmxMetrics());
4042
metrics.add(new PrometheusMetrics());
4143
for (Metrics metric : metrics) {
4244
for (Object optObj : metric.options().getOptions()) {

0 commit comments

Comments
 (0)