/**
* (C) 2011-2012 Alibaba Group Holding Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*/
package com.taobao.profile;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.taobao.profile.config.ProfConfig;
import com.taobao.profile.config.ProfFilter;
import com.taobao.profile.thread.DataDumpThread;
import com.taobao.profile.thread.InnerSocketThread;
import com.taobao.profile.thread.SamplerThread;
import com.taobao.profile.thread.TimeControlThread;
/**
* 管理类,单例实现
*
* @author shutong.dy
* @since 2012-1-9
*/
public class Manager {
/**
* 远程连接端口
*/
public static int PORT;
/**
* 开始命令
*/
public static final String START = "start";
/**
* 结束命令
*/
public static final String STOP = "stop";
/**
* 获取状态命令
*/
public static final String STATUS = "status";
/**
* 远程刷出方法数据
*/
public static final String FLUSHMETHOD = "flushmethod";
/**
* 是否用纳秒采集
*/
private static boolean NEED_NANO_TIME;
/**
* 是否忽略get/set方法
*/
private static boolean IGNORE_GETSET_METHOD;
/**
* 默认方法log位置
*/
public static String METHOD_LOG_PATH;
/**
* Manager
*/
private static Manager manager = new Manager();
/**
* profile配置
*/
private ProfConfig profConfig;
/**
* 时间标记.当前时间大于开始时间小于结束时间,则可以profile. default:false 不可以profile
*/
private volatile boolean timeFlag = false;
/**
* 开关标记.远程开始或结束的开关. default:true 打开状态
*/
private volatile boolean switchFlag = true;
/**
* profile标记.是否可以profile. default:false 不可以profile
*/
private volatile boolean profileFlag = false;
/**
* 开始时间结束时间控制线程
*/
private TimeControlThread controlThread;
/**
* 对外提供Socket开关
*/
private InnerSocketThread socketThread;
/**
* 将性能分析数据写出到磁盘
*/
private DataDumpThread dumpThread;
/**
* 采样线程
*/
private SamplerThread samplerThread;
/**
* 启动时间是否大于采集结束时间
*/
private boolean moreThanEndTime;
/**
* 是否进入调试模式
*/
private boolean isDebugMode;
/**
* 私有构造器
*/
private Manager() {}
/**
* 初始化配置
*/
public void initialization() {
profConfig = new ProfConfig();
NEED_NANO_TIME = profConfig.isNeedNanoTime();
IGNORE_GETSET_METHOD = profConfig.isIgnoreGetSetMethod();
METHOD_LOG_PATH = profConfig.getMethodFilePath();
// 判断启动时间是否大于采集结束时间 2012-05-25
DateFormat df = new SimpleDateFormat("HH:mm:ss");
String now = df.format(new Date());
moreThanEndTime = (now.compareTo(profConfig.getEndProfTime()) > 0 );
isDebugMode = profConfig.isDebugMode();
PORT = profConfig.getPort();
setProfFilter();
}
/**
* @return
*/
public static Manager instance() {
return manager;
}
/**
* @return the needNanoTime
*/
public static boolean isNeedNanoTime() {
return NEED_NANO_TIME;
}
/**
* @return the ignoreGetSetMethod
*/
public static boolean isIgnoreGetSetMethod() {
return IGNORE_GETSET_METHOD;
}
/**
* @param value the timeFlag to set
*/
public void setTimeFlag(boolean value) {
timeFlag = value;
}
/**
* @param value the switchFlag to set
*/
public void setSwitchFlag(boolean value) {
switchFlag = value;
}
/**
* @param value the profileFlag to set
*/
public void setProfileFlag(boolean value) {
profileFlag = value;
}
/**
* 判断当前是否可以采集数据
* @return
*/
public boolean canProfile() {
return profileFlag;
}
/**
* @return
*/
public boolean getSwitchFlag() {
return switchFlag;
}
/**
* @return the timeFlag
*/
public boolean getTimeFlag() {
return timeFlag;
}
/**
* 判断当前是否可以dump数据
*
* @return
*/
public boolean canDump() {
return timeFlag && switchFlag;
}
/**
* 启动时间是否大于profile结束时间
* @return
*/
public boolean isMoreThanEndTime(){
return moreThanEndTime;
}
/**
* @return the isDebugMode
*/
public boolean isDebugMode() {
return isDebugMode;
}
/**
* 设置包名过滤器
*
*/
private void setProfFilter() {
String classLoader = profConfig.getExcludeClassLoader();
if (classLoader != null && classLoader.trim().length() > 0) {
String[] _classLoader = classLoader.split(";");
for (String pack : _classLoader) {
ProfFilter.addExcludeClassLoader(pack);
}
}
String include = profConfig.getIncludePackageStartsWith();
if (include != null && include.trim().length() > 0) {
String[] _includes = include.split(";");
for (String pack : _includes) {
ProfFilter.addIncludeClass(pack);
}
}
String exclude = profConfig.getExcludePackageStartsWith();
if (exclude != null && exclude.trim().length() > 0) {
String[] _excludes = exclude.split(";");
for (String pack : _excludes) {
ProfFilter.addExcludeClass(pack);
}
}
}
/**
* 启动内部线程
*
*/
public void startupThread() {
controlThread = new TimeControlThread(profConfig);
controlThread.setName("TProfiler-TimeControl");
controlThread.setDaemon(true);
socketThread = new InnerSocketThread();
socketThread.setName("TProfiler-InnerSocket");
socketThread.setDaemon(true);
dumpThread = new DataDumpThread(profConfig);
dumpThread.setName("TProfiler-DataDump");
dumpThread.setDaemon(true);
samplerThread = new SamplerThread(profConfig);
samplerThread.setName("TProfiler-Sampler");
samplerThread.setDaemon(true);
controlThread.start();
socketThread.start();
dumpThread.start();
samplerThread.start();
}
}