diff --git a/restx-monitor-admin/src/main/java/restx/monitor/MetricsConfiguration.java b/restx-monitor-admin/src/main/java/restx/monitor/MetricsConfiguration.java index 91cfcabf5..bad8bc1c1 100644 --- a/restx-monitor-admin/src/main/java/restx/monitor/MetricsConfiguration.java +++ b/restx-monitor-admin/src/main/java/restx/monitor/MetricsConfiguration.java @@ -1,7 +1,9 @@ package restx.monitor; +import com.codahale.metrics.DefaultObjectNameFactory; import com.codahale.metrics.JmxReporter; import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.ObjectNameFactory; import com.codahale.metrics.graphite.Graphite; import com.codahale.metrics.graphite.GraphiteReporter; import com.codahale.metrics.health.HealthCheckRegistry; @@ -16,9 +18,11 @@ import restx.metrics.codahale.CodahaleMetricRegistry; import restx.metrics.codahale.health.CodahaleHealthCheckRegistry; +import javax.management.ObjectName; import java.lang.management.ManagementFactory; import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; /** * Date: 17/11/13 @@ -68,14 +72,30 @@ public void start() { } protected void setupReporters() { - logger.info("Initializing Metrics JMX Reporter"); - final JmxReporter jmxReporter = JmxReporter.forRegistry(metrics).build(); - jmxReporter.start(); + setupJmxReporter(); setupGraphiteReporter(); } - private void setupGraphiteReporter() { + protected void setupJmxReporter() { + logger.info("Initializing Metrics JMX Reporter"); + final JmxReporter jmxReporter = JmxReporter.forRegistry(metrics) + .createsObjectNamesWith(new DefaultObjectNameFactory() { + Pattern wildcards = Pattern.compile("[\\*\\?]"); + + @Override + public ObjectName createName(String type, String domain, String name) { + if (wildcards.matcher(name).find()) { + name = ObjectName.quote(name); + } + + return super.createName(type, domain, name); + } + }).build(); + jmxReporter.start(); + } + + protected void setupGraphiteReporter() { if (graphiteSettings.getGraphiteHost().isPresent()) { InetSocketAddress address = new InetSocketAddress( graphiteSettings.getGraphiteHost().get(), graphiteSettings.getGraphitePort().or(2003)); diff --git a/restx-samplest/src/test/java/samplest/core/ProdModeTest.java b/restx-samplest/src/test/java/samplest/core/ProdModeTest.java new file mode 100644 index 000000000..0c13e67bd --- /dev/null +++ b/restx-samplest/src/test/java/samplest/core/ProdModeTest.java @@ -0,0 +1,64 @@ +package samplest.core; + +import com.codahale.metrics.Metric; +import com.codahale.metrics.MetricFilter; +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.Timer; +import com.github.kevinsawicki.http.HttpRequest; +import com.google.common.collect.Lists; +import org.junit.After; +import org.junit.ClassRule; +import org.junit.Test; +import restx.factory.Factory; +import restx.metrics.codahale.CodahaleMetricRegistry; +import restx.tests.RestxServerRule; + +import javax.management.MBeanServer; +import javax.management.ObjectName; +import java.lang.management.ManagementFactory; +import java.util.ArrayList; +import java.util.Set; +import java.util.SortedMap; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Date: 13/12/13 + * Time: 23:09 + */ +public class ProdModeTest { + @ClassRule + public static RestxServerRule server = new RestxServerRule().setMode("prod"); + + @Test + public void should_accept_stars_in_url_and_monitor_it() throws Exception { + // test for #126 + + // first we do a request and check it is properly processed + HttpRequest httpRequest = server.client().authenticatedAs("admin").GET( + "/api/params/path/v1*/v2/35v4"); + assertThat(httpRequest.code()).isEqualTo(200); + assertThat(httpRequest.body().trim()).isEqualTo("a=v1* b=v2 c=35 d=v4"); + + // then we check corresponding timer has been registered in Metrics + MetricRegistry registry = ((CodahaleMetricRegistry) Factory.getFactory(server.getServer().getServerId()).get() + .getComponent(restx.common.metrics.api.MetricRegistry.class)).getCodahaleMetricRegistry(); + + SortedMap timers = registry.getTimers(new MetricFilter() { + @Override + public boolean matches(String name, Metric metric) { + return name.indexOf(" GET /params/path/") != -1; + } + }); + + assertThat(timers.size()).isEqualTo(1); + assertThat(timers.firstKey()).isEqualTo(" GET /params/path/v1*/v2/35v4"); + + // and now we check a MBean has been created for that timer too. + // the name of the MBean is escaped, so it is enclosed in quotes: " + MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); + Set objectNames = mBeanServer.queryNames( + ObjectName.getInstance("metrics:name=\" GET /params/path/*\""), null); + assertThat(objectNames.size()).isEqualTo(1); + } +}