| /** |
| * 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.ambari.metrics.core.timeline; |
| |
| import java.util.Collections; |
| import java.util.concurrent.Callable; |
| import java.util.concurrent.ExecutorService; |
| import java.util.concurrent.Executors; |
| import java.util.concurrent.Future; |
| import java.util.concurrent.TimeUnit; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.hadoop.metrics2.sink.timeline.Precision; |
| import org.apache.hadoop.metrics2.sink.timeline.TimelineMetric; |
| import org.apache.hadoop.metrics2.sink.timeline.TimelineMetrics; |
| import org.apache.hadoop.util.ExitUtil; |
| |
| /** |
| * Acts as the single TimetineMetricStore Watcher. |
| */ |
| public class TimelineMetricStoreWatcher implements Runnable { |
| |
| private static final Log LOG = LogFactory.getLog(TimelineMetricStoreWatcher.class); |
| private static final String FAKE_METRIC_NAME = "TimelineMetricStoreWatcher.FakeMetric"; |
| private static final String FAKE_HOSTNAME = "fakehostname"; |
| private static final String FAKE_APP_ID = "timeline_metric_store_watcher"; |
| |
| private static int failures = 0; |
| private final TimelineMetricConfiguration configuration; |
| |
| private HBaseTimelineMetricsService timelineMetricStore; |
| |
| //used to call timelineMetricStore blocking methods with timeout |
| private ExecutorService executor = Executors.newSingleThreadExecutor(); |
| |
| |
| public TimelineMetricStoreWatcher(HBaseTimelineMetricsService timelineMetricStore, |
| TimelineMetricConfiguration configuration) { |
| this.timelineMetricStore = timelineMetricStore; |
| this.configuration = configuration; |
| } |
| |
| @Override |
| public void run() { |
| if (checkMetricStore()) { |
| failures = 0; |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Successfully got metrics from TimelineMetricStore"); |
| } |
| } else { |
| LOG.info("Failed to get metrics from TimelineMetricStore, attempt = " + failures); |
| failures++; |
| } |
| |
| if (failures >= configuration.getTimelineMetricsServiceWatcherMaxFailures()) { |
| String msg = "Error getting metrics from TimelineMetricStore. " + |
| "Shutting down by TimelineMetricStoreWatcher."; |
| LOG.fatal(msg); |
| ExitUtil.terminate(-1, msg); |
| } |
| |
| } |
| |
| /** |
| * Checks TimelineMetricStore functionality by adding and getting |
| * a fake metric to/from HBase |
| * @return if check was successful |
| */ |
| private boolean checkMetricStore() { |
| final long startTime = System.currentTimeMillis(); |
| final int delay = configuration.getTimelineMetricsServiceWatcherDelay(); |
| final int timeout = configuration.getTimelineMetricsServiceWatcherTimeout(); |
| |
| TimelineMetric fakeMetric = new TimelineMetric(); |
| fakeMetric.setMetricName(FAKE_METRIC_NAME); |
| fakeMetric.setHostName(FAKE_HOSTNAME); |
| fakeMetric.setAppId(FAKE_APP_ID); |
| fakeMetric.setStartTime(startTime); |
| fakeMetric.getMetricValues().put(startTime, 0.0); |
| |
| final TimelineMetrics metrics = new TimelineMetrics(); |
| metrics.setMetrics(Collections.singletonList(fakeMetric)); |
| |
| Callable<TimelineMetric> task = new Callable<TimelineMetric>() { |
| public TimelineMetric call() throws Exception { |
| timelineMetricStore.putMetricsSkipCache(metrics); |
| TimelineMetrics timelineMetrics = timelineMetricStore.getTimelineMetrics( |
| Collections.singletonList(FAKE_METRIC_NAME), Collections.singletonList(FAKE_HOSTNAME), |
| FAKE_APP_ID, null, startTime - delay * 2 * 1000, |
| startTime + delay * 2 * 1000, Precision.SECONDS, 1, true, null, null); |
| return timelineMetrics.getMetrics().get(0); |
| } |
| }; |
| |
| Future<TimelineMetric> future = executor.submit(task); |
| TimelineMetric timelineMetric = null; |
| try { |
| timelineMetric = future.get(timeout, TimeUnit.SECONDS); |
| // Phoenix might throw RuntimeExeption's |
| } catch (Exception e) { |
| return false; |
| } finally { |
| future.cancel(true); |
| } |
| |
| return timelineMetric != null; |
| } |
| |
| } |