All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.phoenix.pherf.jmx.MonitorManager Maven / Gradle / Ivy

The newest version!
/*
 * 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.phoenix.pherf.jmx;

import org.apache.phoenix.pherf.PherfConstants;
import org.apache.phoenix.pherf.exception.FileLoaderRuntimeException;
import org.apache.phoenix.pherf.jmx.monitors.Monitor;
import org.apache.phoenix.pherf.result.Result;
import org.apache.phoenix.pherf.result.ResultHandler;
import org.apache.phoenix.pherf.result.file.ResultFileDetails;
import org.apache.phoenix.pherf.result.impl.CSVFileResultHandler;
import org.apache.phoenix.pherf.workload.Workload;
import org.apache.phoenix.util.DateUtil;

import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.StandardMBean;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

/**
 * This class starts JMX stats for the configured monitors.
 * Monitors should be configured in MonitorDetails Enum.
 * Each stat implements {@link org.apache.phoenix.pherf.jmx.monitors.Monitor}.
 * For the duration of any Pherf run, when the configured
 * {@link org.apache.phoenix.pherf.PherfConstants#MONITOR_FREQUENCY} is reached a snapshot of
 * each monitor is taken and dumped out to a log file.
 */
public class MonitorManager implements Workload {
    // List of MonitorDetails for all the running monitors.
    // TODO Move this out to config. Possible use Guice and use IOC to inject it in.
    private static final List
            MONITOR_DETAILS_LIST =
            Arrays.asList(MonitorDetails.values());
    private final ResultHandler resultHandler;
    private final AtomicLong monitorFrequency;
    private final AtomicLong rowCount;
    private final AtomicBoolean shouldStop = new AtomicBoolean(false);
    private final AtomicBoolean isRunning = new AtomicBoolean(false);

    @SuppressWarnings("unused") public MonitorManager() throws Exception {
        this(PherfConstants.MONITOR_FREQUENCY);
    }

    /**
     * @param monitorFrequency Frequency at which monitor stats are written to a log file.
     * @throws Exception
     */
    public MonitorManager(long monitorFrequency) throws Exception {
        this.monitorFrequency = new AtomicLong(monitorFrequency);
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

        // Register all the monitors to JMX
        for (MonitorDetails monitorDetails : MONITOR_DETAILS_LIST) {
            StandardMBean bean = new StandardMBean(monitorDetails.getMonitor(), Monitor.class);
            ObjectName monitorThreadStatName = new ObjectName(monitorDetails.toString());
            try {
                mbs.registerMBean(bean, monitorThreadStatName);
            } catch (InstanceAlreadyExistsException e) {
                mbs.unregisterMBean(monitorThreadStatName);
                mbs.registerMBean(bean, monitorThreadStatName);
            }
        }
        rowCount = new AtomicLong(0);
        this.resultHandler = new CSVFileResultHandler();
        this.resultHandler.setResultFileDetails(ResultFileDetails.CSV);
        this.resultHandler.setResultFileName(PherfConstants.MONITOR_FILE_NAME);
    }

    @Override public synchronized void complete() {
        this.shouldStop.set(true);
    }

    @Override public Callable execute() {
        return new Callable() {
            @Override public Void call() throws Exception {
                try {
                    while (!shouldStop()) {
                        isRunning.set(true);
                        List rowValues = new ArrayList();
                        synchronized (resultHandler) {
                            for (MonitorDetails monitorDetails : MONITOR_DETAILS_LIST) {
                                rowValues.clear();
                                try {
                                    StandardMBean
                                            bean =
                                            new StandardMBean(monitorDetails.getMonitor(),
                                                    Monitor.class);

                                    Calendar calendar = new GregorianCalendar();
                                    rowValues.add(monitorDetails);

                                    rowValues.add(((Monitor) bean.getImplementation()).getStat());
                                    rowValues.add(DateUtil.DEFAULT_MS_DATE_FORMATTER
                                            .format(calendar.getTime()));
                                    Result
                                            result =
                                            new Result(ResultFileDetails.CSV,
                                                    ResultFileDetails.CSV_MONITOR.getHeader()
                                                            .toString(), rowValues);
                                    resultHandler.write(result);
                                } catch (Exception e) {
                                    throw new FileLoaderRuntimeException(
                                            "Could not log monitor result.", e);
                                }
                                rowCount.getAndIncrement();
                            }
                            try {
                                resultHandler.flush();
                                Thread.sleep(getMonitorFrequency());
                            } catch (Exception e) {
                                Thread.currentThread().interrupt();
                                e.printStackTrace();
                                throw e;
                            }
                        }
                    }
                } finally {
                    try {
                        isRunning.set(false);
                        if (resultHandler != null) {
                            resultHandler.close();
                        }
                    } catch (Exception e) {
                        throw new FileLoaderRuntimeException("Could not close monitor results.", e);
                    }
                }
                return null;
            }
        };
    }

    public long getMonitorFrequency() {
        return monitorFrequency.get();
    }

    public boolean shouldStop() {
        return shouldStop.get();
    }

    // Convenience method for testing.
    @SuppressWarnings("unused")
    public long getRowCount() {
        return rowCount.get();
    }

    public boolean isRunning() {
        return isRunning.get();
    }

    /**
     * This method should really only be used for testing
     *
     * @return {@code List < org.apache.phoenix.pherf.result.Result > }
     * @throws Exception
     */
    public synchronized List readResults() throws Exception {
        ResultHandler handler = null;
        try {
            if (resultHandler.isClosed()) {
                handler = new CSVFileResultHandler();
                handler.setResultFileDetails(ResultFileDetails.CSV);
                handler.setResultFileName(PherfConstants.MONITOR_FILE_NAME);
                return handler.read();
            } else {
                return resultHandler.read();
            }
        } catch (Exception e) {
            throw new FileLoaderRuntimeException("Could not close monitor results.", e);
        } finally {
            if (handler != null) {
                handler.close();
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy