/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF 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 org.apache.flink.dropwizard; import com.codahale.metrics.ScheduledReporter; import org.apache.flink.api.common.JobID; import org.apache.flink.configuration.ConfigConstants; import org.apache.flink.configuration.Configuration; import org.apache.flink.configuration.MetricOptions; import org.apache.flink.dropwizard.metrics.DropwizardMeterWrapper; import org.apache.flink.metrics.Counter; import org.apache.flink.metrics.Gauge; import org.apache.flink.metrics.Histogram; import org.apache.flink.metrics.HistogramStatistics; import org.apache.flink.metrics.Meter; import org.apache.flink.metrics.MetricConfig; import org.apache.flink.metrics.MetricGroup; import org.apache.flink.metrics.SimpleCounter; import org.apache.flink.metrics.groups.UnregisteredMetricsGroup; import org.apache.flink.metrics.reporter.MetricReporter; import org.apache.flink.runtime.metrics.MetricRegistry; import org.apache.flink.runtime.metrics.MetricRegistryConfiguration; import org.apache.flink.runtime.metrics.groups.TaskManagerJobMetricGroup; import org.apache.flink.runtime.metrics.groups.TaskManagerMetricGroup; import org.apache.flink.runtime.metrics.groups.TaskMetricGroup; import org.apache.flink.util.AbstractID; import org.junit.Test; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class ScheduledDropwizardReporterTest { @Test public void testInvalidCharacterReplacement() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { ScheduledDropwizardReporter reporter = new ScheduledDropwizardReporter() { @Override public ScheduledReporter getReporter(MetricConfig config) { return null; } }; assertEquals("abc", reporter.filterCharacters("abc")); assertEquals("a--b-c-", reporter.filterCharacters("a..b.c.")); assertEquals("ab-c", reporter.filterCharacters("a\"b.c")); } /** * Tests that the registered metrics' names don't contain invalid characters. */ @Test public void testAddingMetrics() throws NoSuchFieldException, IllegalAccessException { Configuration configuration = new Configuration(); String taskName = "test\"Ta\"..sk"; String jobName = "testJ\"ob:-!ax..?"; String hostname = "loc<>al\"::host\".:"; String taskManagerId = "tas:kMana::ger"; String counterName = "testCounter"; configuration.setString(MetricOptions.REPORTERS_LIST, "test"); configuration.setString( ConfigConstants.METRICS_REPORTER_PREFIX + "test." + ConfigConstants.METRICS_REPORTER_CLASS_SUFFIX, "org.apache.flink.dropwizard.ScheduledDropwizardReporterTest$TestingScheduledDropwizardReporter"); configuration.setString(MetricOptions.SCOPE_NAMING_TASK, "<host>.<tm_id>.<job_name>"); configuration.setString(MetricOptions.SCOPE_DELIMITER, "_"); MetricRegistryConfiguration metricRegistryConfiguration = MetricRegistryConfiguration.fromConfiguration(configuration); MetricRegistry metricRegistry = new MetricRegistry(metricRegistryConfiguration); char delimiter = metricRegistry.getDelimiter(); TaskManagerMetricGroup tmMetricGroup = new TaskManagerMetricGroup(metricRegistry, hostname, taskManagerId); TaskManagerJobMetricGroup tmJobMetricGroup = new TaskManagerJobMetricGroup(metricRegistry, tmMetricGroup, new JobID(), jobName); TaskMetricGroup taskMetricGroup = new TaskMetricGroup(metricRegistry, tmJobMetricGroup, new AbstractID(), new AbstractID(), taskName, 0, 0); SimpleCounter myCounter = new SimpleCounter(); com.codahale.metrics.Meter dropwizardMeter = new com.codahale.metrics.Meter(); DropwizardMeterWrapper meterWrapper = new DropwizardMeterWrapper(dropwizardMeter); taskMetricGroup.counter(counterName, myCounter); taskMetricGroup.meter("meter", meterWrapper); List<MetricReporter> reporters = metricRegistry.getReporters(); assertTrue(reporters.size() == 1); MetricReporter metricReporter = reporters.get(0); assertTrue("Reporter should be of type ScheduledDropwizardReporter", metricReporter instanceof ScheduledDropwizardReporter); TestingScheduledDropwizardReporter reporter = (TestingScheduledDropwizardReporter) metricReporter; Map<Counter, String> counters = reporter.getCounters(); assertTrue(counters.containsKey(myCounter)); Map<Meter, String> meters = reporter.getMeters(); assertTrue(meters.containsKey(meterWrapper)); String expectedCounterName = reporter.filterCharacters(hostname) + delimiter + reporter.filterCharacters(taskManagerId) + delimiter + reporter.filterCharacters(jobName) + delimiter + reporter.filterCharacters(counterName); assertEquals(expectedCounterName, counters.get(myCounter)); metricRegistry.shutdown(); } /** * This test verifies that metrics are properly added and removed to/from the ScheduledDropwizardReporter and * the underlying Dropwizard MetricRegistry. */ @Test public void testMetricCleanup() { TestingScheduledDropwizardReporter rep = new TestingScheduledDropwizardReporter(); MetricGroup mp = new UnregisteredMetricsGroup(); Counter c = new SimpleCounter(); Meter m = new Meter() { @Override public void markEvent() { } @Override public void markEvent(long n) { } @Override public double getRate() { return 0; } @Override public long getCount() { return 0; } }; Histogram h = new Histogram() { @Override public void update(long value) { } @Override public long getCount() { return 0; } @Override public HistogramStatistics getStatistics() { return null; } }; Gauge g = new Gauge() { @Override public Object getValue() { return null; } }; rep.notifyOfAddedMetric(c, "counter", mp); assertEquals(1, rep.getCounters().size()); assertEquals(1, rep.registry.getCounters().size()); rep.notifyOfAddedMetric(m, "meter", mp); assertEquals(1, rep.getMeters().size()); assertEquals(1, rep.registry.getMeters().size()); rep.notifyOfAddedMetric(h, "histogram", mp); assertEquals(1, rep.getHistograms().size()); assertEquals(1, rep.registry.getHistograms().size()); rep.notifyOfAddedMetric(g, "gauge", mp); assertEquals(1, rep.getGauges().size()); assertEquals(1, rep.registry.getGauges().size()); rep.notifyOfRemovedMetric(c, "counter", mp); assertEquals(0, rep.getCounters().size()); assertEquals(0, rep.registry.getCounters().size()); rep.notifyOfRemovedMetric(m, "meter", mp); assertEquals(0, rep.getMeters().size()); assertEquals(0, rep.registry.getMeters().size()); rep.notifyOfRemovedMetric(h, "histogram", mp); assertEquals(0, rep.getHistograms().size()); assertEquals(0, rep.registry.getHistograms().size()); rep.notifyOfRemovedMetric(g, "gauge", mp); assertEquals(0, rep.getGauges().size()); assertEquals(0, rep.registry.getGauges().size()); } public static class TestingScheduledDropwizardReporter extends ScheduledDropwizardReporter { @Override public ScheduledReporter getReporter(MetricConfig config) { return null; } @Override public void close() { // don't do anything } } }