/** * Copyright 2013 Netflix, Inc. * <p/> * 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 * <p/> * http://www.apache.org/licenses/LICENSE-2.0 * <p/> * 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 com.netflix.servo.publish; import com.netflix.servo.Metric; import com.netflix.servo.annotations.DataSourceType; import com.netflix.servo.tag.Tags; import org.testng.annotations.Test; import javax.management.MBeanServer; import javax.management.ObjectName; import java.lang.management.ManagementFactory; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import static com.netflix.servo.publish.BasicMetricFilter.MATCH_ALL; import static com.netflix.servo.publish.BasicMetricFilter.MATCH_NONE; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; public class JmxMetricPollerTest { @Test public void testBasic() throws Exception { MetricPoller poller = new JmxMetricPoller( new LocalJmxConnector(), new ObjectName("java.lang:type=OperatingSystem"), MATCH_NONE); boolean found = false; List<Metric> metrics = poller.poll(MATCH_ALL); for (Metric m : metrics) { if ("AvailableProcessors".equals(m.getConfig().getName())) { found = true; Map<String, String> tags = m.getConfig().getTags().asMap(); assertEquals(tags.get("JmxDomain"), "java.lang"); assertEquals(tags.get("Jmx.type"), "OperatingSystem"); assertEquals(tags.get("ClassName"), "com.netflix.servo.publish.JmxMetricPoller"); assertEquals(tags.get(DataSourceType.KEY), "GAUGE"); } } assertTrue(found); } @Test public void testCounterFilter() throws Exception { MetricPoller poller = new JmxMetricPoller( new LocalJmxConnector(), new ObjectName("java.lang:type=OperatingSystem"), MATCH_ALL); boolean found = false; List<Metric> metrics = poller.poll(MATCH_ALL); for (Metric m : metrics) { if ("AvailableProcessors".equals(m.getConfig().getName())) { found = true; Map<String, String> tags = m.getConfig().getTags().asMap(); assertEquals(tags.get("JmxDomain"), "java.lang"); assertEquals(tags.get("Jmx.type"), "OperatingSystem"); assertEquals(tags.get("ClassName"), "com.netflix.servo.publish.JmxMetricPoller"); assertEquals(tags.get(DataSourceType.KEY), "COUNTER"); } } assertTrue(found); } /** * Tabular JMX values are very useful for cases where we want the same behavior as CompositePath but we * don't know up front what the values are going to be. */ @Test public void testTabularData() throws Exception { MapMXBean mapMXBean = new MapMXBean(); try { MetricPoller poller = new JmxMetricPoller( new LocalJmxConnector(), new ObjectName("com.netflix.servo.test:*"), MATCH_ALL); List<Metric> metrics = poller.poll(config -> config.getName().equals("Count")); assertEquals(metrics.size(), 2); Map<String, Integer> values = new HashMap<>(); for (Metric m : metrics) { values.put(m.getConfig().getTags().getTag("JmxCompositePath").getValue(), (Integer) m.getValue()); } assertEquals(values.get("Entry1"), (Integer) 111); assertEquals(values.get("Entry2"), (Integer) 222); } finally { mapMXBean.destroy(); } } public interface TestMapMXBean { Map<String, Integer> getCount(); String getStringValue(); } public static class MapMXBean implements TestMapMXBean { private final ObjectName objectName; MapMXBean() throws Exception { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); objectName = new ObjectName("com.netflix.servo.test", "Test", "Obj"); destroy(); mbs.registerMBean(this, objectName); } public void destroy() throws Exception { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); if (mbs.isRegistered(objectName)) { mbs.unregisterMBean(objectName); } } @Override public Map<String, Integer> getCount() { Map<String, Integer> map = new HashMap<>(); map.put("Entry1", 111); map.put("Entry2", 222); return map; } @Override public String getStringValue() { return "AStringResult"; } } @Test public void testDefaultTags() throws Exception { MetricPoller poller = new JmxMetricPoller( new LocalJmxConnector(), Collections.singletonList(new ObjectName("java.lang:type=OperatingSystem")), MATCH_ALL, true, Collections.singletonList(Tags.newTag("HostName", "localhost"))); List<Metric> metrics = poller.poll(MATCH_ALL); for (Metric m : metrics) { Map<String, String> tags = m.getConfig().getTags().asMap(); assertEquals(tags.get("HostName"), "localhost"); } } @Test public void testNonNumericMetrics() throws Exception { MapMXBean mapMXBean = new MapMXBean(); try { MetricPoller poller = new JmxMetricPoller( new LocalJmxConnector(), Collections.singletonList(new ObjectName("com.netflix.servo.test:*")), MATCH_ALL, false, null); List<Metric> metrics = poller.poll(config -> config.getName().equals("StringValue")); assertEquals(metrics.size(), 1); assertEquals(metrics.get(0).getValue(), "AStringResult"); } finally { mapMXBean.destroy(); } } }