Repository: ambari Updated Branches: refs/heads/trunk 79be85886 -> f42378ec9
AMBARI-8662 Incorrect / Missing metrics data (dsen) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f42378ec Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f42378ec Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f42378ec Branch: refs/heads/trunk Commit: f42378ec9123626a6dbb21fdb04062c52759c776 Parents: 79be858 Author: Dmytro Sen <d...@apache.org> Authored: Thu Dec 11 19:16:22 2014 +0200 Committer: Dmytro Sen <d...@apache.org> Committed: Thu Dec 11 19:34:33 2014 +0200 ---------------------------------------------------------------------- .../src/main/python/core/host_info.py | 68 ++- .../src/test/python/core/TestHostInfo.py | 51 +- .../timeline/HBaseTimelineMetricStore.java | 10 +- .../metrics/timeline/PhoenixHBaseAccessor.java | 6 +- .../metrics/timeline/PhoenixTransactSQL.java | 67 +++ .../timeline/TestPhoenixTransactSQL.java | 62 +++ .../metrics/timeline/AMSPropertyProvider.java | 43 +- .../templates/hadoop-metrics2.properties.j2 | 2 + .../timeline/AMSPropertyProviderTest.java | 59 ++- .../ams/multiple_component_regexp_metrics.json | 498 +++++++++++++++++++ 10 files changed, 811 insertions(+), 55 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/f42378ec/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/core/host_info.py ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/core/host_info.py b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/core/host_info.py index 5bc4afb..43c3a41 100644 --- a/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/core/host_info.py +++ b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/core/host_info.py @@ -24,6 +24,8 @@ import os from collections import namedtuple import platform import socket +import time +import threading logger = logging.getLogger() @@ -35,23 +37,28 @@ pass class HostInfo(): - + def __init__(self): + self.__last_network_io_time = 0; + self.__last_network_data = {} + self.__last_network_lock = threading.Lock() def get_cpu_times(self): """ Return cpu stats at current time """ - cpu_times = psutil.cpu_times() + cpu_times = psutil.cpu_times_percent() load_avg = os.getloadavg() + number2percents = lambda x: x * 100 + return { - 'cpu_user' : cpu_times.user if hasattr(cpu_times, 'user') else '', - 'cpu_system' : cpu_times.system if hasattr(cpu_times, 'system') else '', - 'cpu_idle' : cpu_times.idle if hasattr(cpu_times, 'idle') else '', - 'cpu_nice' : cpu_times.nice if hasattr(cpu_times, 'nice') else '', - 'cpu_wio' : cpu_times.iowait if hasattr(cpu_times, 'iowait') else '', - 'cpu_intr' : cpu_times.irq if hasattr(cpu_times, 'irq') else '', - 'cpu_sintr' : cpu_times.softirq if hasattr(cpu_times, 'softirq') else '', + 'cpu_user': number2percents(cpu_times.user) if hasattr(cpu_times, 'user') else '', + 'cpu_system': number2percents(cpu_times.system) if hasattr(cpu_times, 'system') else '', + 'cpu_idle': number2percents(cpu_times.idle) if hasattr(cpu_times, 'idle') else '', + 'cpu_nice': number2percents(cpu_times.nice) if hasattr(cpu_times, 'nice') else '', + 'cpu_wio': number2percents(cpu_times.iowait) if hasattr(cpu_times, 'iowait') else '', + 'cpu_intr': number2percents(cpu_times.irq) if hasattr(cpu_times, 'irq') else '', + 'cpu_sintr': number2percents(cpu_times.softirq) if hasattr(cpu_times, 'softirq') else '', 'load_one' : load_avg[0] if len(load_avg) > 0 else '', 'load_five' : load_avg[1] if len(load_avg) > 1 else '', 'load_fifteen' : load_avg[2] if len(load_avg) > 2 else '' @@ -90,12 +97,14 @@ class HostInfo(): swap_stats = psutil.swap_memory() disk_usage = self.get_combined_disk_usage() + bytes2kilobytes = lambda x: x / 1024 + return { - 'mem_free' : mem_stats.free if hasattr(mem_stats, 'free') else '', - 'mem_shared' : mem_stats.shared if hasattr(mem_stats, 'shared') else '', - 'mem_buffered' : mem_stats.buffers if hasattr(mem_stats, 'buffers') else '', - 'mem_cached' : mem_stats.cached if hasattr(mem_stats, 'cached') else '', - 'swap_free' : swap_stats.free if hasattr(mem_stats, 'free') else '', + 'mem_free': bytes2kilobytes(mem_stats.free) if hasattr(mem_stats, 'free') else '', + 'mem_shared': bytes2kilobytes(mem_stats.shared) if hasattr(mem_stats, 'shared') else '', + 'mem_buffered': bytes2kilobytes(mem_stats.buffers) if hasattr(mem_stats, 'buffers') else '', + 'mem_cached': bytes2kilobytes(mem_stats.cached) if hasattr(mem_stats, 'cached') else '', + 'swap_free': bytes2kilobytes(swap_stats.free) if hasattr(swap_stats, 'free') else '', 'disk_free' : disk_usage.get("disk_free"), # todo: cannot send string #'part_max_used' : disk_usage.get("max_part_used")[0], @@ -107,14 +116,31 @@ class HostInfo(): """ Return network counters """ - net_stats = psutil.net_io_counters() - return { - 'bytes_out' : net_stats.bytes_sent, - 'bytes_in' : net_stats.bytes_recv, - 'pkts_out' : net_stats.packets_sent, - 'pkts_in' : net_stats.packets_recv - } + with self.__last_network_lock: + current_time = time.time() + delta = current_time - self.__last_network_io_time + self.__last_network_io_time = current_time + + if delta <= 0: + delta = float("inf") + + net_stats = psutil.net_io_counters(True) + new_net_stats = {} + for interface, values in net_stats.iteritems(): + if interface != 'lo': + new_net_stats = {'bytes_out': new_net_stats.get('bytes_out', 0) + values.bytes_sent, + 'bytes_in': new_net_stats.get('bytes_in', 0) + values.bytes_recv, + 'pkts_out': new_net_stats.get('pkts_out', 0) + values.packets_sent, + 'pkts_in': new_net_stats.get('pkts_in', 0) + values.packets_recv + } + + with self.__last_network_lock: + result = dict((k, (v - self.__last_network_data.get(k, 0)) / delta) for k, v in new_net_stats.iteritems()) + result = dict((k, 0 if v < 0 else v) for k, v in result.iteritems()) + self.__last_network_data = new_net_stats + + return result pass # Faster version http://git-wip-us.apache.org/repos/asf/ambari/blob/f42378ec/ambari-metrics/ambari-metrics-host-monitoring/src/test/python/core/TestHostInfo.py ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-host-monitoring/src/test/python/core/TestHostInfo.py b/ambari-metrics/ambari-metrics-host-monitoring/src/test/python/core/TestHostInfo.py index 757edbe..71aee86 100644 --- a/ambari-metrics/ambari-metrics-host-monitoring/src/test/python/core/TestHostInfo.py +++ b/ambari-metrics/ambari-metrics-host-monitoring/src/test/python/core/TestHostInfo.py @@ -29,30 +29,31 @@ logger = logging.getLogger() class TestHostInfo(TestCase): @patch("os.getloadavg") - @patch("psutil.cpu_times") + @patch("psutil.cpu_times_percent") def testCpuTimes(self, cp_mock, avg_mock): cp = cp_mock.return_value - cp.user = "user" - cp.system = "system" - cp.idle = "idle" - cp.nice = "nice" - cp.iowait = "iowait" - cp.irq = "irq" - cp.softirq = "softirq" + cp.user = 0.1 + cp.system = 0.1 + cp.idle = 0.7 + cp.nice = 0.1 + cp.iowait = 0 + cp.irq = 0 + cp.softirq = 0 + avg_mock.return_value = [13, 13, 13] hostinfo = HostInfo() cpu = hostinfo.get_cpu_times() - self.assertEqual(cpu['cpu_user'], 'user') - self.assertEqual(cpu['cpu_system'], 'system') - self.assertEqual(cpu['cpu_idle'], 'idle') - self.assertEqual(cpu['cpu_nice'], 'nice') - self.assertEqual(cpu['cpu_wio'], 'iowait') - self.assertEqual(cpu['cpu_intr'], 'irq') - self.assertEqual(cpu['cpu_sintr'], 'softirq') + self.assertAlmostEqual(cpu['cpu_user'], 10) + self.assertAlmostEqual(cpu['cpu_system'], 10) + self.assertAlmostEqual(cpu['cpu_idle'], 70) + self.assertAlmostEqual(cpu['cpu_nice'], 10) + self.assertAlmostEqual(cpu['cpu_wio'], 0) + self.assertAlmostEqual(cpu['cpu_intr'], 0) + self.assertAlmostEqual(cpu['cpu_sintr'], 0) self.assertEqual(cpu['load_one'], 13) self.assertEqual(cpu['load_five'], 13) self.assertEqual(cpu['load_fifteen'], 13) @@ -64,23 +65,23 @@ class TestHostInfo(TestCase): def testMemInfo(self, vm_mock, sw_mock, dm_mock, du_mock): vm = vm_mock.return_value - vm.free = "free" - vm.shared = "shared" - vm.buffers = "buffers" - vm.cached = "cached" + vm.free = 2312043 + vm.shared = 1243 + vm.buffers = 23435 + vm.cached = 23545 sw = sw_mock.return_value - sw.free = "free" + sw.free = 2341234 hostinfo = HostInfo() cpu = hostinfo.get_mem_info() - self.assertEqual(cpu['mem_free'], 'free') - self.assertEqual(cpu['mem_shared'], 'shared') - self.assertEqual(cpu['mem_buffered'], 'buffers') - self.assertEqual(cpu['mem_cached'], 'cached') - self.assertEqual(cpu['swap_free'], 'free') + self.assertAlmostEqual(cpu['mem_free'], 2257) + self.assertAlmostEqual(cpu['mem_shared'], 1) + self.assertAlmostEqual(cpu['mem_buffered'], 22) + self.assertAlmostEqual(cpu['mem_cached'], 22) + self.assertAlmostEqual(cpu['swap_free'], 2286) @patch("psutil.process_iter") http://git-wip-us.apache.org/repos/asf/ambari/blob/f42378ec/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/HBaseTimelineMetricStore.java ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/HBaseTimelineMetricStore.java b/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/HBaseTimelineMetricStore.java index 9364187..3a9c871 100644 --- a/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/HBaseTimelineMetricStore.java +++ b/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/HBaseTimelineMetricStore.java @@ -30,13 +30,15 @@ import java.io.IOException; import java.net.URL; import java.sql.SQLException; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.TreeMap; import static org.apache.hadoop.yarn.server.applicationhistoryservice.metrics .timeline.PhoenixTransactSQL.Condition; import static org.apache.hadoop.yarn.server.applicationhistoryservice.metrics + .timeline.PhoenixTransactSQL.LikeCondition; +import static org.apache.hadoop.yarn.server.applicationhistoryservice.metrics .timeline.TimelineMetricConfiguration.HBASE_SITE_CONFIGURATION_FILE; import static org.apache.hadoop.yarn.server.applicationhistoryservice.metrics .timeline.TimelineMetricConfiguration.METRICS_SITE_CONFIGURATION_FILE; @@ -136,7 +138,7 @@ public class HBaseTimelineMetricStore extends AbstractService Long startTime, Long endTime, Integer limit, boolean groupedByHosts) throws SQLException, IOException { - Condition condition = new Condition(metricNames, hostname, applicationId, + Condition condition = new LikeCondition(metricNames, hostname, applicationId, instanceId, startTime, endTime, limit, groupedByHosts); if (hostname == null) { @@ -153,7 +155,7 @@ public class HBaseTimelineMetricStore extends AbstractService throws SQLException, IOException { TimelineMetrics metrics = hBaseAccessor.getMetricRecords( - new Condition(Collections.singletonList(metricName), hostname, + new LikeCondition(Collections.singletonList(metricName), hostname, applicationId, instanceId, startTime, endTime, limit, true) ); @@ -167,7 +169,7 @@ public class HBaseTimelineMetricStore extends AbstractService metric.setHostName(metricList.get(0).getHostName()); // Assumption that metrics are ordered by start time metric.setStartTime(metricList.get(0).getStartTime()); - Map<Long, Double> metricRecords = new HashMap<Long, Double>(); + Map<Long, Double> metricRecords = new TreeMap<Long, Double>(); for (TimelineMetric timelineMetric : metricList) { metricRecords.putAll(timelineMetric.getMetricValues()); } http://git-wip-us.apache.org/repos/asf/ambari/blob/f42378ec/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixHBaseAccessor.java ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixHBaseAccessor.java b/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixHBaseAccessor.java index cb28a8b..9779e3b 100644 --- a/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixHBaseAccessor.java +++ b/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixHBaseAccessor.java @@ -38,6 +38,7 @@ import java.sql.Statement; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.TreeMap; import java.util.concurrent.TimeUnit; import static java.util.concurrent.TimeUnit.SECONDS; import static org.apache.hadoop.yarn.server.applicationhistoryservice.metrics.timeline.PhoenixTransactSQL.ALTER_SQL; @@ -162,8 +163,9 @@ public class PhoenixHBaseAccessor { metric.setTimestamp(rs.getLong("SERVER_TIME")); metric.setStartTime(rs.getLong("START_TIME")); metric.setType(rs.getString("UNITS")); - metric.setMetricValues( - (Map<Long, Double>) readMetricFromJSON(rs.getString("METRICS"))); + Map<Long, Double> sortedByTimeMetrics = + new TreeMap<Long, Double>((Map<Long, Double>) readMetricFromJSON(rs.getString("METRICS"))); + metric.setMetricValues(sortedByTimeMetrics); return metric; } http://git-wip-us.apache.org/repos/asf/ambari/blob/f42378ec/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixTransactSQL.java ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixTransactSQL.java b/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixTransactSQL.java index 93ba2d8..298a5cf 100644 --- a/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixTransactSQL.java +++ b/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixTransactSQL.java @@ -532,4 +532,71 @@ public class PhoenixTransactSQL { '}'; } } + + static class LikeCondition extends Condition { + + LikeCondition(List<String> metricNames, String hostname, + String appId, String instanceId, Long startTime, + Long endTime, Integer limit, boolean grouped) { + super(metricNames, hostname, appId, instanceId, startTime, endTime, + limit, grouped); + } + + @Override + String getConditionClause() { + StringBuilder sb = new StringBuilder(); + boolean appendConjunction = false; + + if (getMetricNames() != null) { + sb.append("("); + for (String name : metricNames) { + if (sb.length() > 1) { + sb.append(" OR "); + } + sb.append("METRIC_NAME LIKE ?"); + } + sb.append(")"); + appendConjunction = true; + } + if (appendConjunction) { + sb.append(" AND"); + } + appendConjunction = false; + if (getHostname() != null) { + sb.append(" HOSTNAME = ?"); + appendConjunction = true; + } + if (appendConjunction) { + sb.append(" AND"); + } + appendConjunction = false; + if (getAppId() != null) { + sb.append(" APP_ID = ?"); + appendConjunction = true; + } + if (appendConjunction) { + sb.append(" AND"); + } + appendConjunction = false; + if (getInstanceId() != null) { + sb.append(" INSTANCE_ID = ?"); + appendConjunction = true; + } + if (appendConjunction) { + sb.append(" AND"); + } + appendConjunction = false; + if (getStartTime() != null) { + sb.append(" SERVER_TIME >= ?"); + appendConjunction = true; + } + if (appendConjunction) { + sb.append(" AND"); + } + if (getEndTime() != null) { + sb.append(" SERVER_TIME < ?"); + } + return sb.toString(); + } + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/f42378ec/ambari-metrics/ambari-metrics-timelineservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/TestPhoenixTransactSQL.java ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-timelineservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/TestPhoenixTransactSQL.java b/ambari-metrics/ambari-metrics-timelineservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/TestPhoenixTransactSQL.java index 758f5a9..1659e46 100644 --- a/ambari-metrics/ambari-metrics-timelineservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/TestPhoenixTransactSQL.java +++ b/ambari-metrics/ambari-metrics-timelineservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/TestPhoenixTransactSQL.java @@ -21,8 +21,10 @@ import org.junit.Assert; import org.junit.Test; import java.util.Arrays; +import java.util.Collections; import static org.apache.hadoop.yarn.server.applicationhistoryservice.metrics.timeline.PhoenixTransactSQL.Condition; +import static org.apache.hadoop.yarn.server.applicationhistoryservice.metrics.timeline.PhoenixTransactSQL.LikeCondition; public class TestPhoenixTransactSQL { @Test @@ -39,5 +41,65 @@ public class TestPhoenixTransactSQL { Assert.assertEquals(expectedClause, preparedClause); } + @Test + public void testLikeConditionClause() throws Exception { + Condition condition = new LikeCondition( + Arrays.asList("cpu_user", "mem_free"), "h1", "a1", "i1", + 1407959718L, 1407959918L, null, false); + + String preparedClause = condition.getConditionClause(); + String expectedClause = "(METRIC_NAME LIKE ? OR METRIC_NAME LIKE ?) AND HOSTNAME = ? AND " + + "APP_ID = ? AND INSTANCE_ID = ? AND SERVER_TIME >= ? AND SERVER_TIME < ?"; + + Assert.assertNotNull(preparedClause); + Assert.assertEquals(expectedClause, preparedClause); + + + condition = new LikeCondition( + Collections.<String>emptyList(), "h1", "a1", "i1", + 1407959718L, 1407959918L, null, false); + + preparedClause = condition.getConditionClause(); + expectedClause = " HOSTNAME = ? AND " + + "APP_ID = ? AND INSTANCE_ID = ? AND SERVER_TIME >= ? AND SERVER_TIME < ?"; + + Assert.assertNotNull(preparedClause); + Assert.assertEquals(expectedClause, preparedClause); + + + condition = new LikeCondition( + null, "h1", "a1", "i1", + 1407959718L, 1407959918L, null, false); + + preparedClause = condition.getConditionClause(); + expectedClause = " HOSTNAME = ? AND " + + "APP_ID = ? AND INSTANCE_ID = ? AND SERVER_TIME >= ? AND SERVER_TIME < ?"; + Assert.assertNotNull(preparedClause); + Assert.assertEquals(expectedClause, preparedClause); + + + condition = new LikeCondition( + Arrays.asList("cpu_user"), "h1", "a1", "i1", + 1407959718L, 1407959918L, null, false); + + preparedClause = condition.getConditionClause(); + expectedClause = "(METRIC_NAME LIKE ?) AND HOSTNAME = ? AND " + + "APP_ID = ? AND INSTANCE_ID = ? AND SERVER_TIME >= ? AND SERVER_TIME < ?"; + + Assert.assertNotNull(preparedClause); + Assert.assertEquals(expectedClause, preparedClause); + + + condition = new LikeCondition( + Arrays.asList("cpu_user", "mem_free", "cpu_aidle"), "h1", "a1", "i1", + 1407959718L, 1407959918L, null, false); + + preparedClause = condition.getConditionClause(); + expectedClause = "(METRIC_NAME LIKE ? OR METRIC_NAME LIKE ? OR METRIC_NAME LIKE ?) AND HOSTNAME = ? AND " + + "APP_ID = ? AND INSTANCE_ID = ? AND SERVER_TIME >= ? AND SERVER_TIME < ?"; + + Assert.assertNotNull(preparedClause); + Assert.assertEquals(expectedClause, preparedClause); + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/f42378ec/ambari-server/src/main/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProvider.java index 50eb08e..3ecc4c7 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProvider.java @@ -58,6 +58,7 @@ public abstract class AMSPropertyProvider extends MetricsPropertyProvider { private static final DecimalFormat decimalFormat = new DecimalFormat("#.00"); private static final Set<String> PERCENTAGE_METRIC; + private static final String METRIC_REGEXP_PATTERN = "\\([^)]*\\)"; static { TIMELINE_APPID_MAP.put("HBASE_MASTER", "HBASE"); @@ -175,7 +176,7 @@ public abstract class AMSPropertyProvider extends MetricsPropertyProvider { return Collections.emptySet(); } - String metricsParam = getSetString(metrics.keySet(), -1); + String metricsParam = getSetString(processRegexps(metrics.keySet()), -1); // Reuse uriBuilder uriBuilder.removeQuery(); @@ -214,8 +215,11 @@ public abstract class AMSPropertyProvider extends MetricsPropertyProvider { TimelineMetrics timelineMetrics = timelineObjectReader.readValue(reader); LOG.debug("Timeline metrics response => " + timelineMetrics); + Set<String> patterns = createPatterns(metrics.keySet()); + for (TimelineMetric metric : timelineMetrics.getMetrics()) { - if (metric.getMetricName() != null && metric.getMetricValues() != null) { + if (metric.getMetricName() != null && metric.getMetricValues() != null + && checkMetricName(patterns, metric.getMetricName())) { populateResource(resource, metric); } } @@ -239,6 +243,41 @@ public abstract class AMSPropertyProvider extends MetricsPropertyProvider { return Collections.emptySet(); } + private Set<String> createPatterns(Set<String> rawNames) { + Pattern pattern = Pattern.compile(METRIC_REGEXP_PATTERN); + Set<String> result = new HashSet<String>(); + for (String rawName : rawNames) { + Matcher matcher = pattern.matcher(rawName); + StringBuilder sb = new StringBuilder(); + int lastPos = 0; + while (matcher.find()) { + sb.append(Pattern.quote(rawName.substring(lastPos, matcher.start()))); + sb.append(matcher.group()); + lastPos = matcher.end(); + } + sb.append(Pattern.quote(rawName.substring(lastPos))); + result.add(sb.toString()); + } + return result; + } + + private boolean checkMetricName(Set<String> patterns, String name) { + for (String pattern : patterns) { + if (Pattern.matches(pattern, name)) { + return true; + } + } + return false; + } + + private Set<String> processRegexps(Set<String> metricNames) { + Set<String> result = new HashSet<String>(); + for (String name : metricNames) { + result.add(name.replaceAll(METRIC_REGEXP_PATTERN, Matcher.quoteReplacement("%"))); + } + return result; + } + private void populateResource(Resource resource, TimelineMetric metric) { String metric_name = metric.getMetricName(); Set<String> propertyIdSet = metrics.get(metric_name); http://git-wip-us.apache.org/repos/asf/ambari/blob/f42378ec/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/templates/hadoop-metrics2.properties.j2 ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/templates/hadoop-metrics2.properties.j2 b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/templates/hadoop-metrics2.properties.j2 index d7a66ab..6af1a67 100644 --- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/templates/hadoop-metrics2.properties.j2 +++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/templates/hadoop-metrics2.properties.j2 @@ -80,4 +80,6 @@ supervisor.sink.timeline.collector={{metric_collector_host}}:8188 maptask.sink.timeline.collector={{metric_collector_host}}:8188 reducetask.sink.timeline.collector={{metric_collector_host}}:8188 +resourcemanager.sink.timeline.tagsForPrefix.yarn=Queue + {% endif %} http://git-wip-us.apache.org/repos/asf/ambari/blob/f42378ec/ambari-server/src/test/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProviderTest.java index 82f9aff..d9a028f 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProviderTest.java @@ -68,6 +68,7 @@ public class AMSPropertyProviderTest { private static final String SINGLE_COMPONENT_METRICS_FILE_PATH = FILE_PATH_PREFIX + "single_component_metrics.json"; private static final String MULTIPLE_COMPONENT_METRICS_FILE_PATH = FILE_PATH_PREFIX + "multiple_component_metrics.json"; private static final String CLUSTER_REPORT_METRICS_FILE_PATH = FILE_PATH_PREFIX + "cluster_report_metrics.json"; + private static final String MULTIPLE_COMPONENT_REGEXP_METRICS_FILE_PATH = FILE_PATH_PREFIX + "multiple_component_regexp_metrics.json"; @Test public void testPopulateResourcesForSingleHostMetric() throws Exception { @@ -142,7 +143,15 @@ public class AMSPropertyProviderTest { uriBuilder.addParameter("appId", "HOST"); uriBuilder.addParameter("startTime", "1416445244701"); uriBuilder.addParameter("endTime", "1416445244901"); - Assert.assertEquals(uriBuilder.toString(), streamProvider.getLastSpec()); + + URIBuilder uriBuilder2 = AMSPropertyProvider.getUriBuilder("localhost", 8188); + uriBuilder2.addParameter("metricNames", "mem_free,cpu_user"); + uriBuilder2.addParameter("hostname", "h1"); + uriBuilder2.addParameter("appId", "HOST"); + uriBuilder2.addParameter("startTime", "1416445244701"); + uriBuilder2.addParameter("endTime", "1416445244901"); + Assert.assertTrue(uriBuilder.toString().equals(streamProvider.getLastSpec()) + || uriBuilder2.toString().equals(streamProvider.getLastSpec())); Number[][] val = (Number[][]) res.getPropertyValue(PROPERTY_ID1); Assert.assertEquals(111, val.length); val = (Number[][]) res.getPropertyValue(PROPERTY_ID2); @@ -150,6 +159,54 @@ public class AMSPropertyProviderTest { } @Test + public void testPopulateResourcesForRegexpMetrics() throws Exception { + TestStreamProvider streamProvider = new TestStreamProvider(MULTIPLE_COMPONENT_REGEXP_METRICS_FILE_PATH); + TestMetricHostProvider metricHostProvider = new TestMetricHostProvider(); + ComponentSSLConfiguration sslConfiguration = mock(ComponentSSLConfiguration.class); + + Map<String, Map<String, PropertyInfo>> propertyIds = + new HashMap<String, Map<String, PropertyInfo>>() {{ + put("RESOURCEMANAGER", new HashMap<String, PropertyInfo>() {{ + put("metrics/yarn/Queue/$1.replaceAll(\"([.])\",\"/\")/AvailableMB", + new PropertyInfo("yarn.QueueMetrics.(.+).AvailableMB", true, false)); + }}); + }}; + + AMSPropertyProvider propertyProvider = new AMSComponentPropertyProvider( + propertyIds, + streamProvider, + sslConfiguration, + metricHostProvider, + CLUSTER_NAME_PROPERTY_ID, + COMPONENT_NAME_PROPERTY_ID + ); + + + String propertyId1 = "metrics/yarn/Queue/root/AvailableMB"; + Resource resource = new ResourceImpl(Resource.Type.Component); + resource.setProperty(HOST_NAME_PROPERTY_ID, "h1"); + resource.setProperty(COMPONENT_NAME_PROPERTY_ID, "RESOURCEMANAGER"); + Map<String, TemporalInfo> temporalInfoMap = new HashMap<String, TemporalInfo>(); + temporalInfoMap.put(propertyId1, new TemporalInfoImpl(1416528819369L, 1416528819569L, 1L)); + Request request = PropertyHelper.getReadRequest( + Collections.singleton(propertyId1), temporalInfoMap); + Set<Resource> resources = + propertyProvider.populateResources(Collections.singleton(resource), request, null); + Assert.assertEquals(1, resources.size()); + Resource res = resources.iterator().next(); + Map<String, Object> properties = PropertyHelper.getProperties(resources.iterator().next()); + Assert.assertNotNull(properties); + URIBuilder uriBuilder = AMSPropertyProvider.getUriBuilder("localhost", 8188); + uriBuilder.addParameter("metricNames", "yarn.QueueMetrics.%.AvailableMB"); + uriBuilder.addParameter("appId", "RESOURCEMANAGER"); + uriBuilder.addParameter("startTime", "1416528819369"); + uriBuilder.addParameter("endTime", "1416528819569"); + Assert.assertEquals(uriBuilder.toString(), streamProvider.getLastSpec()); + Number[][] val = (Number[][]) res.getPropertyValue("metrics/yarn/Queue/Queue=root/AvailableMB"); + Assert.assertEquals(238, val.length); + } + + @Test public void testPopulateResourcesForSingleComponentMetric() throws Exception { TestStreamProvider streamProvider = new TestStreamProvider(SINGLE_COMPONENT_METRICS_FILE_PATH); TestMetricHostProvider metricHostProvider = new TestMetricHostProvider(); http://git-wip-us.apache.org/repos/asf/ambari/blob/f42378ec/ambari-server/src/test/resources/ams/multiple_component_regexp_metrics.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/ams/multiple_component_regexp_metrics.json b/ambari-server/src/test/resources/ams/multiple_component_regexp_metrics.json new file mode 100644 index 0000000..393cc27 --- /dev/null +++ b/ambari-server/src/test/resources/ams/multiple_component_regexp_metrics.json @@ -0,0 +1,498 @@ +{"metrics": [ + { + "timestamp": 1416528819469, + "type": "Double", + "metricname": "yarn.QueueMetrics.Queue=root.PendingMB", + "appid": "resourcemanager", + "hostname": "h1", + "starttime": 1416528759233, + "metrics": { + "1416528759233": 10.333333333333332, + "1416528769232": 0.75, + "1416528779232": 0.16666666666666669, + "1416528789233": 0.2, + "1416528799232": 0.5, + "1416528809232": 1.6, + "1416528819233": 0.0, + "1416528829232": 0.0, + "1416528839232": 0.33333333333333337, + "1416528849232": 0.33333333333333337, + "1416528859232": 0.25, + "1416528869232": 0.0, + "1416528879232": 0.25, + "1416528889232": 1.0, + "1416528899232": 0.25, + "1416528909232": 0.5, + "1416528919232": 0.25, + "1416528929232": 0.6666666666666667, + "1416528939232": 0.33333333333333337, + "1416528949232": 0.25, + "1416528959233": 0.2, + "1416528969232": 0.25, + "1416528979232": 0.0, + "1416528989232": 0.4, + "1416528999232": 0.33333333333333337, + "1416529009232": 0.25, + "1416529019232": 0.0, + "1416529029232": 0.0, + "1416529039232": 0.0, + "1416529049232": 0.0, + "1416529059232": 0.2, + "1416529069232": 1.0, + "1416529079232": 0.5, + "1416529089232": 0.0, + "1416529099232": 0.0, + "1416529109232": 0.0, + "1416529119232": 0.5, + "1416529129232": 0.5, + "1416529139232": 0.0, + "1416529149232": 0.0, + "1416529159232": 0.5, + "1416529169232": 1.0, + "1416529179232": 0.4, + "1416529189232": 0.0, + "1416529199232": 0.4, + "1416529209232": 1.0, + "1416529219232": 0.25, + "1416529229232": 0.0, + "1416529239232": 0.0, + "1416529249231": 0.5, + "1416529259232": 0.0, + "1416529269232": 0.5, + "1416529279232": 0.0, + "1416529289232": 0.0, + "1416529299232": 0.4, + "1416529309232": 0.0, + "1416529319232": 0.0, + "1416529329232": 0.0, + "1416529339232": 0.25, + "1416529349232": 0.0, + "1416529359232": 0.0, + "1416529369232": 0.0, + "1416529379232": 0.0, + "1416529389233": 0.5, + "1416529399232": 1.0, + "1416529409232": 0.0, + "1416529419232": 0.2, + "1416529429232": 0.0, + "1416529439232": 0.5, + "1416529449232": 0.5, + "1416529459231": 0.5, + "1416529469232": 0.0, + "1416529479232": 0.33333333333333337, + "1416529489231": 0.25, + "1416529499232": 0.6, + "1416529509232": 0.25, + "1416529519232": 0.5, + "1416529529232": 0.0, + "1416529539232": 0.25, + "1416529549232": 0.25, + "1416529559232": 0.33333333333333337, + "1416529569232": 1.0, + "1416529579232": 0.0, + "1416529589232": 0.33333333333333337, + "1416529599232": 0.0, + "1416529609232": 1.0, + "1416529619232": 0.25, + "1416529629232": 0.25, + "1416529639232": 0.0, + "1416529649232": 0.6, + "1416529659232": 0.0, + "1416529669232": 0.25, + "1416529679231": 0.0, + "1416529689232": 0.5, + "1416529699232": 0.25, + "1416529709232": 0.3333333333333333, + "1416529719232": 1.0, + "1416529729232": 0.5, + "1416529739231": 0.4, + "1416529749232": 0.25, + "1416529759232": 0.0, + "1416529769231": 0.6, + "1416529779232": 0.5, + "1416529789232": 0.0, + "1416529799232": 0.0, + "1416529809232": 0.5, + "1416529819232": 0.0, + "1416529829232": 0.0, + "1416529839231": 0.2, + "1416529849232": 0.0, + "1416529859232": 0.0, + "1416529869231": 0.25, + "1416529879232": 0.0, + "1416529889231": 0.6666666666666666, + "1416529899233": 0.0, + "1416529909232": 0.25, + "1416529919232": 0.0, + "1416529929232": 0.0, + "1416529939232": 0.5, + "1416529949232": 0.0, + "1416529959232": 0.4, + "1416529969231": 0.5, + "1416529979232": 0.25, + "1416529989232": 0.5, + "1416529999232": 0.5, + "1416530009232": 0.0, + "1416530019232": 0.5, + "1416530029232": 0.0, + "1416530039232": 0.5, + "1416530049232": 0.5, + "1416530059233": 0.0, + "1416530069232": 0.0, + "1416530079232": 0.0, + "1416530089232": 0.0, + "1416530099232": 0.2, + "1416530109232": 0.0, + "1416530119232": 0.75, + "1416530129232": 0.33333333333333337, + "1416530139232": 1.0, + "1416530149232": 0.5, + "1416530159233": 0.25, + "1416530169232": 0.12500000000000003, + "1416530179232": 0.5, + "1416530189233": 0.14285714285714288, + "1416530199232": 0.33333333333333337, + "1416530209231": 0.33333333333333337, + "1416530219232": 0.5, + "1416530229232": 0.25000000000000006, + "1416530239231": 0.0, + "1416530249232": 0.14285714285714288, + "1416530259232": 0.25000000000000006, + "1416530269232": 0.5714285714285714, + "1416530279232": 0.28571428571428575, + "1416530289232": 0.375, + "1416530299232": 0.33333333333333337, + "1416530309232": 0.14285714285714288, + "1416530319232": 0.4444444444444444, + "1416530329232": 0.0, + "1416530339232": 0.33333333333333337, + "1416530349232": 0.0, + "1416530359232": 0.16666666666666669, + "1416530369232": 0.28571428571428575, + "1416530379232": 0.3333333333333333, + "1416530389231": 0.5, + "1416530399232": 0.33333333333333337, + "1416530409232": 0.375, + "1416530419232": 0.16666666666666669, + "1416530429231": 0.0, + "1416530439232": 0.2222222222222222, + "1416530449232": 0.16666666666666669, + "1416530459232": 0.28571428571428575, + "1416530469232": 0.125, + "1416530479232": 0.33333333333333337, + "1416530489232": 0.4285714285714286, + "1416530499232": 0.375, + "1416530509232": 0.2857142857142857, + "1416530519232": 0.33333333333333337, + "1416530529232": 0.12500000000000003, + "1416530539232": 0.8333333333333334, + "1416530549232": 0.4285714285714286, + "1416530559232": 0.11111111111111113, + "1416530569232": 0.16666666666666669, + "1416530579232": 0.16666666666666669, + "1416530589232": 0.375, + "1416530599231": 0.0, + "1416530609232": 0.28571428571428575, + "1416530619232": 0.33333333333333337, + "1416530629232": 0.0, + "1416530639232": 0.0, + "1416530649232": 0.25, + "1416530659232": 0.33333333333333337, + "1416530669232": 0.14285714285714288, + "1416530679232": 0.33333333333333337, + "1416530689232": 0.16666666666666669, + "1416530699231": 0.6666666666666666, + "1416530709232": 0.0, + "1416530719232": 0.33333333333333337, + "1416530729232": 0.4285714285714286, + "1416530739232": 0.25, + "1416530749232": 0.0, + "1416530759232": 0.16666666666666669, + "1416530769232": 0.25, + "1416530779232": 0.16666666666666669, + "1416530789232": 0.4285714285714286, + "1416530799232": 0.11111111111111113, + "1416530809232": 0.0, + "1416530819232": 0.28571428571428575, + "1416530829232": 0.375, + "1416530839231": 0.33333333333333337, + "1416530849232": 0.4285714285714286, + "1416530859232": 0.0, + "1416530869232": 0.33333333333333337, + "1416530879232": 0.33333333333333337, + "1416530889232": 0.125, + "1416530899232": 0.5, + "1416530909232": 0.14285714285714288, + "1416530919232": 0.4444444444444444, + "1416530929232": 0.0, + "1416530939232": 0.33333333333333337, + "1416530949232": 0.25000000000000006, + "1416530959232": 0.33333333333333337, + "1416530969232": 0.0, + "1416530979232": 0.375, + "1416530989232": 0.14285714285714288, + "1416530999232": 0.4285714285714286, + "1416531009232": 0.375, + "1416531019232": 0.33333333333333337, + "1416531029232": 0.28571428571428575, + "1416531039232": 0.22222222222222227, + "1416531049232": 0.5, + "1416531059232": 0.0, + "1416531069232": 0.5, + "1416531079232": 0.0, + "1416531089232": 1.0, + "1416531099232": 0.0, + "1416531109232": 0.0, + "1416531119232": 0.0, + "1416531129231": 0.0 + } + }, + { + "timestamp": 1416528819469, + "type": "Double", + "metricname": "yarn.QueueMetrics.Queue=root.AvailableMB", + "appid": "resourcemanager", + "hostname": "h1", + "starttime": 1416528759233, + "metrics": { + "1416528759233": 10.333333333333332, + "1416528769232": 0.75, + "1416528779232": 0.16666666666666669, + "1416528789233": 0.2, + "1416528799232": 0.5, + "1416528809232": 1.6, + "1416528819233": 0.0, + "1416528829232": 0.0, + "1416528839232": 0.33333333333333337, + "1416528849232": 0.33333333333333337, + "1416528859232": 0.25, + "1416528869232": 0.0, + "1416528879232": 0.25, + "1416528889232": 1.0, + "1416528899232": 0.25, + "1416528909232": 0.5, + "1416528919232": 0.25, + "1416528929232": 0.6666666666666667, + "1416528939232": 0.33333333333333337, + "1416528949232": 0.25, + "1416528959233": 0.2, + "1416528969232": 0.25, + "1416528979232": 0.0, + "1416528989232": 0.4, + "1416528999232": 0.33333333333333337, + "1416529009232": 0.25, + "1416529019232": 0.0, + "1416529029232": 0.0, + "1416529039232": 0.0, + "1416529049232": 0.0, + "1416529059232": 0.2, + "1416529069232": 1.0, + "1416529079232": 0.5, + "1416529089232": 0.0, + "1416529099232": 0.0, + "1416529109232": 0.0, + "1416529119232": 0.5, + "1416529129232": 0.5, + "1416529139232": 0.0, + "1416529149232": 0.0, + "1416529159232": 0.5, + "1416529169232": 1.0, + "1416529179232": 0.4, + "1416529189232": 0.0, + "1416529199232": 0.4, + "1416529209232": 1.0, + "1416529219232": 0.25, + "1416529229232": 0.0, + "1416529239232": 0.0, + "1416529249231": 0.5, + "1416529259232": 0.0, + "1416529269232": 0.5, + "1416529279232": 0.0, + "1416529289232": 0.0, + "1416529299232": 0.4, + "1416529309232": 0.0, + "1416529319232": 0.0, + "1416529329232": 0.0, + "1416529339232": 0.25, + "1416529349232": 0.0, + "1416529359232": 0.0, + "1416529369232": 0.0, + "1416529379232": 0.0, + "1416529389233": 0.5, + "1416529399232": 1.0, + "1416529409232": 0.0, + "1416529419232": 0.2, + "1416529429232": 0.0, + "1416529439232": 0.5, + "1416529449232": 0.5, + "1416529459231": 0.5, + "1416529469232": 0.0, + "1416529479232": 0.33333333333333337, + "1416529489231": 0.25, + "1416529499232": 0.6, + "1416529509232": 0.25, + "1416529519232": 0.5, + "1416529529232": 0.0, + "1416529539232": 0.25, + "1416529549232": 0.25, + "1416529559232": 0.33333333333333337, + "1416529569232": 1.0, + "1416529579232": 0.0, + "1416529589232": 0.33333333333333337, + "1416529599232": 0.0, + "1416529609232": 1.0, + "1416529619232": 0.25, + "1416529629232": 0.25, + "1416529639232": 0.0, + "1416529649232": 0.6, + "1416529659232": 0.0, + "1416529669232": 0.25, + "1416529679231": 0.0, + "1416529689232": 0.5, + "1416529699232": 0.25, + "1416529709232": 0.3333333333333333, + "1416529719232": 1.0, + "1416529729232": 0.5, + "1416529739231": 0.4, + "1416529749232": 0.25, + "1416529759232": 0.0, + "1416529769231": 0.6, + "1416529779232": 0.5, + "1416529789232": 0.0, + "1416529799232": 0.0, + "1416529809232": 0.5, + "1416529819232": 0.0, + "1416529829232": 0.0, + "1416529839231": 0.2, + "1416529849232": 0.0, + "1416529859232": 0.0, + "1416529869231": 0.25, + "1416529879232": 0.0, + "1416529889231": 0.6666666666666666, + "1416529899233": 0.0, + "1416529909232": 0.25, + "1416529919232": 0.0, + "1416529929232": 0.0, + "1416529939232": 0.5, + "1416529949232": 0.0, + "1416529959232": 0.4, + "1416529969231": 0.5, + "1416529979232": 0.25, + "1416529989232": 0.5, + "1416529999232": 0.5, + "1416530009232": 0.0, + "1416530019232": 0.5, + "1416530029232": 0.0, + "1416530039232": 0.5, + "1416530049232": 0.5, + "1416530059233": 0.0, + "1416530069232": 0.0, + "1416530079232": 0.0, + "1416530089232": 0.0, + "1416530099232": 0.2, + "1416530109232": 0.0, + "1416530119232": 0.75, + "1416530129232": 0.33333333333333337, + "1416530139232": 1.0, + "1416530149232": 0.5, + "1416530159233": 0.25, + "1416530169232": 0.12500000000000003, + "1416530179232": 0.5, + "1416530189233": 0.14285714285714288, + "1416530199232": 0.33333333333333337, + "1416530209231": 0.33333333333333337, + "1416530219232": 0.5, + "1416530229232": 0.25000000000000006, + "1416530239231": 0.0, + "1416530249232": 0.14285714285714288, + "1416530259232": 0.25000000000000006, + "1416530269232": 0.5714285714285714, + "1416530279232": 0.28571428571428575, + "1416530289232": 0.375, + "1416530299232": 0.33333333333333337, + "1416530309232": 0.14285714285714288, + "1416530319232": 0.4444444444444444, + "1416530329232": 0.0, + "1416530339232": 0.33333333333333337, + "1416530349232": 0.0, + "1416530359232": 0.16666666666666669, + "1416530369232": 0.28571428571428575, + "1416530379232": 0.3333333333333333, + "1416530389231": 0.5, + "1416530399232": 0.33333333333333337, + "1416530409232": 0.375, + "1416530419232": 0.16666666666666669, + "1416530429231": 0.0, + "1416530439232": 0.2222222222222222, + "1416530449232": 0.16666666666666669, + "1416530459232": 0.28571428571428575, + "1416530469232": 0.125, + "1416530479232": 0.33333333333333337, + "1416530489232": 0.4285714285714286, + "1416530499232": 0.375, + "1416530509232": 0.2857142857142857, + "1416530519232": 0.33333333333333337, + "1416530529232": 0.12500000000000003, + "1416530539232": 0.8333333333333334, + "1416530549232": 0.4285714285714286, + "1416530559232": 0.11111111111111113, + "1416530569232": 0.16666666666666669, + "1416530579232": 0.16666666666666669, + "1416530589232": 0.375, + "1416530599231": 0.0, + "1416530609232": 0.28571428571428575, + "1416530619232": 0.33333333333333337, + "1416530629232": 0.0, + "1416530639232": 0.0, + "1416530649232": 0.25, + "1416530659232": 0.33333333333333337, + "1416530669232": 0.14285714285714288, + "1416530679232": 0.33333333333333337, + "1416530689232": 0.16666666666666669, + "1416530699231": 0.6666666666666666, + "1416530709232": 0.0, + "1416530719232": 0.33333333333333337, + "1416530729232": 0.4285714285714286, + "1416530739232": 0.25, + "1416530749232": 0.0, + "1416530759232": 0.16666666666666669, + "1416530769232": 0.25, + "1416530779232": 0.16666666666666669, + "1416530789232": 0.4285714285714286, + "1416530799232": 0.11111111111111113, + "1416530809232": 0.0, + "1416530819232": 0.28571428571428575, + "1416530829232": 0.375, + "1416530839231": 0.33333333333333337, + "1416530849232": 0.4285714285714286, + "1416530859232": 0.0, + "1416530869232": 0.33333333333333337, + "1416530879232": 0.33333333333333337, + "1416530889232": 0.125, + "1416530899232": 0.5, + "1416530909232": 0.14285714285714288, + "1416530919232": 0.4444444444444444, + "1416530929232": 0.0, + "1416530939232": 0.33333333333333337, + "1416530949232": 0.25000000000000006, + "1416530959232": 0.33333333333333337, + "1416530969232": 0.0, + "1416530979232": 0.375, + "1416530989232": 0.14285714285714288, + "1416530999232": 0.4285714285714286, + "1416531009232": 0.375, + "1416531019232": 0.33333333333333337, + "1416531029232": 0.28571428571428575, + "1416531039232": 0.22222222222222227, + "1416531049232": 0.5, + "1416531059232": 0.0, + "1416531069232": 0.5, + "1416531079232": 0.0, + "1416531089232": 1.0, + "1416531099232": 0.0, + "1416531109232": 0.0, + "1416531119232": 0.0, + "1416531129231": 0.0 + } + } +]}