/gmonitor/gmonitor-core/src/main/java/com/zdingke/gmonitor/trans/MetricTrans.java
Java | 535 lines | 463 code | 65 blank | 7 comment | 74 complexity | a6cf501e7077b10eeb7fda560715c492 MD5 | raw file
- package com.zdingke.gmonitor.trans;
-
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
-
- import org.apache.commons.cli.CommandLine;
- import org.apache.commons.cli.CommandLineParser;
- import org.apache.commons.cli.GnuParser;
- import org.apache.commons.cli.HelpFormatter;
- import org.apache.commons.cli.Option;
- import org.apache.commons.cli.Options;
- import org.apache.commons.cli.ParseException;
- import org.apache.commons.io.FilenameUtils;
- import org.apache.commons.lang.RandomStringUtils;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.apache.commons.pool.KeyedObjectPool;
- import org.apache.commons.pool.impl.GenericKeyedObjectPool;
- import org.codehaus.jackson.map.ObjectMapper;
- import org.quartz.CronExpression;
- import org.quartz.CronTrigger;
- import org.quartz.JobDataMap;
- import org.quartz.JobDetail;
- import org.quartz.Scheduler;
- import org.quartz.SchedulerException;
- import org.quartz.Trigger;
- import org.quartz.TriggerUtils;
- import org.quartz.impl.StdSchedulerFactory;
-
- import com.alibaba.fastjson.JSON;
- import com.googlecode.jmxtrans.JmxTransformer;
- import com.googlecode.jmxtrans.OutputWriter;
- import com.googlecode.jmxtrans.jmx.ManagedGenericKeyedObjectPool;
- import com.googlecode.jmxtrans.jobs.ServerJob;
- import com.googlecode.jmxtrans.model.JmxProcess;
- import com.googlecode.jmxtrans.model.Query;
- import com.googlecode.jmxtrans.model.Server;
- import com.googlecode.jmxtrans.util.JmxUtils;
- import com.googlecode.jmxtrans.util.LifecycleException;
- import com.googlecode.jmxtrans.util.OptionsException;
- import com.googlecode.jmxtrans.util.ValidationException;
- import com.googlecode.jmxtrans.util.WatchDir;
- import com.googlecode.jmxtrans.util.WatchedCallback;
- import com.zdingke.gmonitor.utils.MetricJsonCreateUtil;
-
- public class MetricTrans implements WatchedCallback {
-
- private static final Log log = LogFactory.getLog(MetricTrans.class);
- private String quartPropertiesFile;
- private int runPeriod;
- private File jsonDirOrFile;
- private boolean runEndlessly;
- private Scheduler serverScheduler;
- private WatchDir watcher;
- private Map<String, KeyedObjectPool> poolMap;
- private Map<String, ManagedGenericKeyedObjectPool> poolMBeans;
- private List<Server> masterServersList;
- private Thread shutdownHook;
- private volatile boolean isRunning;
-
- public MetricTrans() {
- this.quartPropertiesFile = null;
-
- this.runPeriod = 60;
-
- this.runEndlessly = false;
-
- this.masterServersList = new ArrayList();
-
- this.shutdownHook = new ShutdownHook();
-
- this.isRunning = false;
- }
-
- public static void main(String[] args) throws Exception {
- MetricTrans transformer = new MetricTrans();
-
- transformer.doMain(args);
- }
-
- private void doMain(String[] args) throws Exception {
- if (!parseOptions(args)) {
- return;
- }
- // ManagedJmxTransformerProcess mbean = new
- // ManagedJmxTransformerProcess();
- // JmxUtils.registerJMX(mbean);
-
- start();
- damonReload();
- try {
- for (;;) {
- Thread.sleep(5L);
- }
- } catch (Exception e) {
- // JmxUtils.unregisterJMX(mbean);
- }
- }
-
- private void damonReload() {
- ReloadThread re = new ReloadThread(serverScheduler);
- new Thread(re).start();
- }
-
- public class ReloadThread implements Runnable {
-
- Scheduler serverScheduler;
-
- public ReloadThread(Scheduler serverScheduler) {
- this.serverScheduler = serverScheduler;
- }
-
- @Override
- public void run() {
- while (true) {
- try {
- Thread.sleep(60 * 60 * 1000L);
- if (log.isDebugEnabled()) {
- log.debug("reload conf");
- }
- deleteAllJobs(this.serverScheduler);
- startupSystem();
- } catch (Exception e) {
- log.error("reload error!");
- }
- }
- }
- }
-
- public synchronized void start() throws LifecycleException {
- if (this.isRunning) {
- throw new LifecycleException("Process already started");
- }
- log.info("Starting Jmxtrans on : " + this.jsonDirOrFile.toString());
- try {
- startupScheduler();
-
- startupWatchdir();
-
- setupObjectPooling();
-
- startupSystem();
- } catch (Exception e) {
- log.error(e.getMessage(), e);
- throw new LifecycleException(e);
- }
- Runtime.getRuntime().addShutdownHook(this.shutdownHook);
- this.isRunning = true;
- }
-
- public synchronized void stop() throws LifecycleException {
- if (!this.isRunning) {
- throw new LifecycleException("Process already stoped");
- }
- try {
- log.info("Stopping Jmxtrans");
- if (this.shutdownHook != null) {
- Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
- }
- stopServices();
- this.isRunning = false;
- } catch (LifecycleException e) {
- log.error(e.getMessage(), e);
- throw new LifecycleException(e);
- }
- }
-
- private synchronized void stopServices() throws LifecycleException {
- try {
- if (this.serverScheduler != null) {
- this.serverScheduler.shutdown(true);
- log.debug("Shutdown server scheduler");
- try {
- Thread.sleep(1500L);
- } catch (InterruptedException e) {
- log.error(e.getMessage(), e);
- }
- this.serverScheduler = null;
- }
- if (this.watcher != null) {
- this.watcher.stopService();
- this.watcher = null;
- log.debug("Shutdown watch service");
- }
- // for (String key : this.poolMap.keySet()) {
- // JmxUtils.unregisterJMX((ManagedObject) this.poolMBeans.get(key));
- // }
- this.poolMBeans = null;
- for (Map.Entry<String, KeyedObjectPool> entry : this.poolMap.entrySet()) {
- try {
- entry.getValue().close();
- log.debug("Closed object pool factory: " + entry.getKey());
- } catch (Exception ex) {
- log.error("Error closing object pool factory: " + entry.getKey());
- }
- }
- this.poolMap = null;
- Iterator i$;
- Query query;
- for (Server server : this.masterServersList) {
- for (i$ = server.getQueries().iterator(); i$.hasNext();) {
- query = (Query) i$.next();
- for (OutputWriter writer : query.getOutputWriters()) {
- try {
- writer.stop();
- log.debug("Stopped writer: " + writer.getClass().getSimpleName() + " for query: " + query);
- } catch (LifecycleException ex) {
- log.error("Error stopping writer: " + writer.getClass().getSimpleName() + " for query: " + query);
- }
- }
- }
- }
-
- this.masterServersList.clear();
- } catch (Exception e) {
- log.error(e.getMessage(), e);
- throw new LifecycleException(e);
- }
- }
-
- private void startupWatchdir() throws Exception {
- File dirToWatch = null;
- if (getJsonDirOrFile().isFile()) {
- dirToWatch = new File(FilenameUtils.getFullPath(getJsonDirOrFile().getAbsolutePath()));
- } else {
- dirToWatch = getJsonDirOrFile();
- }
- this.watcher = new WatchDir(dirToWatch, this);
- this.watcher.start();
- }
-
- private void startupScheduler() throws Exception {
- StdSchedulerFactory serverSchedFact = new StdSchedulerFactory();
- InputStream stream = null;
- if (this.quartPropertiesFile == null) {
- stream = JmxTransformer.class.getResourceAsStream("/quartz.server.properties");
- } else {
- stream = new FileInputStream(this.quartPropertiesFile);
- }
- serverSchedFact.initialize(stream);
- this.serverScheduler = serverSchedFact.getScheduler();
- this.serverScheduler.start();
- }
-
- public void executeStandalone(JmxProcess process) throws Exception {
- this.masterServersList = process.getServers();
-
- startupScheduler();
- setupObjectPooling();
-
- processServersIntoJobs(this.serverScheduler);
-
- Thread.sleep(10000L);
- }
-
- private void startupSystem() throws LifecycleException {
- processFilesIntoServers(getJsonFiles());
-
- processServersIntoJobs(this.serverScheduler);
- }
-
- protected void setupObjectPooling() throws Exception {
- if (this.poolMap == null) {
- this.poolMap = JmxUtils.getDefaultPoolMap();
-
- this.poolMBeans = new HashMap();
- for (String key : this.poolMap.keySet()) {
- ManagedGenericKeyedObjectPool mbean = new ManagedGenericKeyedObjectPool((GenericKeyedObjectPool) this.poolMap.get(key));
- mbean.setPoolName(key);
- JmxUtils.registerJMX(mbean);
- this.poolMBeans.put(key, mbean);
- }
- }
- }
-
- private void validateSetup(List<Query> queries) throws ValidationException {
- for (Query q : queries) {
- validateSetup(q);
- }
- }
-
- private void validateSetup(Query query) throws ValidationException {
- List<OutputWriter> writers = query.getOutputWriters();
- if (writers != null) {
- for (OutputWriter w : writers) {
- w.validateSetup(query);
- }
- }
- }
-
- private void processFilesIntoServers(List<File> jsonFiles) throws LifecycleException {
- MetricJsonCreateUtil.getAllModuleJsonObj(getJsonDirOrFile().getPath().toString()).stream().forEach(m -> {
- ObjectMapper mapper = new ObjectMapper();
- JmxProcess process = null;
- try {
- process = mapper.readValue(JSON.toJSONString(m), JmxProcess.class);
- } catch (Exception e) {
- log.error(e.getMessage(), e);
- }
- JmxUtils.mergeServerLists(this.masterServersList, process.getServers());
- });
- }
-
- private void processServersIntoJobs(Scheduler scheduler) throws LifecycleException {
- for (Server server : this.masterServersList) {
- try {
- for (Query query : server.getQueries()) {
- query.setServer(server);
- for (OutputWriter writer : query.getOutputWriters()) {
- writer.setObjectPoolMap(this.poolMap);
- writer.start();
- }
- }
- validateSetup(server.getQueries());
-
- scheduleJob(scheduler, server);
- } catch (java.text.ParseException ex) {
- throw new LifecycleException("Error parsing cron expression: " + server.getCronExpression(), ex);
- } catch (SchedulerException ex) {
- throw new LifecycleException("Error scheduling job for server: " + server, ex);
- } catch (ValidationException ex) {
- throw new LifecycleException("Error validating json setup for query", ex);
- }
- }
- }
-
- private void scheduleJob(Scheduler scheduler, Server server) throws java.text.ParseException, SchedulerException {
- String name = server.getHost() + ":" + server.getPort() + "-" + System.currentTimeMillis() + "-" + RandomStringUtils.randomNumeric(10);
- JobDetail jd = new JobDetail(name, "ServerJob", ServerJob.class);
-
- JobDataMap map = new JobDataMap();
- map.put(Server.class.getName(), server);
- map.put(Server.JMX_CONNECTION_FACTORY_POOL, this.poolMap.get(Server.JMX_CONNECTION_FACTORY_POOL));
- jd.setJobDataMap(map);
-
- Trigger trigger = null;
- if ((server.getCronExpression() != null) && (CronExpression.isValidExpression(server.getCronExpression()))) {
- trigger = new CronTrigger();
- ((CronTrigger) trigger).setCronExpression(server.getCronExpression());
- ((CronTrigger) trigger).setName(server.getHost() + ":" + server.getPort() + "-" + Long.valueOf(System.currentTimeMillis()).toString());
- ((CronTrigger) trigger).setStartTime(new Date());
- } else {
- Trigger minuteTrigger = TriggerUtils.makeSecondlyTrigger(this.runPeriod);
- minuteTrigger.setName(server.getHost() + ":" + server.getPort() + "-" + Long.valueOf(System.currentTimeMillis()).toString());
- minuteTrigger.setStartTime(new Date());
-
- trigger = minuteTrigger;
- }
- scheduler.scheduleJob(jd, trigger);
- if (log.isDebugEnabled()) {
- log.debug("Scheduled job: " + jd.getName() + " for server: " + server);
- }
- }
-
- private void deleteAllJobs(Scheduler scheduler) throws Exception {
- List<JobDetail> allJobs = new ArrayList();
- String[] jobGroups = scheduler.getJobGroupNames();
- for (String jobGroup : jobGroups) {
- String[] jobNames = scheduler.getJobNames(jobGroup);
- for (String jobName : jobNames) {
- allJobs.add(scheduler.getJobDetail(jobName, jobGroup));
- }
- }
- for (JobDetail jd : allJobs) {
- scheduler.deleteJob(jd.getName(), jd.getGroup());
- if (log.isDebugEnabled()) {
- log.debug("Deleted scheduled job: " + jd.getName() + " group: " + jd.getGroup());
- }
- }
- }
-
- public void setRunEndlessly(boolean runEndlessly) {
- this.runEndlessly = runEndlessly;
- }
-
- public boolean isRunEndlessly() {
- return this.runEndlessly;
- }
-
- private boolean parseOptions(String[] args) throws OptionsException, ParseException {
- CommandLineParser parser = new GnuParser();
- CommandLine cl = parser.parse(getOptions(), args);
- Option[] options = cl.getOptions();
-
- boolean result = true;
- for (Option option : options) {
- if (option.getOpt().equals("j")) {
- File tmp = new File(option.getValue());
- if ((!tmp.exists()) && (!tmp.isDirectory())) {
- throw new OptionsException("Path to json directory is invalid: " + tmp);
- }
- setJsonDirOrFile(tmp);
- } else if (option.getOpt().equals("f")) {
- File tmp = new File(option.getValue());
- if ((!tmp.exists()) && (!tmp.isFile())) {
- throw new OptionsException("Path to json file is invalid: " + tmp);
- }
- setJsonDirOrFile(tmp);
- } else if (option.getOpt().equals("e")) {
- setRunEndlessly(true);
- } else if (option.getOpt().equals("q")) {
- setQuartPropertiesFile(option.getValue());
- File file = new File(option.getValue());
- if (!file.exists()) {
- throw new OptionsException("Could not find path to the quartz properties file: " + file.getAbsolutePath());
- }
- } else if (option.getOpt().equals("s")) {
- setRunPeriod(Integer.valueOf(option.getValue()).intValue());
- } else if (option.getOpt().equals("h")) {
- HelpFormatter formatter = new HelpFormatter();
- formatter.printHelp("java -jar jmxtrans-all.jar", getOptions());
- result = false;
- }
- }
- if ((result == true) && (getJsonDirOrFile() == null)) {
- throw new OptionsException("Please specify either the -f or -j option.");
- }
- return result;
- }
-
- public Options getOptions() {
- Options options = new Options();
- options.addOption("j", true, "Directory where json configuration is stored. Default is .");
- options.addOption("f", true, "A single json file to execute.");
- options.addOption("e", false, "Run endlessly. Default false.");
- options.addOption("q", true, "Path to quartz configuration file.");
- options.addOption("s", true, "Seconds between server job runs (not defined with cron). Default: 60");
- options.addOption("h", false, "Help");
- return options;
- }
-
- public String getQuartPropertiesFile() {
- return this.quartPropertiesFile;
- }
-
- public void setQuartPropertiesFile(String quartPropertiesFile) {
- this.quartPropertiesFile = quartPropertiesFile;
- }
-
- public int getRunPeriod() {
- return this.runPeriod;
- }
-
- public void setRunPeriod(int runPeriod) {
- this.runPeriod = runPeriod;
- }
-
- public void setJsonDirOrFile(File jsonDirOrFile) {
- this.jsonDirOrFile = jsonDirOrFile;
- }
-
- public File getJsonDirOrFile() {
- return this.jsonDirOrFile;
- }
-
- private List<File> getJsonFiles() {
- File[] files = null;
- if ((getJsonDirOrFile() != null) && (getJsonDirOrFile().isFile())) {
- files = new File[1];
- files[0] = getJsonDirOrFile();
- } else {
- files = getJsonDirOrFile().listFiles();
- }
- List<File> result = new ArrayList();
- for (File file : files) {
- if (isJsonFile(file)) {
- result.add(file);
- }
- }
- return result;
- }
-
- private boolean isJsonFile(File file) {
- if (getJsonDirOrFile().isFile()) {
- return file.equals(getJsonDirOrFile());
- }
- return file.getName().endsWith(".json");
- }
-
- @Override
- public void fileModified(File file) throws Exception {
- if (isJsonFile(file)) {
- Thread.sleep(1000L);
- if (log.isDebugEnabled()) {
- log.debug("File modified: " + file);
- }
- deleteAllJobs(this.serverScheduler);
- startupSystem();
- }
- }
-
- @Override
- public void fileDeleted(File file) throws Exception {
- if (isJsonFile(file)) {
- Thread.sleep(1000L);
- if (log.isDebugEnabled()) {
- log.debug("File deleted: " + file);
- }
- deleteAllJobs(this.serverScheduler);
- startupSystem();
- }
- }
-
- @Override
- public void fileAdded(File file) throws Exception {
- if (isJsonFile(file)) {
- Thread.sleep(1000L);
- if (log.isDebugEnabled()) {
- log.debug("File added: " + file);
- }
- startupSystem();
- }
- }
-
- protected class ShutdownHook extends Thread {
- protected ShutdownHook() {
- }
-
- @Override
- public void run() {
- try {
- MetricTrans.this.stopServices();
- } catch (LifecycleException e) {
- MetricTrans.log.error("Error shutdown hook", e);
- }
- }
- }
- }