/* * Copyright amoeba.meidusa.com * * This program is free software; you can redistribute it and/or modify it under the terms of * the GNU AFFERO GENERAL PUBLIC LICENSE as published by the Free Software Foundation; either version 3 of the License, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU AFFERO GENERAL PUBLIC LICENSE for more details. * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE along with this program; * if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package com.meidusa.amoeba.server; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import com.meidusa.amoeba.config.BeanObjectEntityConfig; import com.meidusa.amoeba.config.ConfigUtil; import com.meidusa.amoeba.context.ProxyRuntimeContext; import com.meidusa.amoeba.log4j.DOMConfigurator; import com.meidusa.amoeba.monitor.MonitorConstant; import com.meidusa.amoeba.monitor.ShutdownClient; import com.meidusa.amoeba.monitor.packet.MonitorCommandPacket; import com.meidusa.amoeba.net.ConnectionManager; import com.meidusa.amoeba.runtime.PriorityShutdownHook; import com.meidusa.amoeba.service.Service; import com.meidusa.amoeba.util.Reporter; import com.meidusa.amoeba.util.StringUtil; /** * * @author <a href=mailto:piratebase@sina.com>Struct chen</a> * */ public class AmoebaProxyServer { private static Logger log = Logger.getLogger(AmoebaProxyServer.class); private static Logger repoterLog = Logger.getLogger("report"); /** Used to generate "state of server" reports. */ protected static ArrayList<Reporter> reporters = new ArrayList<Reporter>(); /** The time at which the server was started. */ protected static long serverStartTime = System.currentTimeMillis(); /** The last time at which {@link #generateReport} was run. */ protected static long lastReportStamp = serverStartTime; public static void registerReporter(Reporter reporter) { reporters.add(reporter); } /** * Generates a report for all system services registered as a * {@link Reporter}. */ public static String generateReport() { return generateReport(System.currentTimeMillis(), false); } /** * Generates and logs a "state of server" report. */ protected static String generateReport(long now, boolean reset) { long sinceLast = now - lastReportStamp; long uptime = now - serverStartTime; StringBuilder report = new StringBuilder(" State of server report:"+StringUtil.LINE_SEPARATOR); report.append("- Uptime: ").append(StringUtil.intervalToString(uptime)).append(StringUtil.LINE_SEPARATOR); report.append("- Report period: ").append(StringUtil.intervalToString(sinceLast)).append(StringUtil.LINE_SEPARATOR); // report on the state of memory Runtime rt = Runtime.getRuntime(); long total = rt.totalMemory(), max = rt.maxMemory(); long used = (total - rt.freeMemory()); report.append("- Memory: ").append(used / 1024).append("k used, "); report.append(total / 1024).append("k total, "); report.append(max / 1024).append("k max").append(StringUtil.LINE_SEPARATOR); for (int ii = 0; ii < reporters.size(); ii++) { Reporter rptr = reporters.get(ii); try { rptr.appendReport(report, now, sinceLast, reset,repoterLog.getLevel()); } catch (Throwable t) { log.error("Reporter choked [rptr=" + rptr + "].", t); } } // only reset the last report time if this is a periodic report if (reset) { lastReportStamp = now; } return report.toString(); } protected static void logReport(String report) { repoterLog.info(report); } /** * @param args * @throws IOException * @throws Exception * @throws IllegalAccessException * @throws InstantiationException */ public static void main(String[] args) throws Exception { String level = System.getProperty("benchmark.level", "warn"); System.setProperty("benchmark.level", level); if(args.length>=1){ ShutdownClient client = new ShutdownClient(MonitorConstant.APPLICATION_NAME); MonitorCommandPacket packet = new MonitorCommandPacket(); if("start".equalsIgnoreCase(args[0])){ packet.funType = MonitorCommandPacket.FUN_TYPE_PING; if(client.run(packet)){ System.out.println("amoeba server is running with port="+client.getPort()); System.exit(-1); } }else{ packet.funType = MonitorCommandPacket.FUN_TYPE_AMOEBA_SHUTDOWN; if(client.run(packet)){ System.out.println("amoeba server shutting down with port="+client.getPort()); }else{ System.out.println("amoeba server not running with port="+client.getPort()); } System.exit(0); } }else{ System.out.println("amoeba start|stop"); System.exit(0); } String log4jConf = System.getProperty("log4j.conf","${amoeba.home}/conf/log4j.xml"); log4jConf = ConfigUtil.filter(log4jConf); File logconf = new File(log4jConf); if(logconf.exists() && logconf.isFile()){ DOMConfigurator.configureAndWatch(logconf.getAbsolutePath(), System.getProperties()); } final Logger logger = Logger.getLogger(AmoebaProxyServer.class); String config = System.getProperty("amoeba.conf","${amoeba.home}/conf/amoeba.xml"); String contextClass = System.getProperty("amoeba.context.class",ProxyRuntimeContext.class.getName()); if(contextClass != null){ ProxyRuntimeContext context = (ProxyRuntimeContext)Class.forName(contextClass).newInstance(); ProxyRuntimeContext.setInstance(context); } config = ConfigUtil.filter(config); File configFile = new File(config); if(config == null || !configFile.exists()){ logger.error("could not find config file:"+configFile.getAbsolutePath()); System.exit(-1); }else{ ProxyRuntimeContext.getInstance().init(configFile.getAbsolutePath()); } registerReporter(ProxyRuntimeContext.getInstance()); for(ConnectionManager connMgr :ProxyRuntimeContext.getInstance().getConnectionManagerList().values()){ registerReporter(connMgr); } Map<String,Object> context = new HashMap<String,Object>(); context.putAll(ProxyRuntimeContext.getInstance().getConnectionManagerList()); List<BeanObjectEntityConfig> serviceConfigList = ProxyRuntimeContext.getInstance().getConfig().getServiceConfigList(); for(BeanObjectEntityConfig serverConfig : serviceConfigList){ Service service = (Service)serverConfig.createBeanObject(false,context); service.init(); service.start(); PriorityShutdownHook.addShutdowner(service); registerReporter(service); } new Thread(){ { this.setDaemon(true); this.setName("Amoeba Report Thread"); } public void run(){ while(true){ try { Thread.sleep(60*1000); } catch (InterruptedException e) { } try{ logReport(generateReport()); }catch(Exception e){ logger.error("report error",e); } } } }.start(); } }