/* * Copyright (c) 2014 the original author or authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.werval.modules.metrics; import com.codahale.metrics.MetricRegistry; import io.werval.api.outcomes.Outcome; import io.werval.runtime.routes.RoutesParserProvider; import io.werval.test.WervalHttpRule; import java.lang.management.ManagementFactory; import javax.management.MBeanServer; import javax.management.ObjectName; import org.junit.ClassRule; import org.junit.Test; import static com.jayway.awaitility.Awaitility.await; import static com.jayway.restassured.RestAssured.expect; import static io.werval.api.context.CurrentContext.outcomes; import static io.werval.api.context.CurrentContext.plugin; import static io.werval.api.mime.MimeTypes.APPLICATION_JSON; import static io.werval.api.mime.MimeTypes.TEXT_HTML; import static io.werval.api.mime.MimeTypes.TEXT_PLAIN; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; /** * Metrics Test. */ public class MetricsTest { @ClassRule public static WervalHttpRule WERVAL = new WervalHttpRule( new RoutesParserProvider( "GET / Default.ok\n" + "GET /redir Default.seeOther( String url = / )\n" + "GET /error Default.internalServerError\n" + "GET /unknown io.werval.modules.metrics.MetricsTest$Controller.unknown\n" + "GET /@metrics io.werval.modules.metrics.Tools.devShellIndex\n" + "GET /@metrics/metrics io.werval.modules.metrics.Tools.metrics\n" + "GET /@metrics/health-checks io.werval.modules.metrics.Tools.healthchecks\n" + "GET /@metrics/thread-dump io.werval.modules.metrics.Tools.threadDump\n" ) ); @Counter( name = "unknown-counter" ) @Meter( name = "unknown-meter" ) public static class Controller { @Timer( name = "unknown-timer" ) public Outcome unknown() { plugin( Metrics.class ).metrics().counter( "MetricsTest" ).inc(); return outcomes().status( 666 ).build(); } } @Test public void devShellRoutesAndMetrics() throws Exception { MetricRegistry metrics = WERVAL.application().plugin( Metrics.class ).metrics(); expect() .statusCode( 200 ) .when() .get( "/" ); expect() .statusCode( 200 ) .contentType( TEXT_HTML ) .body( containsString( "href=\"/@metrics/metrics" ) ) .body( containsString( "href=\"/@metrics/health-checks" ) ) .body( containsString( "href=\"/@metrics/thread-dump" ) ) .when() .get( "/@metrics" ); expect() .statusCode( 200 ) .contentType( APPLICATION_JSON ) .body( "timers.'io.werval.http.requests'.count", is( 2 ) ) .body( "meters.'io.werval.http.success'.count", is( 2 ) ) .when() .get( "/@metrics/metrics" ); expect() .statusCode( 200 ) .contentType( APPLICATION_JSON ) .body( "'jvm.deadlocks'.healthy", is( true ) ) .when() .get( "/@metrics/health-checks" ); expect() .statusCode( 200 ) .contentType( TEXT_PLAIN ) .body( containsString( "io.werval.modules.metrics.Tools.threadDump" ) ) .when() .get( "/@metrics/thread-dump" ); await( "io.werval.http.requests == 5" ).until( () -> metrics.timer( "io.werval.http.requests" ).getCount() == 5L ); assertThat( metrics.meter( "io.werval.http.success" ).getCount(), is( 5L ) ); assertThat( metrics.meter( "io.werval.http.redirections" ).getCount(), is( 0L ) ); assertThat( metrics.meter( "io.werval.http.client-errors" ).getCount(), is( 0L ) ); assertThat( metrics.meter( "io.werval.http.server-errors" ).getCount(), is( 0L ) ); assertThat( metrics.meter( "io.werval.http.unknown" ).getCount(), is( 0L ) ); expect().statusCode( 200 ).when().get( "/redir" ); // Follows the redirection to / that returns 200 expect().statusCode( 404 ).when().get( "/not-found" ); expect().statusCode( 500 ).when().get( "/error" ); // Wait for https://code.google.com/p/rest-assured/issues/detail?id=382 to be fixed // expect().statusCode( 666 ).when().get( "/unknown" ); await( "io.werval.http.requests == 9" ).until( () -> metrics.timer( "io.werval.http.requests" ).getCount() == 9L // 10L ); assertThat( metrics.meter( "io.werval.http.success" ).getCount(), is( 6L ) ); assertThat( metrics.meter( "io.werval.http.redirections" ).getCount(), is( 1L ) ); assertThat( metrics.meter( "io.werval.http.client-errors" ).getCount(), is( 1L ) ); assertThat( metrics.meter( "io.werval.http.server-errors" ).getCount(), is( 1L ) ); assertThat( metrics.meter( "io.werval.http.unknown" ).getCount(), is( 0L ) ); // 1L // assertThat( metrics.counter( "unknown-counter" ).getCount(), is( 1L ) ); // assertThat( metrics.meter( "unknown-meter" ).getCount(), is( 1L ) ); // assertThat( metrics.timer( "unknown-timer" ).getCount(), is( 1L ) ); // assertThat( metrics.counter( "MetricsTest" ).getCount(), is( 1L ) ); // JMX MBeanServer jmx = ManagementFactory.getPlatformMBeanServer(); assertThat( jmx.getAttribute( new ObjectName( "metrics:name=io.werval.http.requests" ), "Count" ), is( 9L ) ); // 10L assertThat( jmx.getAttribute( new ObjectName( "metrics:name=io.werval.http.success" ), "Count" ), is( 6L ) ); assertThat( jmx.getAttribute( new ObjectName( "metrics:name=io.werval.http.redirections" ), "Count" ), is( 1L ) ); assertThat( jmx.getAttribute( new ObjectName( "metrics:name=io.werval.http.client-errors" ), "Count" ), is( 1L ) ); assertThat( jmx.getAttribute( new ObjectName( "metrics:name=io.werval.http.server-errors" ), "Count" ), is( 1L ) ); // assertThat( jmx.getAttribute( new ObjectName( "metrics:name=io.werval.http.unknown" ), "Count" ), is( 1L ) ); // assertThat( jmx.getAttribute( new ObjectName( "metrics:name=unknown-counter" ), "Count" ), is( 1L ) ); // assertThat( jmx.getAttribute( new ObjectName( "metrics:name=unknown-meter" ), "Count" ), is( 1L ) ); // assertThat( jmx.getAttribute( new ObjectName( "metrics:name=unknown-timer" ), "Count" ), is( 1L ) ); // assertThat( jmx.getAttribute( new ObjectName( "metrics:name=MetricsTest" ), "Count" ), is( 1L ) ); } }