@Test public void dropwizardInstalledIfPresent() { this.context = new AnnotationConfigApplicationContext( MetricsDropwizardAutoConfiguration.class, MetricRepositoryAutoConfiguration.class, AopAutoConfiguration.class); GaugeService gaugeService = this.context.getBean(GaugeService.class); assertThat(gaugeService).isNotNull(); gaugeService.submit("foo", 2.7); DropwizardMetricServices exporter = this.context .getBean(DropwizardMetricServices.class); assertThat(exporter).isEqualTo(gaugeService); MetricRegistry registry = this.context.getBean(MetricRegistry.class); @SuppressWarnings("unchecked") Gauge<Double> gauge = (Gauge<Double>) registry.getMetrics().get("gauge.foo"); assertThat(gauge.getValue()).isEqualTo(new Double(2.7)); }
@Test public void recordsHttpInteractions() throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( Config.class, MetricFilterAutoConfiguration.class); Filter filter = context.getBean(Filter.class); final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test/path"); final MockHttpServletResponse response = new MockHttpServletResponse(); FilterChain chain = mock(FilterChain.class); willAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { response.setStatus(200); return null; } }).given(chain).doFilter(request, response); filter.doFilter(request, response, chain); verify(context.getBean(CounterService.class)).increment("status.200.test.path"); verify(context.getBean(GaugeService.class)).submit(eq("response.test.path"), anyDouble()); context.close(); }
@Test public void records302HttpInteractionsAsSingleMetric() throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( Config.class, MetricFilterAutoConfiguration.class, RedirectFilter.class); MetricsFilter filter = context.getBean(MetricsFilter.class); MockMvc mvc = MockMvcBuilders.standaloneSetup(new MetricFilterTestController()) .addFilter(filter).addFilter(context.getBean(RedirectFilter.class)) .build(); mvc.perform(get("/unknownPath/1")).andExpect(status().is3xxRedirection()); mvc.perform(get("/unknownPath/2")).andExpect(status().is3xxRedirection()); verify(context.getBean(CounterService.class), times(2)) .increment("status.302.unmapped"); verify(context.getBean(GaugeService.class), times(2)) .submit(eq("response.unmapped"), anyDouble()); context.close(); }
@Test public void controllerMethodThatThrowsUnhandledException() throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( Config.class, MetricFilterAutoConfiguration.class); Filter filter = context.getBean(Filter.class); MockMvc mvc = MockMvcBuilders.standaloneSetup(new MetricFilterTestController()) .addFilter(filter).build(); try { mvc.perform(get("/unhandledException")) .andExpect(status().isInternalServerError()); } catch (NestedServletException ex) { // Expected } verify(context.getBean(CounterService.class)) .increment("status.500.unhandledException"); verify(context.getBean(GaugeService.class)) .submit(eq("response.unhandledException"), anyDouble()); context.close(); }
@Test public void gaugeServiceThatThrows() throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( Config.class, MetricFilterAutoConfiguration.class); GaugeService gaugeService = context.getBean(GaugeService.class); willThrow(new IllegalStateException()).given(gaugeService).submit(anyString(), anyDouble()); Filter filter = context.getBean(Filter.class); MockMvc mvc = MockMvcBuilders.standaloneSetup(new MetricFilterTestController()) .addFilter(filter).build(); mvc.perform(get("/templateVarTest/foo")).andExpect(status().isOk()); verify(context.getBean(CounterService.class)) .increment("status.200.templateVarTest.someVariable"); verify(context.getBean(GaugeService.class)) .submit(eq("response.templateVarTest.someVariable"), anyDouble()); context.close(); }
@Test public void records5xxxHttpInteractionsAsSingleMetric() throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( Config.class, MetricFilterAutoConfiguration.class, ServiceUnavailableFilter.class); MetricsFilter filter = context.getBean(MetricsFilter.class); MockMvc mvc = MockMvcBuilders.standaloneSetup(new MetricFilterTestController()) .addFilter(filter) .addFilter(context.getBean(ServiceUnavailableFilter.class)).build(); mvc.perform(get("/unknownPath/1")).andExpect(status().isServiceUnavailable()); mvc.perform(get("/unknownPath/2")).andExpect(status().isServiceUnavailable()); verify(context.getBean(CounterService.class), times(2)) .increment("status.503.unmapped"); verify(context.getBean(GaugeService.class), times(2)) .submit(eq("response.unmapped"), anyDouble()); context.close(); }
@Test public void doesNotRecordRolledUpMetricsIfConfigured() throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(Config.class, MetricFilterAutoConfiguration.class); EnvironmentTestUtils.addEnvironment(context, "endpoints.metrics.filter.gauge-submissions=", "endpoints.metrics.filter.counter-submissions="); context.refresh(); Filter filter = context.getBean(Filter.class); final MockHttpServletRequest request = new MockHttpServletRequest("PUT", "/test/path"); final MockHttpServletResponse response = new MockHttpServletResponse(); FilterChain chain = mock(FilterChain.class); willAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { response.setStatus(200); return null; } }).given(chain).doFilter(request, response); filter.doFilter(request, response, chain); verify(context.getBean(GaugeService.class), never()).submit(anyString(), anyDouble()); verify(context.getBean(CounterService.class), never()).increment(anyString()); context.close(); }
@Test public void provideAdditionalWriter() { this.context = new AnnotationConfigApplicationContext(WriterConfig.class, MetricRepositoryAutoConfiguration.class, MetricExportAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); GaugeService gaugeService = this.context.getBean(GaugeService.class); assertThat(gaugeService).isNotNull(); gaugeService.submit("foo", 2.7); MetricExporters exporters = this.context.getBean(MetricExporters.class); MetricCopyExporter exporter = (MetricCopyExporter) exporters.getExporters() .get("writer"); exporter.setIgnoreTimestamps(true); exporter.export(); MetricWriter writer = this.context.getBean("writer", MetricWriter.class); Mockito.verify(writer, Mockito.atLeastOnce()).set(Matchers.any(Metric.class)); }
/** * Method for setting Kafka-related properties, required for proper updating of metrics. * * @param configs {@link Map} with Kafka-specific properties, required to initialize the appropriate consumer/producer. * @param gaugeService reference to an instance of Springs {@link GaugeService}, used to set the collected metrics * @param prefix initial part of the metric's label * @param executorService reference to an instance of {@link ScheduledExecutorService}, used to schedule periodic values' recalculation for metrics * @param updateInterval interval for iterating the whole set of tracked metrics to recalculate and resubmit their values */ public static void configureKafkaMetrics(Map<String, Object> configs, GaugeService gaugeService, String prefix, ScheduledExecutorService executorService, Long updateInterval) { if (gaugeService == null) { throw new IllegalArgumentException("Initializing GaugeService as null is meaningless!"); } configs.put(CommonClientConfigs.METRIC_REPORTER_CLASSES_CONFIG, Collections.singletonList(KafkaStatisticsProvider.class.getName())); configs.put(KafkaStatisticsProvider.METRICS_GAUGE_SERVICE_IMPL, gaugeService); LOGGER.debug("Set property {} with provided GaugeService instance reference", KafkaStatisticsProvider.METRICS_GAUGE_SERVICE_IMPL); if (executorService != null) { configs.put(KafkaStatisticsProvider.METRICS_UPDATE_EXECUTOR_IMPL, executorService); LOGGER.debug("Set property {} with provided ScheduledExecutorService instance reference", KafkaStatisticsProvider.METRICS_UPDATE_EXECUTOR_IMPL); } if (updateInterval != null) { configs.put(KafkaStatisticsProvider.METRICS_UPDATE_INTERVAL_PARAM, updateInterval); LOGGER.debug("Set property {} with value {}", KafkaStatisticsProvider.METRICS_UPDATE_INTERVAL_PARAM, updateInterval); } if (prefix != null) { configs.put(KafkaStatisticsProvider.METRICS_PREFIX_PARAM, prefix); LOGGER.debug("Set property {} with value {}", KafkaStatisticsProvider.METRICS_PREFIX_PARAM, prefix); } }
@Test public void configureKafkaMetrics_withGaugeServiceAndPrefix() { Map<String, Object> config = new HashMap<>(); assertThat(config).isEmpty(); GaugeService gaugeService = mockGaugeService(); String prefix = "test.prefix"; KafkaConfigUtils.configureKafkaMetrics(config, gaugeService, prefix, null, null); assertThat(config).hasSize(3); assertThat(config.get(CommonClientConfigs.METRIC_REPORTER_CLASSES_CONFIG)) .asList() .contains(KafkaStatisticsProvider.class.getCanonicalName()); assertThat(config.get(KafkaStatisticsProvider.METRICS_GAUGE_SERVICE_IMPL)).isSameAs(gaugeService); assertThat(config.get(KafkaStatisticsProvider.METRICS_PREFIX_PARAM)).isEqualTo(prefix); assertThat(config.get(KafkaStatisticsProvider.METRICS_UPDATE_EXECUTOR_IMPL)).isNull(); assertThat(config.get(KafkaStatisticsProvider.METRICS_UPDATE_INTERVAL_PARAM)).isNull(); }
@Test public void configureKafkaMetrics_withGaugeServiceAndInterval() { Map<String, Object> config = new HashMap<>(); assertThat(config).isEmpty(); GaugeService gaugeService = mockGaugeService(); Long universalAnswer = 42L; KafkaConfigUtils.configureKafkaMetrics(config, gaugeService, null, null, universalAnswer); assertThat(config).hasSize(3); assertThat(config.get(CommonClientConfigs.METRIC_REPORTER_CLASSES_CONFIG)) .asList() .contains(KafkaStatisticsProvider.class.getCanonicalName()); assertThat(config.get(KafkaStatisticsProvider.METRICS_GAUGE_SERVICE_IMPL)).isSameAs(gaugeService); assertThat(config.get(KafkaStatisticsProvider.METRICS_PREFIX_PARAM)).isNull(); assertThat(config.get(KafkaStatisticsProvider.METRICS_UPDATE_EXECUTOR_IMPL)).isNull(); assertThat(config.get(KafkaStatisticsProvider.METRICS_UPDATE_INTERVAL_PARAM)).isEqualTo(universalAnswer); }
@Test public void configureKafkaMetrics_withGaugeServiceAndExecutors() { ScheduledExecutorService executors = Executors.newSingleThreadScheduledExecutor(); try { Map<String, Object> config = new HashMap<>(); assertThat(config).isEmpty(); GaugeService gaugeService = mockGaugeService(); KafkaConfigUtils.configureKafkaMetrics(config, gaugeService, null, executors, null); assertThat(config).hasSize(3); assertThat(config.get(CommonClientConfigs.METRIC_REPORTER_CLASSES_CONFIG)) .asList() .contains(KafkaStatisticsProvider.class.getCanonicalName()); assertThat(config.get(KafkaStatisticsProvider.METRICS_GAUGE_SERVICE_IMPL)).isSameAs(gaugeService); assertThat(config.get(KafkaStatisticsProvider.METRICS_PREFIX_PARAM)).isNull(); assertThat(config.get(KafkaStatisticsProvider.METRICS_UPDATE_EXECUTOR_IMPL)).isSameAs(executors); assertThat(config.get(KafkaStatisticsProvider.METRICS_UPDATE_INTERVAL_PARAM)).isNull(); } finally { executors.shutdown(); } }
@Test public void dropwizardInstalledIfPresent() { this.context = new AnnotationConfigApplicationContext( MetricsDropwizardAutoConfiguration.class, MetricRepositoryAutoConfiguration.class, AopAutoConfiguration.class); GaugeService gaugeService = this.context.getBean(GaugeService.class); assertNotNull(gaugeService); gaugeService.submit("foo", 2.7); DropwizardMetricServices exporter = this.context .getBean(DropwizardMetricServices.class); assertEquals(gaugeService, exporter); MetricRegistry registry = this.context.getBean(MetricRegistry.class); @SuppressWarnings("unchecked") Gauge<Double> gauge = (Gauge<Double>) registry.getMetrics().get("gauge.foo"); assertEquals(new Double(2.7), gauge.getValue()); }
@Test public void provideAdditionalWriter() { this.context = new AnnotationConfigApplicationContext(WriterConfig.class, MetricRepositoryAutoConfiguration.class, MetricExportAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); GaugeService gaugeService = this.context.getBean(GaugeService.class); assertNotNull(gaugeService); gaugeService.submit("foo", 2.7); MetricExporters exporters = this.context.getBean(MetricExporters.class); MetricCopyExporter exporter = (MetricCopyExporter) exporters.getExporters() .get("writer"); exporter.setIgnoreTimestamps(true); exporter.export(); MetricWriter writer = this.context.getBean("writer", MetricWriter.class); Mockito.verify(writer, Mockito.atLeastOnce()).set(Matchers.any(Metric.class)); }
@Autowired public TimerAspect(GaugeService gaugeService, CounterService counterService, ObjectMapper mapper) { this.counterService = counterService; this.gaugeService = gaugeService; this.mapper = mapper; }
public AbstractPartMetrics(CounterService counterService, GaugeService gaugeService, P properties) { this.properties = properties; this.prefix = properties.getPrefix() + "."; this.counterService = new PrefixCounterServiceDecorator(counterService, prefix); this.gaugeService = new PrefixGaugeServiceDecorator(gaugeService, prefix); this.counterService.increment("instances.active"); this.counterService.increment("instances.total"); }
ActuateCollectorMetrics(CounterService counterService, GaugeService gaugeService, @Nullable String transport) { this.counterService = counterService; this.gaugeService = gaugeService; String footer = transport == null ? "" : "." + transport; this.messages = "zipkin_collector.messages" + footer; this.messagesDropped = "zipkin_collector.messages_dropped" + footer; this.messageBytes = "zipkin_collector.message_bytes" + footer; this.messageSpans = "zipkin_collector.message_spans" + footer; this.bytes = "zipkin_collector.bytes" + footer; this.spans = "zipkin_collector.spans" + footer; this.spansDropped = "zipkin_collector.spans_dropped" + footer; }
@Bean @ConditionalOnMissingBean({ DropwizardMetricServices.class, CounterService.class, GaugeService.class }) public DropwizardMetricServices dropwizardMetricServices( MetricRegistry metricRegistry) { return new DropwizardMetricServices(metricRegistry); }
@Test public void createServices() throws Exception { this.context = new AnnotationConfigApplicationContext( MetricRepositoryAutoConfiguration.class); GaugeService gaugeService = this.context.getBean(BufferGaugeService.class); assertThat(gaugeService).isNotNull(); assertThat(this.context.getBean(BufferCounterService.class)).isNotNull(); assertThat(this.context.getBean(PrefixMetricReader.class)).isNotNull(); gaugeService.submit("foo", 2.7); MetricReader bean = this.context.getBean(MetricReader.class); assertThat(bean.findOne("gauge.foo").getValue()).isEqualTo(2.7); }
@Test public void recordsHttpInteractionsWithTemplateVariable() throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( Config.class, MetricFilterAutoConfiguration.class); Filter filter = context.getBean(Filter.class); MockMvc mvc = MockMvcBuilders.standaloneSetup(new MetricFilterTestController()) .addFilter(filter).build(); mvc.perform(get("/templateVarTest/foo")).andExpect(status().isOk()); verify(context.getBean(CounterService.class)) .increment("status.200.templateVarTest.someVariable"); verify(context.getBean(GaugeService.class)) .submit(eq("response.templateVarTest.someVariable"), anyDouble()); context.close(); }
@Test public void recordsKnown404HttpInteractionsAsSingleMetricWithPathAndTemplateVariable() throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( Config.class, MetricFilterAutoConfiguration.class); Filter filter = context.getBean(Filter.class); MockMvc mvc = MockMvcBuilders.standaloneSetup(new MetricFilterTestController()) .addFilter(filter).build(); mvc.perform(get("/knownPath/foo")).andExpect(status().isNotFound()); verify(context.getBean(CounterService.class)) .increment("status.404.knownPath.someVariable"); verify(context.getBean(GaugeService.class)) .submit(eq("response.knownPath.someVariable"), anyDouble()); context.close(); }
@Test public void records404HttpInteractionsAsSingleMetric() throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( Config.class, MetricFilterAutoConfiguration.class); Filter filter = context.getBean(Filter.class); MockMvc mvc = MockMvcBuilders.standaloneSetup(new MetricFilterTestController()) .addFilter(filter).build(); mvc.perform(get("/unknownPath/1")).andExpect(status().isNotFound()); mvc.perform(get("/unknownPath/2")).andExpect(status().isNotFound()); verify(context.getBean(CounterService.class), times(2)) .increment("status.404.unmapped"); verify(context.getBean(GaugeService.class), times(2)) .submit(eq("response.unmapped"), anyDouble()); context.close(); }
@Test public void additionallyRecordsMetricsWithHttpMethodNameIfConfigured() throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(Config.class, MetricFilterAutoConfiguration.class); EnvironmentTestUtils.addEnvironment(context, "endpoints.metrics.filter.gauge-submissions=merged,per-http-method", "endpoints.metrics.filter.counter-submissions=merged,per-http-method"); context.refresh(); Filter filter = context.getBean(Filter.class); final MockHttpServletRequest request = new MockHttpServletRequest("PUT", "/test/path"); final MockHttpServletResponse response = new MockHttpServletResponse(); FilterChain chain = mock(FilterChain.class); willAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { response.setStatus(200); return null; } }).given(chain).doFilter(request, response); filter.doFilter(request, response, chain); verify(context.getBean(GaugeService.class)).submit(eq("response.test.path"), anyDouble()); verify(context.getBean(GaugeService.class)).submit(eq("response.PUT.test.path"), anyDouble()); verify(context.getBean(CounterService.class)) .increment(eq("status.200.test.path")); verify(context.getBean(CounterService.class)) .increment(eq("status.PUT.200.test.path")); context.close(); }
@Test public void metricsFlushAutomatically() throws Exception { this.context = new AnnotationConfigApplicationContext(WriterConfig.class, MetricRepositoryAutoConfiguration.class, MetricExportAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); GaugeService gaugeService = this.context.getBean(GaugeService.class); assertThat(gaugeService).isNotNull(); gaugeService.submit("foo", 2.7); MetricExporters flusher = this.context.getBean(MetricExporters.class); flusher.close(); // this will be called by Spring on shutdown MetricWriter writer = this.context.getBean("writer", MetricWriter.class); Mockito.verify(writer, Mockito.atLeastOnce()).set(Matchers.any(Metric.class)); }