Java tutorial
// // A Java VM status Watcher for Fluent // // Copyright (C) 2013 Masayuki Miyake // // 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 org.fluentd.jvmwatcher; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.regex.Pattern; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.fluentd.jvmwatcher.data.JvmWatchState; import org.fluentd.jvmwatcher.parser.AbstractStateParser; import org.fluentd.jvmwatcher.parser.JsonSimpleLogParser; import org.fluentd.jvmwatcher.proxy.JvmClientProxy; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; /** * JVM Watcher Main Class * @author miyake * */ public class JvmWatcher { private static Log log = LogFactory.getLog(JvmWatcher.class); private Map<Integer, JvmWatchThread> jvmProcessorMap_ = new HashMap<Integer, JvmWatchThread>(); private OutputParseThread jsonOutputParseTread_ = null; private BlockingQueue<JvmWatchState> queue_ = new LinkedBlockingQueue<JvmWatchState>(); private long refindJvmInterval_ = 20000L; // msec private long watchInterval_ = 1000L; // msec private int logBuffNum_ = 1; private String hostName_ = null; /** * @param args */ public static void main(String[] args) { JvmWatcher jvmWatcher = new JvmWatcher(); if (args.length < 1) { log.warn("not property. watch or targetlist "); // start JVM Watcher mode jvmWatcher.startJvmWatcher(null); } String type = null; String configPath = null; /* * args[0] => command type. watcher or targetlist * args[1] => config file * args[2] => refind Jvm Interval(msec) * args[3] => watch Interval(msec) * args[4] => logging buffer number * args[5] => host name */ if (args.length == 1) { // command type type = args[0]; } else if (args.length >= 2) { // command type type = args[0]; // config file path configPath = args[1]; } if ("watcher".compareTo(type) == 0) { jvmWatcher.getJvmWatcherParam(args); // if ("NO_CONFIG".compareTo(configPath) == 0) { configPath = null; } jvmWatcher.startJvmWatcher(configPath); } else if ("targetlist".compareTo(type) == 0) { jvmWatcher.startTargetList(configPath); } else { log.warn("unknown type. type=" + type); // start JVM Watcher mode jvmWatcher.startJvmWatcher(configPath); } } /** * @param args */ public void getJvmWatcherParam(String[] args) { for (int cnt = 2; cnt < args.length; cnt++) { try { if (cnt == 2) { long val = Long.parseLong(args[cnt]); if (val > 0) { this.refindJvmInterval_ = val; } } else if (cnt == 3) { long val = Long.parseLong(args[cnt]); if (val > 0) { this.watchInterval_ = val; } } else if (cnt == 4) { int val = Integer.parseInt(args[cnt]); if (val > 0) { this.logBuffNum_ = val; } } else if (cnt == 5) { this.hostName_ = args[cnt]; } } catch (NumberFormatException ex) { log.error("Number paramator error.", ex); } } } /** * @param paramFilePath */ public void startJvmWatcher(String paramFilePath) { // load configuration this.loadProperty(paramFilePath); // start OutputParseThread AbstractStateParser parser = new JsonSimpleLogParser(); parser.setHostName(getHostName(this.hostName_)); jsonOutputParseTread_ = new OutputParseThread(this, this.queue_, parser); // start thread Thread thread = new Thread(this.jsonOutputParseTread_); thread.start(); // loop this.runProcess(); } /** * @param paramFilePath */ public void startTargetList(String paramFilePath) { // load configuration this.loadProperty(paramFilePath); // get JVM process list Map<Integer, LocalJvmInfo> allJvm = LocalJvmInfo.getAllLocalJvmInfos(); System.out.println("-- process list start --"); for (Map.Entry<Integer, LocalJvmInfo> elem : allJvm.entrySet()) { int key = elem.getKey(); LocalJvmInfo val = elem.getValue(); System.out.println("Target prosecc [pid]=" + key + " [ShortName]=" + val.getShortName() + " [CommandLine]=" + val.getCommandLine_()); } System.out.println("-- process list end --"); } /** * @param paramFilePath */ public void loadProperty(String paramFilePath) { if (null == paramFilePath) { return; } try { // load JSON property file. File file = new File(paramFilePath); JsonFactory factory = new JsonFactory(); JsonParser parser = factory.createParser(file); JsonToken token = null; while ((token = parser.nextToken()) != null) { if (token == JsonToken.FIELD_NAME) { if (parser.getText().compareTo("target") == 0) { this.loadTarget(parser); } } } parser.close(); } catch (JsonParseException e) { log.error("Property parse error.", e); } catch (IOException e) { log.error("Property file open error.", e); } catch (Exception e) { log.error("Property file open error.", e); } } /** * @param parser * @throws JsonParseException * @throws IOException */ private void loadTarget(JsonParser parser) throws JsonParseException, IOException { if (parser.nextToken() == JsonToken.START_ARRAY) { while (parser.nextToken() != JsonToken.END_ARRAY) { if (parser.getCurrentToken() == JsonToken.START_OBJECT) { String shortName = null; String pattern = null; while (parser.nextToken() != JsonToken.END_OBJECT) { if ((parser.getCurrentToken() == JsonToken.FIELD_NAME) && (parser.getText().compareTo("shortname") == 0)) { if (parser.nextToken() == JsonToken.VALUE_STRING) { shortName = parser.getText(); } } if ((parser.getCurrentToken() == JsonToken.FIELD_NAME) && (parser.getText().compareTo("pattern") == 0)) { if (parser.nextToken() == JsonToken.VALUE_STRING) { pattern = parser.getText(); } } } // add target pattern Pattern regexPattern = Pattern.compile(pattern); LocalJvmInfo.addTargetProcessPattern(shortName, regexPattern); } } } } /** * @param pid */ public void removeJvmWatchThread(int pid) { synchronized (this.jvmProcessorMap_) { this.jvmProcessorMap_.remove(pid); } return; } /** * @param pid * @param info */ private void startJvmWatchThread(int pid, LocalJvmInfo info) { synchronized (this.jvmProcessorMap_) { JvmWatchThread watchThread = this.jvmProcessorMap_.get(pid); // is new JVM if (null == watchThread) { JvmClientProxy clientProxy = new JvmClientProxy(info); // connect JVM boolean connState = clientProxy.connect(); if (connState == true) { // start JvmWatchThread JvmWatchThread newWatchThread = new JvmWatchThread(this, this.queue_, clientProxy); // set interval time newWatchThread.setInterval(this.watchInterval_, this.logBuffNum_); // regist Process map. this.jvmProcessorMap_.put(pid, newWatchThread); // start thread Thread thread = new Thread(newWatchThread); thread.start(); } } } return; } /** * */ public void runProcess() { while (true) { long startTime = System.currentTimeMillis(); // get LocalJvmInfo Map<Integer, LocalJvmInfo> jvmInfoMap = LocalJvmInfo.getAllLocalJvmInfos(); for (Map.Entry<Integer, LocalJvmInfo> elem : jvmInfoMap.entrySet()) { int key = elem.getKey(); LocalJvmInfo val = elem.getValue(); // create and start JvmWatchThread. this.startJvmWatchThread(key, val); } long endTime = System.currentTimeMillis(); long watiTime = endTime - startTime; // wait interval time. try { Thread.sleep(this.refindJvmInterval_ - watiTime); } catch (InterruptedException ex) { log.error(ex); System.exit(1); } } } /** * @return */ public String getHostName(String defaultName) { String ret = null; try { ret = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException ex) { if (defaultName != null) { ret = defaultName; } log.error(ex); } return ret; } }