azkaban.metric.MetricReportManager Maven / Gradle / Ivy
/*
* Copyright 2012 LinkedIn Corp.
*
* 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
*
* 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 azkaban.metric;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.log4j.Logger;
/**
* Manager for access or updating metric related functionality of Azkaban MetricManager is
* responsible all handling all action requests from statsServlet in Exec server Metric Manager
* 'has a' relationship with :-
- all the metric Azkaban is tracking
- all the
* emitters Azkaban is supposed to report metrics
*/
public class MetricReportManager {
/**
* Maximum number of metrics reporting threads
*/
private static final int MAX_EMITTER_THREADS = 4;
private static final Logger logger = Logger.getLogger(MetricReportManager.class);
// Singleton variable
private static volatile MetricReportManager instance = null;
private static volatile boolean isManagerEnabled;
/**
* List of all the metrics that Azkaban is tracking Manager is not concerned with type of metric
* as long as it honors IMetric contracts
*/
private final List> metrics;
/**
* List of all the emitter listening all the metrics Manager is not concerned with how emitter is
* reporting value. Manager is only responsible to notify all emitters whenever an IMetric wants
* to be notified
*/
private final List metricEmitters;
private final ExecutorService executorService;
private MetricReportManager() {
logger.debug("Instantiating Metric Manager");
this.executorService = Executors.newFixedThreadPool(MAX_EMITTER_THREADS);
this.metrics = new ArrayList<>();
this.metricEmitters = new LinkedList<>();
enableManager();
}
/**
* @return true, if we have Instantiated and enabled metric manager from Azkaban exec server
*/
public static boolean isAvailable() {
return isInstantiated() && isManagerEnabled;
}
/**
* @return true, if we have Instantiated metric manager from Azkaban exec server
*/
public static boolean isInstantiated() {
return instance != null;
}
/**
* Get a singleton object for Metric Manager
*/
public static MetricReportManager getInstance() {
if (instance == null) {
synchronized (MetricReportManager.class) {
if (instance == null) {
logger.info("Instantiating MetricReportManager");
instance = new MetricReportManager();
}
}
}
return instance;
}
/***
* each element of metrics List is responsible to call this method and report metrics
* @param metric
*/
@SuppressWarnings("FutureReturnValueIgnored")
public void reportMetric(final IMetric> metric) {
if (metric != null && isAvailable()) {
try {
final IMetric> metricSnapshot;
// take snapshot
synchronized (metric) {
metricSnapshot = metric.getSnapshot();
}
logger.debug(String
.format("Submitting %s metric for metric emission pool", metricSnapshot.getName()));
// report to all emitters
for (final IMetricEmitter metricEmitter : this.metricEmitters) {
this.executorService.submit(() -> {
try {
metricEmitter.reportMetric(metricSnapshot);
} catch (final Exception ex) {
logger.error(
String.format("Failed to report %s metric due to ", metricSnapshot.getName()),
ex);
}
});
}
} catch (final CloneNotSupportedException ex) {
logger.error(
String.format("Failed to take snapshot for %s metric", metric.getClass().getName()),
ex);
}
}
}
/**
* Add a metric emitter to report metric
*/
public void addMetricEmitter(final IMetricEmitter emitter) {
this.metricEmitters.add(emitter);
}
/**
* remove a metric emitter
*/
public void removeMetricEmitter(final IMetricEmitter emitter) {
this.metricEmitters.remove(emitter);
}
/**
* Get all the metric emitters
*/
public List getMetricEmitters() {
return this.metricEmitters;
}
/**
* Add a metric to be managed by Metric Manager
*/
public void addMetric(final IMetric> metric) {
// metric null or already present
if (metric == null) {
throw new IllegalArgumentException("Cannot add a null metric");
}
if (getMetricFromName(metric.getName()) == null) {
logger.debug(String.format("Adding %s metric in Metric Manager", metric.getName()));
this.metrics.add(metric);
metric.updateMetricManager(this);
} else {
logger.error("Failed to add metric");
}
}
/**
* Get metric object for a given metric name
*
* @param name metricName
* @return metric Object, if found. Otherwise null.
*/
public IMetric> getMetricFromName(final String name) {
IMetric> metric = null;
if (name != null) {
for (final IMetric> currentMetric : this.metrics) {
if (currentMetric.getName().equals(name)) {
metric = currentMetric;
break;
}
}
}
return metric;
}
/**
* Get all the emitters
*/
public List> getAllMetrics() {
return this.metrics;
}
public void enableManager() {
logger.info("Enabling Metric Manager");
isManagerEnabled = true;
}
/**
* Disable Metric Manager and ask all emitters to purge all available data.
*/
public void disableManager() {
logger.info("Disabling Metric Manager");
if (isManagerEnabled) {
isManagerEnabled = false;
for (final IMetricEmitter emitter : this.metricEmitters) {
try {
emitter.purgeAllData();
} catch (final MetricException ex) {
logger.error("Failed to purge data ", ex);
}
}
}
}
/**
* Shutdown execution service {@inheritDoc}
*
* @see java.lang.Object#finalize()
*/
@Override
protected void finalize() {
this.executorService.shutdown();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy