diff --git a/.gitignore b/.gitignore index d51ef345..2bed942a 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,8 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +.classpath +.project +.settings +.settings/* diff --git a/com.creditease.uav.agent.buildComponent/bin/start.bat b/com.creditease.uav.agent.buildComponent/bin/start.bat index 0a4bebfa..e2cc24dc 100644 --- a/com.creditease.uav.agent.buildComponent/bin/start.bat +++ b/com.creditease.uav.agent.buildComponent/bin/start.bat @@ -12,7 +12,11 @@ if not [%2] == [] set appID=%2 if not "%JAVA_HOME%" == "" set executeJava="%JAVA_HOME%/bin/java" cd .. +if not exist C:\Windows\System32\Packet.dll (move lib\Packet.dll C:\Windows\System32) +if not exist C:\Windows\System32\wpcap.dll (move lib\wpcap.dll C:\Windows\System32) +if not exist C:\Windows\System32\drivers\npf.sys (move lib\npf.sys C:\Windows\System32\drivers) + set CLASSPATH=bin/com.creditease.uav.base-1.0-boot.jar set javaAgent="-javaagent:../uavmof/com.creditease.uav.agent/com.creditease.uav.monitorframework.agent-1.0-agent.jar" set javaOpts=-server -Xms64m -Xmx256m -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing -XX:CMSIncrementalDutyCycleMin=0 -XX:CMSIncrementalDutyCycle=10 -XX:+UseParNewGC -%executeJava% %javaAgent% %javaOpts% -DNetCardIndex=0 -DJAppID=%appID% -DJAppGroup=UAV -classpath "%CLASSPATH%" com.creditease.mscp.boot.MSCPBoot -p %profile% +java %javaAgent% %javaOpts% -Djava.library.path=./lib -DNetCardIndex=0 -DJAppID=%appID% -DJAppGroup=UAV -classpath "%CLASSPATH%" com.creditease.mscp.boot.MSCPBoot -p %profile% diff --git a/com.creditease.uav.agent.buildComponent/exlib/Jpcap.dll b/com.creditease.uav.agent.buildComponent/exlib/Jpcap.dll new file mode 100644 index 00000000..0ab8aa17 Binary files /dev/null and b/com.creditease.uav.agent.buildComponent/exlib/Jpcap.dll differ diff --git a/com.creditease.uav.agent.buildComponent/exlib/Packet.dll b/com.creditease.uav.agent.buildComponent/exlib/Packet.dll new file mode 100644 index 00000000..a8bbfa4e Binary files /dev/null and b/com.creditease.uav.agent.buildComponent/exlib/Packet.dll differ diff --git a/com.creditease.uav.agent.buildComponent/exlib/jpcap.jar b/com.creditease.uav.agent.buildComponent/exlib/jpcap.jar new file mode 100644 index 00000000..3cbe0f3a Binary files /dev/null and b/com.creditease.uav.agent.buildComponent/exlib/jpcap.jar differ diff --git a/com.creditease.uav.agent.buildComponent/exlib/npf.sys b/com.creditease.uav.agent.buildComponent/exlib/npf.sys new file mode 100644 index 00000000..761c90c9 Binary files /dev/null and b/com.creditease.uav.agent.buildComponent/exlib/npf.sys differ diff --git a/com.creditease.uav.agent.buildComponent/exlib/wpcap.dll b/com.creditease.uav.agent.buildComponent/exlib/wpcap.dll new file mode 100644 index 00000000..eabb73dd Binary files /dev/null and b/com.creditease.uav.agent.buildComponent/exlib/wpcap.dll differ diff --git a/com.creditease.uav.agent.buildComponent/pom.xml b/com.creditease.uav.agent.buildComponent/pom.xml index 29c85537..4903c095 100644 --- a/com.creditease.uav.agent.buildComponent/pom.xml +++ b/com.creditease.uav.agent.buildComponent/pom.xml @@ -60,6 +60,8 @@ + + diff --git a/com.creditease.uav.agent.heartbeat/pom.xml b/com.creditease.uav.agent.heartbeat/pom.xml index ec2e9af0..e3c93d2e 100644 --- a/com.creditease.uav.agent.heartbeat/pom.xml +++ b/com.creditease.uav.agent.heartbeat/pom.xml @@ -35,7 +35,13 @@ com.creditease.uav.cache.redis - + + jpcap + jpcap + 1.0 + system + ${basedir}/../com.creditease.uav.agent.buildComponent/exlib/jpcap.jar + diff --git a/com.creditease.uav.agent.heartbeat/src/main/java/com/creditease/agent/feature/hbagent/handlers/HBClientDefaultHandler.java b/com.creditease.uav.agent.heartbeat/src/main/java/com/creditease/agent/feature/hbagent/handlers/HBClientDefaultHandler.java index 6bcb4cf2..f25b5e32 100644 --- a/com.creditease.uav.agent.heartbeat/src/main/java/com/creditease/agent/feature/hbagent/handlers/HBClientDefaultHandler.java +++ b/com.creditease.uav.agent.heartbeat/src/main/java/com/creditease/agent/feature/hbagent/handlers/HBClientDefaultHandler.java @@ -291,28 +291,25 @@ private String getIODiskInfo() throws Exception { if (JVMToolHelper.isWindows()) { File[] roots = File.listRoots(); - StringBuilder sb = new StringBuilder("{"); - + Map> resultMap = new HashMap>(); for (int i = 0; i < roots.length; i++) { File file = roots[i]; - sb.append("\"" + file.getPath() + "\":{") - .append("\"free\":\"" + Math.round((double) (file.getFreeSpace() / 1024)) + "\",")// 空闲空间 - .append("\"total\":\"" + +Math.round((double) (file.getTotalSpace() / 1024)) + "\",")// 总空间 - .append("\"use\":\"" - + +Math.round((double) ((file.getTotalSpace() - file.getFreeSpace()) / 1024)) + "\",")// 已使用空间 - .append("\"useRate\":\"" - + ((file.getTotalSpace() == 0) ? "0" - : (file.getTotalSpace() - file.getFreeSpace()) * 100 / file.getTotalSpace()) - + "%\"")// 空间占用率 - .append("}"); - - if (i < roots.length - 1) { - sb.append(","); - } + if (0 == file.getTotalSpace()) + continue; + + Map temp = new HashMap(); + temp.put("free", String.valueOf(Math.round((double) (file.getFreeSpace() / 1024)))); + temp.put("total", String.valueOf(Math.round((double) (file.getTotalSpace() / 1024)))); + temp.put("use", + String.valueOf(Math.round((double) ((file.getTotalSpace() - file.getFreeSpace()) / 1024)))); + temp.put("useRate", ((file.getTotalSpace() == 0) ? 0 + : (file.getTotalSpace() - file.getFreeSpace()) * 100 / file.getTotalSpace()) + "%"); + resultMap.put(file.getPath().substring(0, file.getPath().length() - 1), temp); } - sb.append("}"); - return sb.toString(); + dioc.collectWin(resultMap); + + return JSON.toJSONString(resultMap); } else { Map> resultMap = new HashMap>(); diff --git a/com.creditease.uav.agent.heartbeat/src/main/java/com/creditease/agent/feature/procdetectagent/NetworkIoDetector.java b/com.creditease.uav.agent.heartbeat/src/main/java/com/creditease/agent/feature/procdetectagent/NetworkIoDetector.java index a73304c4..f11c9fd9 100644 --- a/com.creditease.uav.agent.heartbeat/src/main/java/com/creditease/agent/feature/procdetectagent/NetworkIoDetector.java +++ b/com.creditease.uav.agent.heartbeat/src/main/java/com/creditease/agent/feature/procdetectagent/NetworkIoDetector.java @@ -20,12 +20,22 @@ package com.creditease.agent.feature.procdetectagent; +import java.text.DecimalFormat; +import java.util.HashMap; + +import com.creditease.agent.helpers.JSONHelper; import com.creditease.agent.helpers.JVMToolHelper; import com.creditease.agent.helpers.NetworkHelper; import com.creditease.agent.helpers.RuntimeHelper; import com.creditease.agent.spi.AbstractTimerWork; import com.creditease.agent.spi.AgentFeatureComponent; +import jpcap.JpcapCaptor; +import jpcap.NetworkInterface; +import jpcap.NetworkInterfaceAddress; +import jpcap.packet.Packet; +import jpcap.packet.TCPPacket; + public class NetworkIoDetector extends AbstractTimerWork { private String portList; @@ -39,49 +49,98 @@ public NetworkIoDetector(String cName, String feature) { @Override public void run() { - /** - * NOTE: not support windows yet - */ - if (JVMToolHelper.isWindows()) { + if (portList == null) { return; } - if (countDown != 0) { - countDown--; - return; + + String result = null; + String networkdetectTime = this.getConfigManager().getFeatureConfiguration(this.feature, + "networkDetect.collectTime"); + String ip = NetworkHelper.getLocalIP(); + + // windows + if (JVMToolHelper.isWindows()) { + + try { + String Local_ip = "/" + ip; + // ˿ + HashMap counter = new HashMap(); + String[] split_ProtList = portList.split(" "); + for (String str : split_ProtList) { + counter.put("in_" + str, 0); + counter.put("out_" + str, 0); + } + // ȡ豸б + NetworkInterface[] devices = JpcapCaptor.getDeviceList(); + // ȷ豸ӿ + boolean true_devices = false; + int i = 0; + for (; i < devices.length; i++) { + for (NetworkInterfaceAddress nia : devices[i].addresses) { + if (Local_ip.equals(nia.address.toString())) { + true_devices = true; + break; + } + + } + if (true_devices) { + break; + } + } + NetworkInterface nc = devices[i]; + // 豸 ijϵץȡ,Ϊ65535 + JpcapCaptor jpcap = JpcapCaptor.openDevice(nc, 65535, false, 20); + jpcap.setFilter("tcp", true);// ù + + // ץ ͳ + result = portFlux(jpcap, counter, nc, networkdetectTime, Local_ip); + + } + catch (Exception e) { + log.err(this, "NetworkIo Monitor runs FAIL.", e); + } + } - if (portList != null) { + + // linux + else { + + if (countDown != 0) { + countDown--; + return; + } + try { - String networkdetectTime = this.getConfigManager().getFeatureConfiguration(this.feature, - "networkDetect.collectTime"); - String ip = NetworkHelper.getLocalIP(); + String netcardName = NetworkHelper.getNetCardName(ip); String command = "cd bin; sh networkIoDetect.sh " + netcardName + " " + ip + " " + networkdetectTime + " " + portList; - String result = RuntimeHelper.exec(10000, "/bin/sh", "-c", command); + result = RuntimeHelper.exec(10000, "/bin/sh", "-c", command); if (!result.contains("in_") || result.toLowerCase().contains("error") || result.toLowerCase().contains("traceback")) { log.err(this, "NetworkIo Monitor runs FAIL with TechError: error=" + result); countDown = 100; return; } - - AgentFeatureComponent afc = (AgentFeatureComponent) this.getConfigManager().getComponent(this.feature, - "ProcDetectAgent"); - if (null != afc) { - afc.exchange("procscan.nodeinfo.portFlux", result, System.currentTimeMillis()); - } - - if (log.isDebugEnable()) { - log.debug(this, "NetworkIo Monitor Result: " + result); - } - } catch (Exception e) { log.err(this, "NetworkIo Monitor runs FAIL.", e); countDown = 100; } + } + + AgentFeatureComponent afc = (AgentFeatureComponent) this.getConfigManager().getComponent(this.feature, + "ProcDetectAgent"); + if (null != afc) { + afc.exchange("procscan.nodeinfo.portFlux", result, System.currentTimeMillis()); + } + + if (log.isDebugEnable()) { + log.debug(this, "NetworkIo Monitor Result: " + result); + } + } public void setPortList(String portList) { @@ -89,4 +148,51 @@ public void setPortList(String portList) { this.portList = portList; } + public String portFlux(JpcapCaptor jpcap, HashMap counter, NetworkInterface nc, + String networkdetectTime, String Local_ip) { + + Packet packet; + + int int_networkdetectTime = 1024 * Integer.parseInt(networkdetectTime) / 1000; + long time = Long.parseLong(networkdetectTime); + long startTime = System.currentTimeMillis(); + while (startTime + time >= System.currentTimeMillis()) { + // ץ + packet = jpcap.getPacket(); + if (null == packet) { + continue; + } + TCPPacket p = (TCPPacket) packet; + // ˿ڲprotList + String dst_ip = p.dst_ip.toString(); + String src_ip = p.src_ip.toString(); + // ͳ + if (dst_ip.equals(Local_ip)) { + String in_port = "in_" + p.dst_port; + if (counter.containsKey(in_port)) { + int in_value = counter.get(in_port) + p.len; + counter.put(in_port, in_value); + } + } + // ͳƳ + if (src_ip.equals(Local_ip)) { + String out_port = "out_" + p.src_port; + if (counter.containsKey(out_port)) { + int out_value = counter.get(out_port) + p.len; + counter.put(out_port, out_value); + } + } + } + + HashMap counterValueIntToString = new HashMap(); + // ֽתkb/s + for (String key : counter.keySet()) { + DecimalFormat df = new DecimalFormat("#0.00"); + Double value = Double.valueOf(df.format(counter.get(key) / int_networkdetectTime * 1.0)); + counterValueIntToString.put(key, value.toString()); + } + // hashmap תΪjson + return JSONHelper.toString(counterValueIntToString); + } + } diff --git a/com.creditease.uav.agent.heartbeat/src/main/java/com/creditease/agent/feature/procdetectagent/OSProcessScanner.java b/com.creditease.uav.agent.heartbeat/src/main/java/com/creditease/agent/feature/procdetectagent/OSProcessScanner.java index b381289b..8ec01b0e 100644 --- a/com.creditease.uav.agent.heartbeat/src/main/java/com/creditease/agent/feature/procdetectagent/OSProcessScanner.java +++ b/com.creditease.uav.agent.heartbeat/src/main/java/com/creditease/agent/feature/procdetectagent/OSProcessScanner.java @@ -312,7 +312,7 @@ public void scanWindowsProcesses(Map procs, StringBuffer port proc.addPort(port); portList = portList.append(port).append(" "); - if (!"UNKOWN".equals(proc.getName())) { + if (!"UNKNOWN".equals(proc.getName())) { continue; } diff --git a/com.creditease.uav.console/pom.xml b/com.creditease.uav.console/pom.xml index 3255e3dd..49d9162c 100644 --- a/com.creditease.uav.console/pom.xml +++ b/com.creditease.uav.console/pom.xml @@ -62,6 +62,12 @@ commons-logging 1.2 + + + aredis.sourceforge.net + aredis-api + 1.4 + diff --git a/com.creditease.uav.console/src/main/java/com/creditease/uav/xrobot/rest/XRobotRestService.java b/com.creditease.uav.console/src/main/java/com/creditease/uav/xrobot/rest/XRobotRestService.java index e88c46d7..37dda0bf 100644 --- a/com.creditease.uav.console/src/main/java/com/creditease/uav/xrobot/rest/XRobotRestService.java +++ b/com.creditease.uav.console/src/main/java/com/creditease/uav/xrobot/rest/XRobotRestService.java @@ -86,7 +86,7 @@ public void doCommand(String data, @Suspended AsyncResponse response) { UAVHttpMessage msg = new UAVHttpMessage(data); - this.doHttpPost("uav.app.xrobot.http.addr", "/xrobot", JSONHelper.toString(msg).getBytes(), "application/json", + this.doHttpPost("uav.app.xrobot.http.addr", "/hit/xrobot", JSONHelper.toString(msg).getBytes(), "application/json", "utf-8", new CmdCallback(response)); } diff --git a/com.creditease.uav.console/src/main/webapp/apphub/js/common/helper.js b/com.creditease.uav.console/src/main/webapp/apphub/js/common/helper.js index 9efb34b7..2865d8b3 100644 --- a/com.creditease.uav.console/src/main/webapp/apphub/js/common/helper.js +++ b/com.creditease.uav.console/src/main/webapp/apphub/js/common/helper.js @@ -449,7 +449,18 @@ var HtmlHelper={ var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); var r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); return undefined; - } + }, + //get all url params + getQParams:function() { + var vars = [], hash; + var hashes = window.location.href.slice(window.location.href.indexOf('?')+1).split('&'); + for(var i = 0; i < hashes.length; i++) { + hash = hashes[i].split('='); + vars.push(hash[0]); + vars[hash[0]] = hash[1]; + } + return vars; + } }; /** * 日志输出 diff --git a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/appmonitor/css/uav.appmonitor.css b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/appmonitor/css/uav.appmonitor.css index 2fbbd469..5d91a127 100644 --- a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/appmonitor/css/uav.appmonitor.css +++ b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/appmonitor/css/uav.appmonitor.css @@ -591,9 +591,17 @@ select{ } /*APM相关CSS*/ +.AppIVCWnd_AppMode { + height: 80px; + text-align: left; + padding-top: 5px; + padding-left: 5px; + color: #000; +} + .AppIVCWnd_GlobalMode{ font-size: 14px; - height: 80px; + height: 105px; text-align: left; padding-top: 0px; padding-left: 10px; diff --git a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/appmonitor/js/uav.apm.js b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/appmonitor/js/uav.apm.js index da404138..1f65df7f 100644 --- a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/appmonitor/js/uav.apm.js +++ b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/appmonitor/js/uav.apm.js @@ -303,25 +303,25 @@ function APMTool(app) { case 11: return ""+value+""; case 1: - return "
"+TimeHelper.getTime(value,"FMSN")+"
"; + return "
"+TimeHelper.getTime(value,"FMSN")+"
"; case 2: - return "
"+value+"
"; + return "
"+value+"
"; case 3: - return "
"+value+"
"; + return "
"+value+"
"; case 4: - return "
"+value+"
"; + return "
"+value+"
"; case 5: - return "
"+value+"
"; + return "
"+value+"
"; case 6: - return "
"+value+"
"; + return "
"+value+"
"; case 7: - return "
"+value+"
"; + return "
"+value+"
"; case 8: var color=""; if (value.indexOf(_this.appInfo["appid"])>-1) { color="font-weight:bold;color:#36648B;"; } - return "
"+value+"
"; + return "
"+value+"
"; case 9: return _this.UI_list_state(value,true); case 10: @@ -465,6 +465,8 @@ function APMTool(app) { ""+this.appInfo["appurl"]+"" + "
" + ""; + + html+="
"; } //全局模式 else { @@ -472,13 +474,27 @@ function APMTool(app) { html+= "
应用实例
"; } - html+="
" + - " "+ + html+="
时间
" + + "" + + "" + + "" + + + "" + + + "
"; + +// + "
搜索 " + + html+=" "+ " " + " " + - " " + - - "
"; + " " ; + html+="
"; return html; @@ -522,8 +538,43 @@ function APMTool(app) { this.mainList.cellClickUser = function(id,pNode) { app.controller.showWindow({traceid:id},"AppIVCTraceWnd","buildAppIVCTraceWnd","runAppIVCTraceWnd"); }; + + //init datetime picker + $('.form_datetime').datetimepicker({ + language : 'zh-CN', + autoclose : true, + minuteStep : 1, + minView: 1, + format:"yyyy-mm-dd hh", + todayBtn : true + }); + + //init timetrange selector + this.timeRangeSelector=new AppHubSelector({ + id:"AppIVCWnd_TimeRangeSelector", + cid:"AppIVCWnd_TimeRangeSelectorCtn", + title:"时间单位", + style:"font-size:12px;width:50px", + events:{ + onchange:"appAPM.onChangeTimeRangeSelector()" + } + }); + this.timeRangeSelector.init(); + this.timeRangeSelector.load([{title:"日期",value:"D"},{title:"小时",value:"H",select:true},{title:"分钟",value:"M"}]); + + //init time sort selector + this.timeSortSelector=new AppHubSelector({ + id:"AppIVCWnd_TimeSortSelector", + cid:"AppIVCWnd_TimeRangeSelectorCtn", + title:"时间排序方式", + style:"font-size:12px;width:50px" + }); + this.timeSortSelector.init(); + this.timeSortSelector.load([{title:"降序",value:"DESC", select:true},{title:"升序",value:"ASC"}]); }; + + /** * 调用链Trace窗口UI */ @@ -554,7 +605,7 @@ function APMTool(app) { /** * 跳转到重调用链明细页 */ - jumpAppIVCDataWnd = function(sObj){ + this.jumpAppIVCDataWnd = function(sObj){ var pNode = sObj.parentNode.parentNode; var spanid = pNode.getElementsByTagName("td")[0].id; var stime = pNode.getElementsByTagName("td")[1].id; @@ -569,7 +620,8 @@ function APMTool(app) { var parentid = $(pNode).attr("data-tt-parent-id"); app.controller.showWindow({traceid:traceid,stime:stime,url:url,epinfo:epinfo,clazz:clazz,method:method,ipport:ipport,appid:appid,state:state,spanid:spanid,parentid:parentid},"AppIVCDataWnd","buildAppIVCDataWnd","runAppIVCDataWnd"); - } + }; + /** * 重调用链窗口UI */ @@ -584,7 +636,7 @@ function APMTool(app) { "
"; var sb=new StringBuffer(); - sb.append("
" + + sb.append("
" + "
" + " 时间"+ TimeHelper.getTime(Number(sObj["stime"]),"FMS") +""+ "
" + @@ -609,8 +661,8 @@ function APMTool(app) { "
" + " 状态"+ _this.UI_list_state(sObj["state"],false) +""+ "
" + - " 元数据" + - " "); + html+="
"+sb.toString()+"
"; return html; }; @@ -716,16 +771,16 @@ function APMTool(app) { } if(isEmpty){ - var errMsg = "数据处理中,请刷新重试"; + var errMsg = "无数据,请刷新重试"; var epinfo = sObj["epinfo"].split(",")[0]; //当前支持的类型 var epinfos = ["http.service","apache.http.Client","apache.http.AsyncClient","mq.service","rabbitmq.client","jdbc.client","method","dubbo.provider","dubbo.consumer"]; if($.inArray(epinfo, epinfos)==-1){ - errMsg = "不支持的数据类型,努力更新中..."; + errMsg = "不支持的数据类型"; } sb.append(""+errMsg+""); } - HtmlHelper.id("AppIVCDataWnd_TContainer_ContentDiv").innerHTML+=sb.toString(); + HtmlHelper.id("AppIVCDataWnd_TContainer_ContentDiv").innerHTML=sb.toString(); } @@ -941,6 +996,37 @@ function APMTool(app) { } switch(intent) { + /** + * 完整查询 + */ + case "qsearch": + dataList=this.mainList; + + var timeRange=_this.getCurTimeRange(); + + if (timeRange==undefined) { + var tmp=new Date().getTime(); + timeRange={etime:tmp,stime:tmp-60000}; + } + + var etime=timeRange["etime"]; + var stime=timeRange["stime"]; + data["request"]["appuuid"]=appuuid; + data["request"]["stime"]=stime+""; + data["request"]["etime"]=etime+""; + data["request"]["eptype"]="E,S"; + data["request"]["from"]=0+""; + data["request"]["size"]=500+""; + data["request"]["indexdate"]=timeRange["indexdate"]; + + var timeSort=this.timeSortSelector.value(); + if (timeSort=="DESC") { + data["request"]["sort"]="stime=DESC"; + } + else { + data["request"]["sort"]="stime=ASC"; + } + break; case "lst1min": dataList=this.mainList; @@ -1092,6 +1178,97 @@ function APMTool(app) { this.runIVCCfgWnd=function(sObj) { }; + + //TODO -----------------------------------------------调用链时间控制------------------------------------------ + /** + * 改变时间区段的单位 + */ + this.onChangeTimeRangeSelector=function() { + + var val=this.timeRangeSelector.value(); + + if (val=="D") { + $('.form_datetime').datetimepicker("remove"); + HtmlHelper.id("AppIVCWnd_TimeRange").value=""; + $('.form_datetime').datetimepicker({ + language : 'zh-CN', + autoclose : true, + minuteStep : 1, + minView: 2, + format:"yyyy-mm-dd", + todayBtn : true + }); + } + else if (val=="H") { + $('.form_datetime').datetimepicker("remove"); + HtmlHelper.id("AppIVCWnd_TimeRange").value=""; + $('.form_datetime').datetimepicker({ + language : 'zh-CN', + autoclose : true, + minuteStep : 1, + minView: 1, + format:"yyyy-mm-dd hh", + todayBtn : true + }); + } + else if (val=="M") { + $('.form_datetime').datetimepicker("remove"); + HtmlHelper.id("AppIVCWnd_TimeRange").value=""; + $('.form_datetime').datetimepicker({ + language : 'zh-CN', + autoclose : true, + minuteStep : 1, + minView: 0, + format:"yyyy-mm-dd hh:ii", + todayBtn : true + }); + } + + }; + + /** + * 清除时间选择 + */ + this.cleanTimeRange=function() { + HtmlHelper.id("AppIVCWnd_TimeRange").value=""; + }; + + /** + * 获取当前的时间区段 + */ + this.getCurTimeRange=function() { + + var timeRange=HtmlHelper.id("AppIVCWnd_TimeRange").value; + var timeUnit=this.timeRangeSelector.value(); + + //全部时间 + if (timeRange=="") { + return undefined; + } + + var date; + var plus; + switch(timeUnit) { + case "D": + date=TimeHelper.toDate(timeRange+" 00:00:00"); + plus=24*3600*1000; + break; + case "H": + date=TimeHelper.toDate(timeRange+":00:00"); + plus=3600*1000; + break; + case "M": + date=TimeHelper.toDate(timeRange+":00"); + plus=60*1000; + break; + } + + var startTime=date.getTime(); + var endTime=startTime+plus; + var reqDate=TimeHelper.getTime(startTime,"FD"); + + return {stime:startTime,etime:endTime,indexdate:reqDate}; + }; } diff --git a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/appmonitor/js/uav.appmonitor.js b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/appmonitor/js/uav.appmonitor.js index 28d8cf1e..dba892d9 100644 --- a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/appmonitor/js/uav.appmonitor.js +++ b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/appmonitor/js/uav.appmonitor.js @@ -1019,6 +1019,39 @@ var monitorCfg={ } }; +/** + * TODO: open link + */ +var openLink={ + + /** + * 延迟打开window + * @param ip + * @param winId + * @param func + * @param callback + * @param tag + */ + showWindowDelay:function(ip,winId,func,callback,tag) { + var info={ip:ip,winId:winId,func:func,callback:callback,tag:tag}; + window["openlink_"+tag]=info; + }, + + /** + * 触发点执行打开窗口 + * @param tag + */ + runWindowDelay:function(tag) { + if (window["openlink_"+tag]==undefined) { + return; + } + + var info=window["openlink_"+tag]; + app.controller.showWindow(info["ip"],info["winId"],info["func"],info["callback"]); + window["openlink_"+tag]=undefined; + } +}; + /** * TODO:应用画像与监控 */ @@ -1255,12 +1288,25 @@ var mvcObj={ //not start sync return false; } + // for 应用实例监控 + else if (view=="appinst") { + window.winmgr.show("AppInstWnd"); + var param=HtmlHelper.getQParams()["param"]; + param=decodeURI(param); + var params=param.split(","); + var id=params[0]; + var instid=params[1]; + var isJse=params[2]; + var appInfo={id:id,instid:instid,isJse:isJse}; + openLink.showWindowDelay(appInfo,"AppInstChartWnd","buildAppInstChart","runAppInstChart","monitorapp"); + } //for 应用监控 else { - window.winmgr.show("AppList"); - window.tablistmgr.build(appTabListConfig); + window.winmgr.show("AppList"); } + //init app tab list + window.tablistmgr.build(appTabListConfig); //init monitorcfg dialog this.controller.initMonitorCfgDialog(); }, @@ -1552,6 +1598,7 @@ var mvcObj={ "cpt.jaxrs":"cpt.jaxrs", "cpt.springmvc":"cpt.springmvc", "cpt.springmvcRest":"cpt.springmvcRest", + "cpt.struts2":"cpt.struts2", state:"state", "cpt.services":"cpt.services", "cpt.clients":"cpt.clients", @@ -1735,6 +1782,9 @@ var mvcObj={ //启动图谱的Edge的刷新 appStream.startAppEdgeMoUpdate(); + + //完成openlink事件 + openLink.runWindowDelay("monitorapp"); }, //--------------元数据定义----------------- //primary key @@ -1924,6 +1974,13 @@ var mvcObj={ */ controller:{ //----------------------COMMON-------------------------- + /** + * TODO: delay open + */ + showWindowDelay:function(iObj,winId,func,callback,tag) { + var info={iObj:iObj,winId:winId,func:func,callback:callback,tag:tag}; + window["openlink_"+tag]=info; + }, /** * TODO: controller COMMON */ @@ -2307,7 +2364,7 @@ var mvcObj={ /** * check if one app instance window is open and try to query history data */ - if (monitorCfg.app["id"]!=undefined) { + if (monitorCfg.app["id"]!=undefined&&monitorCfg["app"].isusecustomized==true) { pdata=[pdata[monitorCfg.app["id"]]]; } } @@ -2912,6 +2969,10 @@ var mvcObj={ */ quitMonitorChartData:function(dType) { + if (dType=="app") { + monitorCfg.app["id"]=undefined; + } + if (monitorCfg[dType].isusecustomized==false) { return; } @@ -2923,16 +2984,12 @@ var mvcObj={ if (dType=="app") { monitorCfg.startTime=undefined; + //reset isautorefresh + monitorCfg.isautorefresh=true; + + app.refresh("app.monitor"); } - switch(dType) { - case "app": - //reset isautorefresh - monitorCfg.isautorefresh=true; - monitorCfg.app["id"]=undefined; - app.refresh("app.monitor"); - break; - } }, /** * init LogCfgDialog @@ -3654,6 +3711,13 @@ var mvcObj={ var jsonObj=mdata[obj.id]; + if(jsonObj==undefined) { + setTimeout(function() { + openLink.runWindowDelay("monitorapp"); + },1000); + return; + } + var isJse=this.isJSE(jsonObj.appurl); if (isJse==true) { @@ -3665,6 +3729,10 @@ var mvcObj={ var appInstMO=app.mdata("monitor.app")[appInstMOId]; + if (appInstMO==undefined) { + console.log(appInstMOId+" monitor data is null~~~"); + } + var sObjStr=StringHelper.obj2str(obj); var backWndId=""; @@ -3734,6 +3802,19 @@ var mvcObj={ html+="
"+this.buildAppInstServerWndContent(jsonObj)+ "
"; + /** + * 主机(应用容器)查看窗口 + */ + html+="
"+this.buildAppMachineWndContent(jsonObj,appInstMOId,isJse)+ + "
"; + + /** + * 应用进程查看窗口 + */ + html+="
"+this.buildAppProcessWndContent(jsonObj,appInstMOId,isJse)+ + "
"; + + /** * AppInst Chart 日志组件按钮列表,可以打开日志组件查看窗口 */ @@ -3756,6 +3837,42 @@ var mvcObj={ html+="
"; return html; }, + /** + * buildAppMachineWndContent + */ + buildAppMachineWndContent:function(jsonObj,appInstMOId,isJse) { + var ip=jsonObj["ip"]; + var sb=new StringBuffer(); + var param=encodeURI(jsonObj["id"]+","+appInstMOId+","+isJse); + sb.append("应用容器 "+ip+""); + + return sb.toString(); + }, + /** + * buildAppProcessWndContent + */ + buildAppProcessWndContent:function(jsonObj,appInstMOId,isJse) { + var ip=jsonObj["ip"]; + var proc; + //jse can get the pid directly + if (isJse) { + var jseInfo=jsonObj["appurl"].split("-"); + proc="pid="+jseInfo[jseInfo.length-1]; + } + //jee can get the port + else { + var ipport=app.controller.getAppInstIPPort( jsonObj["appurl"]); + proc="port="+ipport.split(":")[2]; + } + + var param=encodeURI(jsonObj["id"]+","+appInstMOId+","+isJse); + + var sb=new StringBuffer(); + + sb.append("应用进程"); + + return sb.toString(); + }, /** * App Customized Metrics */ @@ -4505,6 +4622,10 @@ var mvcObj={ if (jsonObj["cpt.springmvcRest"]!=undefined&&jsonObj["cpt.springmvcRest"]!="{}") { sb.append("组件[SpringMVCRest]" ); } + + if (jsonObj["cpt.struts2"]!=undefined&&jsonObj["cpt.struts2"]!="{}") { + sb.append("组件[Struts2]" ); + } sb.append("
"); sb.append("
其他组件"); @@ -5324,7 +5445,7 @@ var mvcObj={ var ret = JSON.parse(data); if(ret.code){ // dba server error... if(ret.code == 20002){ - alert("该数据源性能数据不存在。\n注:数据源性能数据由系统部DBA提供,如有疑问请联系dba.list"); + alert("该数据源性能数据不存在。\n注:数据源性能数据由系统部DBA提供,如有疑问请联系dba.list@creditease.cn"); } app.controller.accessDbInstData(reqs,index+1,models); return; @@ -5379,7 +5500,7 @@ var mvcObj={ if(ret.code){ // dba server error... app.controller.openClose(id); console.log(data); - alert("访问数据源性能数据服务失败!\n注:数据源性能数据由系统部DBA提供,如有疑问请联系dba.list"); + alert("访问数据源性能数据服务失败!\n注:数据源性能数据由系统部DBA提供,如有疑问请联系dba.list@creditease.cn"); return; } var html = '
'; diff --git a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/uavnetwork/js/uav.network.js b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/uavnetwork/js/uav.network.js index 0bec415d..f5942605 100644 --- a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/uavnetwork/js/uav.network.js +++ b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/uavnetwork/js/uav.network.js @@ -376,6 +376,9 @@ var dataCacheCfg={ var dataCache={}; +/** + * TODO: UserFilterCache + */ var UserFilterCache={ all:false, nomapping:false, @@ -775,6 +778,80 @@ var preUpgradeDialog = { } } +/** + * TODO: open link + */ +var openLink={ + + /** + * 延迟打开window + * @param ip + * @param winId + * @param func + * @param callback + * @param tag + */ + showWindowDelay:function(ip,winId,func,callback,tag,proc) { + + var info={ip:ip,winId:winId,func:func,callback:callback,tag:tag}; + + if (proc!=undefined) { + if (proc["pid"]!=undefined) { + info["pid"]=proc["pid"]; + } + else { + info["port"]=proc["port"]; + } + } + + window["openlink_"+tag]=info; + }, + + /** + * 触发点执行打开窗口 + * @param tag + */ + runWindowDelay:function(tag) { + if (window["openlink_"+tag]==undefined) { + return; + } + + var info=window["openlink_"+tag]; + window["openlink_"+tag]=undefined; + if (tag=="procinfo") { + + var pid=info["pid"]; + //need find pid by port + if (pid==undefined) { + var macInfo=app.mdata("macinfo")[info["ip"]]; + + var procs=eval("("+macInfo["node.procs"]+")"); + + for(var key in procs) { + + var proc=procs[key]; + + var ports=proc["ports"]; + + for(var i=0;i\n" + "
\n" + " "+resultObj["host"]+"
\n" + " "+resultObj["ip"]+"\n" + - "
\n" + + "
\n" + "
\n" + "
" + "
" + @@ -2099,6 +2219,12 @@ var mvcObj={ buildProcessChartContent : function(resultObj,pid){ var procs=eval("("+resultObj["node.procs"]+")"); var proc=procs[pid]; + + if (proc==undefined) { + alert("进程号["+pid+"]的进程在["+resultObj["ip"]+"]不存在!") + return; + } + var ports=proc["ports"]; var connSeries=[ { @@ -2152,12 +2278,25 @@ var mvcObj={ window["appcharts"].bulid(processConnChartCfg); window["appcharts"].bulid(processFluxChartCfg); - + + var backScript="javascript:app.controller.closeWindow('ProcessChartWnd','destroyProcessChart')"; + + //if open link + var view=HtmlHelper.getQParam("view"); + + if (view!=undefined) { + var from=HtmlHelper.getQParam("from"); + var fview=HtmlHelper.getQParam("fview"); + var fparam=HtmlHelper.getQParams()["fparam"]; + var burl=from+"?view="+fview+"¶m="+fparam; + backScript="window.parent.jumpUrl('"+burl+"','应用监控')"; + } + return "
\n" + "
\n" + " "+resultObj["ip"]+"
\n" + " "+"["+pid+"] "+app.controller.getJavaProName(proc)+"\n" + - "
\n" + + "
\n" + "
\n" + "
" + "
" + diff --git a/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_apphubmgr.properties b/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_apphubmgr.properties index 114787ef..87d8f50b 100644 --- a/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_apphubmgr.properties +++ b/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_apphubmgr.properties @@ -98,18 +98,21 @@ feature.healthmanager.components=com.creditease.uav.feature.HealthManager feature.healthmanager.properties= #feature.xxx. feature.healthmanager.messagingnameserver=127.0.0.1:9876;127.0.0.1:9876;127.0.0.1:9876 -feature.healthmanager.MT_Monitor.consumethreadmax=5 +feature.healthmanager.MT_Monitor.consumethreadmax=10 feature.healthmanager.MT_Notify.consumethreadmax=10 feature.healthmanager.MT_Profile.consumethreadmax=10 -feature.healthmanager.MT_Log.consumethreadmax=5 +feature.healthmanager.MT_Log.consumethreadmax=10 +feature.healthmanager.MT_Node.consumethreadmax=10 feature.healthmanager.MT_Monitorconsumestopinterval=0 feature.healthmanager.MT_Notify.consumestopinterval=0 feature.healthmanager.MT_Profile.consumestopinterval=0 feature.healthmanager.MT_Log.consumestopinterval=0 +feature.healthmanager.MT_Node.consumestopinterval=0 feature.healthmanager.MT_Monitor.enable=false feature.healthmanager.MT_Notify.enable=false feature.healthmanager.MT_Profile.enable=false feature.healthmanager.MT_Log.enable=false +feature.healthmanager.MT_Node.enable=false #feature.healthmanager.healthmanger handlers feature.healthmanager.healthMangerHandlers=com.creditease.uav.feature.healthmanager.http.handlers.HMDataStoreQueryHandler,com.creditease.uav.feature.healthmanager.http.handlers.HMCacheQueryHandler feature.healthmanager.http.port=8044 diff --git a/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_logserver.properties b/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_logserver.properties index 5d25f424..ad29351d 100644 --- a/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_logserver.properties +++ b/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_logserver.properties @@ -83,14 +83,17 @@ feature.healthmanager.MT_Monitor.consumethreadmax=5 feature.healthmanager.MT_Notify.consumethreadmax=5 feature.healthmanager.MT_Profile.consumethreadmax=5 feature.healthmanager.MT_Log.consumethreadmax=20 +feature.healthmanager.MT_Node.consumethreadmax=10 feature.healthmanager.MT_Monitorconsumestopinterval=0 feature.healthmanager.MT_Notify.consumestopinterval=0 feature.healthmanager.MT_Profile.consumestopinterval=0 feature.healthmanager.MT_Log.consumestopinterval=0 +feature.healthmanager.MT_Node.consumestopinterval=0 feature.healthmanager.MT_Monitor.enable=false feature.healthmanager.MT_Notify.enable=false feature.healthmanager.MT_Profile.enable=false feature.healthmanager.MT_Log.enable=true +feature.healthmanager.MT_Node.enable=false #feature.healthmanager.healthmanger handlers feature.healthmanager.healthMangerHandlers=com.creditease.uav.feature.healthmanager.http.handlers.HMDataStoreQueryHandler,com.creditease.uav.feature.healthmanager.http.handlers.HMCacheQueryHandler feature.healthmanager.http.port=8041 diff --git a/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_moserver.properties b/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_moserver.properties index 64c331ca..7bed4cb7 100644 --- a/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_moserver.properties +++ b/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_moserver.properties @@ -81,17 +81,20 @@ feature.healthmanager.properties= #feature.xxx. feature.healthmanager.messagingnameserver=127.0.0.1:9876;127.0.0.1:9876;127.0.0.1:9876 feature.healthmanager.MT_Monitor.consumethreadmax=50 -feature.healthmanager.MT_Notify.consumethreadmax=5 -feature.healthmanager.MT_Profile.consumethreadmax=5 -feature.healthmanager.MT_Log.consumethreadmax=5 +feature.healthmanager.MT_Notify.consumethreadmax=10 +feature.healthmanager.MT_Profile.consumethreadmax=10 +feature.healthmanager.MT_Log.consumethreadmax=10 +feature.healthmanager.MT_Node.consumethreadmax=10 feature.healthmanager.MT_Monitorconsumestopinterval=0 feature.healthmanager.MT_Notify.consumestopinterval=0 feature.healthmanager.MT_Profile.consumestopinterval=0 feature.healthmanager.MT_Log.consumestopinterval=0 +feature.healthmanager.MT_Node.consumestopinterval=0 feature.healthmanager.MT_Monitor.enable=true feature.healthmanager.MT_Notify.enable=false feature.healthmanager.MT_Profile.enable=false feature.healthmanager.MT_Log.enable=false +feature.healthmanager.MT_Node.enable=false #feature.healthmanager.healthmanger handlers feature.healthmanager.healthMangerHandlers=com.creditease.uav.feature.healthmanager.http.handlers.HMDataStoreQueryHandler,com.creditease.uav.feature.healthmanager.http.handlers.HMCacheQueryHandler feature.healthmanager.http.port=8042 diff --git a/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_nodeserver.properties b/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_nodeserver.properties index b5770671..bf812b15 100644 --- a/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_nodeserver.properties +++ b/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_nodeserver.properties @@ -84,7 +84,7 @@ feature.healthmanager.MT_Monitor.consumethreadmax=10 feature.healthmanager.MT_Notify.consumethreadmax=10 feature.healthmanager.MT_Profile.consumethreadmax=10 feature.healthmanager.MT_Log.consumethreadmax=10 -feature.healthmanager.MT_Node.consumethreadmax=50 +feature.healthmanager.MT_Node.consumethreadmax=10 feature.healthmanager.MT_Monitorconsumestopinterval=0 feature.healthmanager.MT_Notify.consumestopinterval=0 feature.healthmanager.MT_Profile.consumestopinterval=0 diff --git a/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_pfntfyserver.properties b/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_pfntfyserver.properties index 3f0907a3..ab40d611 100644 --- a/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_pfntfyserver.properties +++ b/com.creditease.uav.healthmanager.buildComponent/config/hm_pro_pfntfyserver.properties @@ -80,18 +80,21 @@ feature.healthmanager.components=com.creditease.uav.feature.HealthManager feature.healthmanager.properties= #feature.xxx. feature.healthmanager.messagingnameserver=127.0.0.1:9876;127.0.0.1:9876;127.0.0.1:9876 -feature.healthmanager.MT_Monitor.consumethreadmax=5 +feature.healthmanager.MT_Monitor.consumethreadmax=10 feature.healthmanager.MT_Notify.consumethreadmax=15 feature.healthmanager.MT_Profile.consumethreadmax=25 -feature.healthmanager.MT_Log.consumethreadmax=5 +feature.healthmanager.MT_Log.consumethreadmax=10 +feature.healthmanager.MT_Node.consumethreadmax=10 feature.healthmanager.MT_Monitorconsumestopinterval=0 feature.healthmanager.MT_Notify.consumestopinterval=0 feature.healthmanager.MT_Profile.consumestopinterval=0 feature.healthmanager.MT_Log.consumestopinterval=0 +feature.healthmanager.MT_Node.consumestopinterval=0 feature.healthmanager.MT_Monitor.enable=false feature.healthmanager.MT_Notify.enable=true feature.healthmanager.MT_Profile.enable=true feature.healthmanager.MT_Log.enable=false +feature.healthmanager.MT_Node.enable=false #feature.healthmanager.healthmanger handlers feature.healthmanager.healthMangerHandlers=com.creditease.uav.feature.healthmanager.http.handlers.HMDataStoreQueryHandler,com.creditease.uav.feature.healthmanager.http.handlers.HMCacheQueryHandler feature.healthmanager.http.port=8043 diff --git a/com.creditease.uav.healthmanager.buildComponent/config/hm_test_logserver.properties b/com.creditease.uav.healthmanager.buildComponent/config/hm_test_logserver.properties index f54a0bb2..16aeb53e 100644 --- a/com.creditease.uav.healthmanager.buildComponent/config/hm_test_logserver.properties +++ b/com.creditease.uav.healthmanager.buildComponent/config/hm_test_logserver.properties @@ -81,17 +81,20 @@ feature.healthmanager.properties= #feature.xxx. feature.healthmanager.messagingnameserver=127.0.0.1:9876 feature.healthmanager.MT_Monitor.consumethreadmax=5 -feature.healthmanager.MT_Notify.consumethreadmax=10 -feature.healthmanager.MT_Profile.consumethreadmax=10 +feature.healthmanager.MT_Notify.consumethreadmax=5 +feature.healthmanager.MT_Profile.consumethreadmax=5 feature.healthmanager.MT_Log.consumethreadmax=20 +feature.healthmanager.MT_Node.consumethreadmax=10 feature.healthmanager.MT_Monitorconsumestopinterval=0 feature.healthmanager.MT_Notify.consumestopinterval=0 feature.healthmanager.MT_Profile.consumestopinterval=0 feature.healthmanager.MT_Log.consumestopinterval=0 +feature.healthmanager.MT_Node.consumestopinterval=0 feature.healthmanager.MT_Monitor.enable=false feature.healthmanager.MT_Notify.enable=false feature.healthmanager.MT_Profile.enable=false feature.healthmanager.MT_Log.enable=true +feature.healthmanager.MT_Node.enable=false #feature.healthmanager.healthmanger handlers feature.healthmanager.healthMangerHandlers=com.creditease.uav.feature.healthmanager.http.handlers.HMDataStoreQueryHandler,com.creditease.uav.feature.healthmanager.http.handlers.HMCacheQueryHandler feature.healthmanager.http.port=8042 diff --git a/com.creditease.uav.healthmanager.buildComponent/config/hm_test_moserver.properties b/com.creditease.uav.healthmanager.buildComponent/config/hm_test_moserver.properties index 31c706b1..fd792739 100644 --- a/com.creditease.uav.healthmanager.buildComponent/config/hm_test_moserver.properties +++ b/com.creditease.uav.healthmanager.buildComponent/config/hm_test_moserver.properties @@ -84,14 +84,17 @@ feature.healthmanager.MT_Monitor.consumethreadmax=35 feature.healthmanager.MT_Notify.consumethreadmax=10 feature.healthmanager.MT_Profile.consumethreadmax=10 feature.healthmanager.MT_Log.consumethreadmax=10 +feature.healthmanager.MT_Node.consumethreadmax=10 feature.healthmanager.MT_Monitorconsumestopinterval=0 feature.healthmanager.MT_Notify.consumestopinterval=0 feature.healthmanager.MT_Profile.consumestopinterval=0 feature.healthmanager.MT_Log.consumestopinterval=0 +feature.healthmanager.MT_Node.consumestopinterval=0 feature.healthmanager.MT_Monitor.enable=true feature.healthmanager.MT_Notify.enable=false feature.healthmanager.MT_Profile.enable=false feature.healthmanager.MT_Log.enable=false +feature.healthmanager.MT_Node.enable=false #feature.healthmanager.healthmanger handlers feature.healthmanager.healthMangerHandlers=com.creditease.uav.feature.healthmanager.http.handlers.HMDataStoreQueryHandler,com.creditease.uav.feature.healthmanager.http.handlers.HMCacheQueryHandler feature.healthmanager.http.port=8043 diff --git a/com.creditease.uav.healthmanager.buildComponent/config/hm_test_nodeserver.properties b/com.creditease.uav.healthmanager.buildComponent/config/hm_test_nodeserver.properties index be80319c..d0fc078c 100644 --- a/com.creditease.uav.healthmanager.buildComponent/config/hm_test_nodeserver.properties +++ b/com.creditease.uav.healthmanager.buildComponent/config/hm_test_nodeserver.properties @@ -84,7 +84,7 @@ feature.healthmanager.MT_Monitor.consumethreadmax=10 feature.healthmanager.MT_Notify.consumethreadmax=10 feature.healthmanager.MT_Profile.consumethreadmax=10 feature.healthmanager.MT_Log.consumethreadmax=10 -feature.healthmanager.MT_Node.consumethreadmax=35 +feature.healthmanager.MT_Node.consumethreadmax=10 feature.healthmanager.MT_Monitorconsumestopinterval=0 feature.healthmanager.MT_Notify.consumestopinterval=0 feature.healthmanager.MT_Profile.consumestopinterval=0 diff --git a/com.creditease.uav.healthmanager.buildComponent/config/hm_test_pnhbserver.properties b/com.creditease.uav.healthmanager.buildComponent/config/hm_test_pnhbserver.properties index c7bf0568..54d67f84 100644 --- a/com.creditease.uav.healthmanager.buildComponent/config/hm_test_pnhbserver.properties +++ b/com.creditease.uav.healthmanager.buildComponent/config/hm_test_pnhbserver.properties @@ -151,18 +151,21 @@ feature.healthmanager.components=com.creditease.uav.feature.HealthManager feature.healthmanager.properties= #feature.xxx. feature.healthmanager.messagingnameserver=127.0.0.1:9876 -feature.healthmanager.MT_Monitor.consumethreadmax=5 +feature.healthmanager.MT_Monitor.consumethreadmax=10 feature.healthmanager.MT_Notify.consumethreadmax=10 feature.healthmanager.MT_Profile.consumethreadmax=10 -feature.healthmanager.MT_Log.consumethreadmax=5 +feature.healthmanager.MT_Log.consumethreadmax=10 +feature.healthmanager.MT_Node.consumethreadmax=10 feature.healthmanager.MT_Monitorconsumestopinterval=0 feature.healthmanager.MT_Notify.consumestopinterval=0 feature.healthmanager.MT_Profile.consumestopinterval=0 feature.healthmanager.MT_Log.consumestopinterval=0 +feature.healthmanager.MT_Node.consumestopinterval=0 feature.healthmanager.MT_Monitor.enable=false feature.healthmanager.MT_Notify.enable=true feature.healthmanager.MT_Profile.enable=true feature.healthmanager.MT_Log.enable=false +feature.healthmanager.MT_Node.enable=false #feature.healthmanager.healthmanger handlers feature.healthmanager.healthMangerHandlers=com.creditease.uav.feature.healthmanager.http.handlers.HMDataStoreQueryHandler,com.creditease.uav.feature.healthmanager.http.handlers.HMCacheQueryHandler feature.healthmanager.http.port=8041 diff --git a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/healthmanager/messaging/handlers/ProfileDataMessageHandler.java b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/healthmanager/messaging/handlers/ProfileDataMessageHandler.java index 55ad286d..60eb28be 100644 --- a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/healthmanager/messaging/handlers/ProfileDataMessageHandler.java +++ b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/healthmanager/messaging/handlers/ProfileDataMessageHandler.java @@ -21,8 +21,10 @@ package com.creditease.uav.feature.healthmanager.messaging.handlers; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -553,13 +555,228 @@ private void buildJEEServiceComponents(MonitorDataFrame mdf, Map getSpringMVCURLs(springmvcBaseURL, compServices, springMVCRest); - pi.put("cpt.servlets", JSONHelper.toString(servlets)); + // get struts2 urls + Map strutsAction = mdf.getElemInstValues(appid, "cpt", "com.opensymphony.xwork2.Action"); + getStruts2URLs(appurl, compServices, strutsAction); + pi.put("cpt.servlets", JSONHelper.toString(servlets)); pi.put("cpt.jaxws", JSONHelper.toString(jaxws)); pi.put("cpt.jaxwsP", JSONHelper.toString(jaxwsProviders)); pi.put("cpt.jaxrs", JSONHelper.toString(jaxrs)); pi.put("cpt.springmvc", JSONHelper.toString(springMVC)); pi.put("cpt.springmvcRest", JSONHelper.toString(springMVCRest)); + pi.put("cpt.struts2", JSONHelper.toString(strutsAction)); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private void getStruts2URLsByAnno(String appurl, Map> compServices, + Map strutsAction, String key, Set extSet) { + + Set compServicesURLs = compServices.get(key); + if (compServicesURLs == null) { + compServicesURLs = new HashSet(); + compServices.put(key, compServicesURLs); + } + + Map valueMap = (Map) strutsAction.get(key); + + Map methodsMap = (Map) valueMap.get("methods"); + Map classAnnoMap = (Map) valueMap.get("anno"); + + // get namespaces + Set namespaces = new HashSet(); + + if (classAnnoMap != null && classAnnoMap.size() > 0) { + for (Map.Entry classAnno : classAnnoMap.entrySet()) { + + String annoKey = classAnno.getKey(); + Object annoValue = classAnno.getValue(); + + if ("org.apache.struts2.convention.annotation.Namespace".equals(annoKey)) { + namespaces.add((String) ((Map) annoValue).get("value")); + } + + if ("org.apache.struts2.convention.annotation.Namespaces".equals(annoKey)) { + + List aList = (List) ((Map) annoValue).get("value"); + + for (Object obj : aList) { + namespaces.add((String) ((Map) obj).get("value")); + } + } + + } + } + else { + namespaces.add("/"); + } + + // get actions + Set actionNames = new HashSet(); + if (methodsMap != null) { + for (Map.Entry method : methodsMap.entrySet()) { + + Map map = (Map) method.getValue(); + if (map.get("anno") == null) { + continue; + } + + Map methodAnnoMap = (Map) map.get("anno"); + + for (Map.Entry methodAnno : methodAnnoMap.entrySet()) { + + String annoKey = methodAnno.getKey(); + Object annoValue = methodAnno.getValue(); + + // if have Actions annotation ignore Action annotation + if ("org.apache.struts2.convention.annotation.Actions".equals(annoKey)) { + + List aList = (List) ((Map) annoValue).get("value"); + + for (Object obj : aList) { + actionNames.add((String) ((Map) obj).get("value")); + } + + continue; + } + + if ("org.apache.struts2.convention.annotation.Action".equals(annoKey) + && !methodAnnoMap.containsKey("org.apache.struts2.convention.annotation.Actions")) { + actionNames.add((String) ((Map) annoValue).get("value")); + } + } + } + } + + Iterator nsIterator = namespaces.iterator(); + while (nsIterator.hasNext()) { + String ns = nsIterator.next(); + + if (!"/".equals(ns)) { + ns = ns + "/"; + } + + Iterator actionNamesIterator = actionNames.iterator(); + while (actionNamesIterator.hasNext()) { + String actionName = actionNamesIterator.next(); + + Iterator extIterator = extSet.iterator(); + while (extIterator.hasNext()) { + String ext = extIterator.next(); + if (!"".equals(ext)) { + ext = "." + ext; + } + compServicesURLs.add(appurl.substring(0, appurl.length() - 1) + ns + actionName + ext); + } + + } + } + } + + @SuppressWarnings("unchecked") + private void getStruts2URLsByDes(String appurl, Map> compServices, + Map strutsAction, String key, Set extSet) { + + Set compServicesURLs = compServices.get(key); + if (compServicesURLs == null) { + compServicesURLs = new HashSet(); + compServices.put(key, compServicesURLs); + } + + Map valueMap = (Map) strutsAction.get(key); + + // get action urls by des + List desList = (List) (valueMap.get("des")); + if (desList == null || desList.size() <= 0) { + return; + } + + Iterator extIterator = extSet.iterator(); + while (extIterator.hasNext()) { + String ext = extIterator.next(); + if (!"".equals(ext)) { + ext = "." + ext; + } + + for (Object desObj : desList) { + Map aMap = (Map) desObj; + + String ns = (String) aMap.get("namespace"); + + if (!"/".equals(ns)) { + ns = ns + "/"; + } + + compServicesURLs.add(appurl.substring(0, appurl.length() - 1) + ns + aMap.get("name") + ext); + } + } + } + + private void getStruts2URLs(String appurl, Map> compServices, + Map strutsAction) { + + for (Map.Entry entry : strutsAction.entrySet()) { + + String key = entry.getKey(); + + if ("com.opensymphony.xwork2.ActionSupport".equals(key)) { + continue; + } + + Set extSet = getStruts2URLExtension(strutsAction); + getStruts2URLsByAnno(appurl, compServices, strutsAction, key, extSet); + getStruts2URLsByDes(appurl, compServices, strutsAction, key, extSet); + + } + + // ignore com.opensymphony.xwork2.ActionSupport + strutsAction.remove("com.opensymphony.xwork2.ActionSupport"); + } + + @SuppressWarnings("unchecked") + private Set getStruts2URLExtension(Map strutsAction) { + + Set extSet = new HashSet(); + + for (Map.Entry entry : strutsAction.entrySet()) { + + String key = entry.getKey(); + Object value = entry.getValue(); + + if ("com.opensymphony.xwork2.ActionSupport".equals(key)) { + continue; + } + + Map valueMap = (Map) value; + + List desList = (List) valueMap.get("des"); + + if (desList == null) { + continue; + } + + for (Object desObj : desList) { + Map aMap = (Map) desObj; + Object extObj = aMap.get("extension"); + if (extObj == null) { + continue; + } + + String[] extArr = ((String) extObj).split(","); + + List extList = Arrays.asList(extArr); + + extSet.addAll(extList); + + return extSet; + } + } + + if (extSet.size() <= 0) { + extSet.add("action"); + } + + return extSet; } /** diff --git a/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/osproc/DiskIOCollector.java b/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/osproc/DiskIOCollector.java index 63565350..2d78b871 100644 --- a/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/osproc/DiskIOCollector.java +++ b/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/osproc/DiskIOCollector.java @@ -26,6 +26,8 @@ import java.util.regex.Pattern; import com.creditease.agent.helpers.IOHelper; +import com.creditease.agent.helpers.RuntimeHelper; +import com.creditease.agent.helpers.StringHelper; public class DiskIOCollector { @@ -39,6 +41,39 @@ public class DiskIOCollector { private Map> lastDiskIoMap = new HashMap>(); private long time = 0; + public void collectWin(Map> resultMap) { + + try { + String output = RuntimeHelper.exec( + "wmic path Win32_PerfFormattedData_PerfDisk_LogicalDisk get DiskReadBytesPerSec,DiskWriteBytesPerSec,Name"); + + if (StringHelper.isEmpty(output)) { + return; + } + + String[] strs = output.split("\n"); + for (String str : strs) { + str = str.replaceAll("\\s{2,}", " "); + String[] args = str.split(" "); + if (1 == args.length) { + continue; + } + + if (!(args[2].equals("_Total")) && !(args[2].equals("Name"))) { + double rd_persec = Long.parseLong(args[0]) / 1024.0; + double wr_persec = Long.parseLong(args[1]) / 1024.0; + + DecimalFormat df = new DecimalFormat("#0.00"); + resultMap.get(args[2]).put("disk_read", df.format(rd_persec)); + resultMap.get(args[2]).put("disk_write", df.format(wr_persec)); + } + } + } + catch (Exception e) { + // ignore + } + } + public void collect(Map> resultMap) { Map> currentDiskIoMap = new HashMap>(); diff --git a/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/osproc/OSProcess.java b/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/osproc/OSProcess.java index f1a992fe..3d31fa8b 100644 --- a/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/osproc/OSProcess.java +++ b/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/osproc/OSProcess.java @@ -34,7 +34,7 @@ public class OSProcess { private Set ports = new HashSet(); // program name - private String name = "UNKOWN"; + private String name = "UNKNOWN"; // extract info to describe the process private Map tags = new LinkedHashMap(); diff --git a/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/osproc/ProcDiskIOCollector.java b/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/osproc/ProcDiskIOCollector.java index b8e17723..d6802e82 100644 --- a/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/osproc/ProcDiskIOCollector.java +++ b/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/osproc/ProcDiskIOCollector.java @@ -26,6 +26,8 @@ import com.creditease.agent.helpers.IOHelper; import com.creditease.agent.helpers.JVMToolHelper; +import com.creditease.agent.helpers.RuntimeHelper; +import com.creditease.agent.helpers.StringHelper; public class ProcDiskIOCollector { @@ -37,45 +39,86 @@ public class ProcDiskIOCollector { public void collect(Map procs) { - if (JVMToolHelper.isWindows()) { - return; - } Map> currentPidsDiskIoMap = new HashMap>(); - for (String pid : procs.keySet()) { + if (JVMToolHelper.isWindows()) { + // for Windows try { - Map lastIoStat = lastPidsDiskIoMap.get(pid); - Map ioStat = new HashMap(); - String procpath = "/proc/" + pid + "/io"; - if (!IOHelper.exists(procpath)) { - continue; + String output = RuntimeHelper.exec("wmic process list IO"); + if (StringHelper.isEmpty(output)) { + return; } - String[] strs = IOHelper.readTxtFile(procpath, "UTF-8").split("\n"); + String[] strs = output.split("\n"); for (String str : strs) { - - if (str.startsWith("read_bytes")) { - ioStat.put("read_bytes", Long.parseLong(str.split(":")[1].replace(" ", ""))); - } - if (str.startsWith("write_bytes")) { - ioStat.put("write_bytes", Long.parseLong(str.split(":")[1].replace(" ", ""))); + str = str.replaceAll("\\s{2,}", " "); + String[] args = str.split(" "); + if (1 == args.length) { + continue; } + if (procs.containsKey(args[1])) { + Map lastIoStat = lastPidsDiskIoMap.get(args[1]); + Map ioStat = new HashMap(); + + ioStat.put(read_bytes, Long.parseLong(args[3])); + ioStat.put(write_bytes, Long.parseLong(args[5])); + + if (null != lastIoStat && time != 0) { + long timerange = System.currentTimeMillis() - time; + DecimalFormat df = new DecimalFormat("#0.00"); + + double rd_persec = (ioStat.get(read_bytes) - lastIoStat.get(read_bytes)) * 1.0 / timerange; + double wr_persec = (ioStat.get(write_bytes) - lastIoStat.get(write_bytes)) * 1.0 + / timerange; + procs.get(args[1]).addTag("disk_read", df.format(rd_persec)); + procs.get(args[1]).addTag("disk_write", df.format(wr_persec)); + } + currentPidsDiskIoMap.put(args[1], ioStat); + } } - if (null != lastIoStat && time != 0) { - long timerange = System.currentTimeMillis() - time; - DecimalFormat df = new DecimalFormat("#0.00"); - double rd_persec = (ioStat.get(read_bytes) - lastIoStat.get(read_bytes)) * 1.0 / timerange; - double wr_persec = (ioStat.get(write_bytes) - lastIoStat.get(write_bytes)) * 1.0 / timerange; - procs.get(pid).addTag("disk_read", df.format(rd_persec)); - procs.get(pid).addTag("disk_write", df.format(wr_persec)); - } - currentPidsDiskIoMap.put(pid, ioStat); } catch (Exception e) { // ignore } + } + else { + // for linux + for (String pid : procs.keySet()) { + try { + Map lastIoStat = lastPidsDiskIoMap.get(pid); + Map ioStat = new HashMap(); + String procpath = "/proc/" + pid + "/io"; + if (!IOHelper.exists(procpath)) { + continue; + } + + String[] strs = IOHelper.readTxtFile(procpath, "UTF-8").split("\n"); + for (String str : strs) { + + if (str.startsWith("read_bytes")) { + ioStat.put("read_bytes", Long.parseLong(str.split(":")[1].replace(" ", ""))); + } + if (str.startsWith("write_bytes")) { + ioStat.put("write_bytes", Long.parseLong(str.split(":")[1].replace(" ", ""))); + } + + } + if (null != lastIoStat && time != 0) { + long timerange = System.currentTimeMillis() - time; + DecimalFormat df = new DecimalFormat("#0.00"); + double rd_persec = (ioStat.get(read_bytes) - lastIoStat.get(read_bytes)) * 1.0 / timerange; + double wr_persec = (ioStat.get(write_bytes) - lastIoStat.get(write_bytes)) * 1.0 / timerange; + procs.get(pid).addTag("disk_read", df.format(rd_persec)); + procs.get(pid).addTag("disk_write", df.format(wr_persec)); + } + currentPidsDiskIoMap.put(pid, ioStat); + } + catch (Exception e) { + // ignore + } + } } lastPidsDiskIoMap = currentPidsDiskIoMap; time = System.currentTimeMillis(); diff --git a/com.creditease.uav.hook.dubbo/src/main/java/com/creditease/uav/hook/dubbo/DubboHookProxy.java b/com.creditease.uav.hook.dubbo/src/main/java/com/creditease/uav/hook/dubbo/DubboHookProxy.java index be34ee3a..3fcc6230 100644 --- a/com.creditease.uav.hook.dubbo/src/main/java/com/creditease/uav/hook/dubbo/DubboHookProxy.java +++ b/com.creditease.uav.hook.dubbo/src/main/java/com/creditease/uav/hook/dubbo/DubboHookProxy.java @@ -93,7 +93,7 @@ public void process(CtMethod m) throws Exception { if ("onApplicationEvent".equals(m.getName())) { dpInstall.defineLocalVal(m, "mObj", DubboIT.class); - m.insertBefore( + m.insertAfter( "{mObj=new DubboIT(\"" + appid + "\");mObj.doProfiling(new Object[]{this,$1});}"); } diff --git a/com.creditease.uav.hook.dubbo/src/main/java/com/creditease/uav/hook/dubbo/interceptors/DubboIT.java b/com.creditease.uav.hook.dubbo/src/main/java/com/creditease/uav/hook/dubbo/interceptors/DubboIT.java index afa62163..442c3029 100644 --- a/com.creditease.uav.hook.dubbo/src/main/java/com/creditease/uav/hook/dubbo/interceptors/DubboIT.java +++ b/com.creditease.uav.hook.dubbo/src/main/java/com/creditease/uav/hook/dubbo/interceptors/DubboIT.java @@ -26,7 +26,6 @@ import com.alibaba.dubbo.common.Constants; import com.alibaba.dubbo.common.URL; -import com.alibaba.dubbo.config.ProtocolConfig; import com.alibaba.dubbo.config.spring.ServiceBean; import com.alibaba.dubbo.rpc.Invocation; import com.alibaba.dubbo.rpc.Invoker; @@ -365,16 +364,25 @@ else if ("".equals(group) && !"".equals(version)) { dspi.setGroup(group); dspi.setVersion(version); - List plist = sb.getProtocols(); + @SuppressWarnings("unchecked") + List urlList = sb.getExportedUrls(); - if (plist != null) { - for (ProtocolConfig pc : plist) { + if (urlList != null) { + for (URL url : urlList) { DubboServiceProfileInfo.Protocol pro = new DubboServiceProfileInfo.Protocol(); - pro.setpName(pc.getName()); - pro.setPort(pc.getPort()); - pro.setCharset(pc.getCharset()); - pro.setContextpath(pc.getContextpath()); - pro.setSerialization(pc.getSerialization()); + pro.setPort(url.getPort()); + pro.setpName(url.getProtocol()); + int pathLength = url.getPath().length(); + // 长度加1为了去除反斜杠/ + int interfaceLength = url.getServiceInterface().length() + 1; + String contextpath = null; + if (pathLength > interfaceLength + 1) { + contextpath = url.getPath().substring(0, pathLength - interfaceLength); + } + pro.setContextpath(contextpath); + pro.setCharset(url.getParameter("charset")); + // dubbo当前默认的序列化方式为hessian2,不知道日后会不会变,故此处不进行默认赋值 + pro.setSerialization(url.getParameter("serialization")); dspi.addProtocol(pro); } } diff --git a/com.creditease.uav.monitorframework.agent/src/main/java/com/creditease/uav/monitorframework/adaptors/TomcatAdaptor.java b/com.creditease.uav.monitorframework.agent/src/main/java/com/creditease/uav/monitorframework/adaptors/TomcatAdaptor.java index 9d522fae..179afcb6 100644 --- a/com.creditease.uav.monitorframework.agent/src/main/java/com/creditease/uav/monitorframework/adaptors/TomcatAdaptor.java +++ b/com.creditease.uav.monitorframework.agent/src/main/java/com/creditease/uav/monitorframework/adaptors/TomcatAdaptor.java @@ -31,6 +31,7 @@ public class TomcatAdaptor extends AbstractAdaptor { private String currentVersion = ""; + private String currentVersionDetailed = ""; private void detectTomcatVersion() { @@ -70,6 +71,7 @@ private void detectTomcatVersion() { } currentVersion = ver; + currentVersionDetailed = version; } @Override @@ -322,6 +324,7 @@ public String getMethodName() { else if (className.equals("org.apache.catalina.startup.HostConfig")) { final String curVersion = this.currentVersion; + final String currentVersionDetailed = this.currentVersionDetailed; return this.inject(className, new String[] { "com.creditease.tomcat.plus.interceptor" }, new AdaptorProcessor[] { new AdaptorProcessor() { @@ -337,7 +340,8 @@ public void process(CtMethod m) throws Exception { aa.addLocalVar(m, "mObj", "com.creditease.tomcat.plus.interceptor.TomcatPlusIT"); m.insertAfter( "{mObj=new TomcatPlusIT();mObj.onDeployUAVApp(new Object[]{this,this.host,$1,\"" - + uavMofRoot + "\",\"" + curVersion + "\"});}"); + + uavMofRoot + "\",\"" + curVersion + "\",\"" + currentVersionDetailed + + "\"});}"); } } }); diff --git a/com.creditease.uav.monitorframework.buildFat/lib/com.creditease.uav.monitorframework-1.0.jar b/com.creditease.uav.monitorframework.buildFat/lib/com.creditease.uav.monitorframework-1.0.jar new file mode 100644 index 00000000..9a11f0f8 Binary files /dev/null and b/com.creditease.uav.monitorframework.buildFat/lib/com.creditease.uav.monitorframework-1.0.jar differ diff --git a/com.creditease.uav.monitorframework.buildFat/lib/fast-scan.jar b/com.creditease.uav.monitorframework.buildFat/lib/fast-scan.jar new file mode 100644 index 00000000..560f3da8 Binary files /dev/null and b/com.creditease.uav.monitorframework.buildFat/lib/fast-scan.jar differ diff --git a/com.creditease.uav.monitorframework.buildFat/pom.xml b/com.creditease.uav.monitorframework.buildFat/pom.xml index 24eca346..f9fc1898 100644 --- a/com.creditease.uav.monitorframework.buildFat/pom.xml +++ b/com.creditease.uav.monitorframework.buildFat/pom.xml @@ -10,6 +10,11 @@ com.creditease.uav.monitorframework.buildFat 4.0.0 war + + + 2.3.15.1 + + org.apache.cxf @@ -259,6 +264,27 @@ commons-httpclient 3.0.1 + + + org.apache.struts + struts2-core + ${struts2.version} + + + org.apache.struts + struts2-convention-plugin + ${struts2.version} + + + org.apache.struts + struts2-json-plugin + ${struts2.version} + + + org.apache.struts + struts2-config-browser-plugin + ${struts2.version} + diff --git a/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2Action.java b/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2Action.java new file mode 100644 index 00000000..ee7bfb93 --- /dev/null +++ b/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2Action.java @@ -0,0 +1,65 @@ +package com.creditease.monitorframework.fat.struts; + +import java.io.IOException; +import java.io.PrintWriter; + +import org.apache.struts2.ServletActionContext; + +public class TestStruts2Action { + + public void hello() throws IOException { + + ServletActionContext.getResponse().setContentType("text/html;charset=utf-8"); + PrintWriter out = ServletActionContext.getResponse().getWriter(); + try { + out.print("TestStruts2Action hello()"); + out.flush(); + out.close(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void hello2() throws IOException { + + ServletActionContext.getResponse().setContentType("text/html;charset=utf-8"); + PrintWriter out = ServletActionContext.getResponse().getWriter(); + try { + out.print("TestStruts2Action hello2()"); + out.flush(); + out.close(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void hello3() throws IOException { + + ServletActionContext.getResponse().setContentType("text/html;charset=utf-8"); + PrintWriter out = ServletActionContext.getResponse().getWriter(); + try { + out.print("TestStruts2Action hello3()"); + out.flush(); + out.close(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void hello4() throws IOException { + + ServletActionContext.getResponse().setContentType("text/html;charset=utf-8"); + PrintWriter out = ServletActionContext.getResponse().getWriter(); + try { + out.print("TestStruts2Action hello4()"); + out.flush(); + out.close(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } +} diff --git a/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2ActionAnno.java b/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2ActionAnno.java new file mode 100644 index 00000000..4d12d6e7 --- /dev/null +++ b/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2ActionAnno.java @@ -0,0 +1,34 @@ +package com.creditease.monitorframework.fat.struts; + +import java.io.IOException; +import java.io.PrintWriter; + +import org.apache.struts2.ServletActionContext; +import org.apache.struts2.convention.annotation.Action; +import org.apache.struts2.convention.annotation.Actions; +import org.apache.struts2.convention.annotation.Namespace; +import org.apache.struts2.convention.annotation.Namespaces; + +import com.opensymphony.xwork2.ActionSupport; + +@Namespaces({ @Namespace("/a"), @Namespace("/b") }) +@Namespace("/anno") +public class TestStruts2ActionAnno extends ActionSupport { + + @Actions({ @Action("aa"), @Action("bb") }) + @Action("anno1") + public void anno1() throws IOException { + + ServletActionContext.getResponse().setContentType("text/html;charset=utf-8"); + PrintWriter out = ServletActionContext.getResponse().getWriter(); + try { + out.print("TestStruts2ActionAnno anno1()"); + out.flush(); + out.close(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + +} diff --git a/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2ActionAnno2.java b/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2ActionAnno2.java new file mode 100644 index 00000000..a4e11036 --- /dev/null +++ b/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2ActionAnno2.java @@ -0,0 +1,28 @@ +package com.creditease.monitorframework.fat.struts; + +import java.io.IOException; +import java.io.PrintWriter; + +import org.apache.struts2.ServletActionContext; +import org.apache.struts2.convention.annotation.Action; + +import com.opensymphony.xwork2.ActionSupport; + +public class TestStruts2ActionAnno2 extends ActionSupport { + + @Action("anno2") + public void anno2() throws IOException { + + ServletActionContext.getResponse().setContentType("text/html;charset=utf-8"); + PrintWriter out = ServletActionContext.getResponse().getWriter(); + try { + out.print("TestStruts2ActionAnno2 anno2()"); + out.flush(); + out.close(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + +} diff --git a/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2ActionAnno3.java b/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2ActionAnno3.java new file mode 100644 index 00000000..d99ad0fa --- /dev/null +++ b/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2ActionAnno3.java @@ -0,0 +1,28 @@ +package com.creditease.monitorframework.fat.struts; + +import java.io.IOException; +import java.io.PrintWriter; + +import org.apache.struts2.ServletActionContext; +import org.apache.struts2.convention.annotation.Action; + +import com.opensymphony.xwork2.ActionSupport; + +public class TestStruts2ActionAnno3 extends ActionSupport { + + @Action("anno3") + public void anno3() throws IOException { + + ServletActionContext.getResponse().setContentType("text/html;charset=utf-8"); + PrintWriter out = ServletActionContext.getResponse().getWriter(); + try { + out.print("TestStruts2ActionAnno3 anno3()"); + out.flush(); + out.close(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + +} diff --git a/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2ActionAnno4.java b/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2ActionAnno4.java new file mode 100644 index 00000000..3aecf087 --- /dev/null +++ b/com.creditease.uav.monitorframework.buildFat/src/main/java/com/creditease/monitorframework/fat/struts/TestStruts2ActionAnno4.java @@ -0,0 +1,33 @@ +package com.creditease.monitorframework.fat.struts; + +import java.io.IOException; +import java.io.PrintWriter; + +import org.apache.struts2.ServletActionContext; +import org.apache.struts2.convention.annotation.Action; +import org.apache.struts2.convention.annotation.InterceptorRef; +import org.apache.struts2.convention.annotation.Result; + +import com.opensymphony.xwork2.ActionSupport; + +public class TestStruts2ActionAnno4 extends ActionSupport { + + @Action(value = "anno4", interceptorRefs = @InterceptorRef("auth"), results = { + @Result(type = "stream", params = { "inputName", "inputStream", "contentDisposition", + "attachment;filename=\"${downloadFileName}\"", "bufferSize", "512" }) }, params = {}) + // @Action(value = "anno4") + public void anno4() throws IOException { + + ServletActionContext.getResponse().setContentType("text/html;charset=utf-8"); + PrintWriter out = ServletActionContext.getResponse().getWriter(); + try { + out.print("TestStruts2ActionAnno4 anno4()"); + out.flush(); + out.close(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + +} diff --git a/com.creditease.uav.monitorframework/src/main/java/com/creditease/monitor/proxy/spi/JDKProxyInvokeHandler.java b/com.creditease.uav.monitorframework/src/main/java/com/creditease/monitor/proxy/spi/JDKProxyInvokeHandler.java index 0f950575..d9f8002f 100644 --- a/com.creditease.uav.monitorframework/src/main/java/com/creditease/monitor/proxy/spi/JDKProxyInvokeHandler.java +++ b/com.creditease.uav.monitorframework/src/main/java/com/creditease/monitor/proxy/spi/JDKProxyInvokeHandler.java @@ -65,6 +65,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl } try { + method.setAccessible(true); res = method.invoke(this.target, args); } catch (InvocationTargetException e) { diff --git a/com.creditease.uav.monitorframework/src/main/java/com/creditease/uav/profiling/handlers/ComponentProfileHandler.java b/com.creditease.uav.monitorframework/src/main/java/com/creditease/uav/profiling/handlers/ComponentProfileHandler.java index fdef0ac9..f138ec2a 100644 --- a/com.creditease.uav.monitorframework/src/main/java/com/creditease/uav/profiling/handlers/ComponentProfileHandler.java +++ b/com.creditease.uav.monitorframework/src/main/java/com/creditease/uav/profiling/handlers/ComponentProfileHandler.java @@ -27,10 +27,12 @@ import java.lang.reflect.Method; import java.net.UnknownHostException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -52,6 +54,7 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; +import com.creditease.agent.helpers.JSONHelper; import com.creditease.agent.helpers.NetworkHelper; import com.creditease.agent.helpers.ReflectHelper; import com.creditease.agent.helpers.StringHelper; @@ -1045,7 +1048,9 @@ public void loadInfo(String sKey, String sKeyRawValue, Map sInfo } }; } - else if ("/web-app/display-name".equals(xpath)) { + else if ("/web-app/display-name".equals(xpath)) + + { // get display-name as the application name ic = new DescriptorCollector() { @@ -1135,33 +1140,167 @@ protected List getDescriptorFileLocations(String webAppRoot) { } - // ----------------------------------------------annotation based component - // processor------------------------------------------------------------- - /** - * ComponentAnnotationProcessor is the interface to process component class to get the info via annotations * - * @author zhen zhang + * struts2.xml descriptor * */ - private static abstract class ComponentAnnotationProcessor { + public static class Struts2XmlProcessor extends DescriptorProcessor { - public final static String DEFAULT_VALUE = "_default_value"; + public Struts2XmlProcessor(ProfileContext context) { + super(context); + } - @SuppressWarnings("rawtypes") - public abstract Map process(Class annoCls, Class comCls, ProfileContext context); + @Override + public DescriptorCollector selectDescriptorCollector(String xpath) { - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected void putAnnoValue(Class c, Class annoCls, String configName, Class configCls, - String keyName, Map info) { + DescriptorCollector ic = null; - T value = (T) ReflectHelper.getAnnotationValue(c, annoCls, configName); + if ("/struts/package/action".equals(xpath)) { - if (null == value || DEFAULT_VALUE.equals(value)) { - return; + // get actions + ic = new DescriptorCollector() { + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void loadInfo(String sKey, String sKeyRawValue, Map sInfo) { + + Map elementMap = getProfileElement().getValues(); + + List desList = null; + if (elementMap.containsKey(sKey)) { + Map annoValueMap = (Map) elementMap.get(sKey); + desList = (List) annoValueMap.get("des"); + if (desList == null) { + desList = new ArrayList(); + } + desList.add(sInfo); + annoValueMap.put("des", desList); + } + else { + Map aMap = new HashMap(); + desList = new ArrayList(); + desList.add(sInfo); + aMap.put("des", desList); + elementMap.put(sKey, aMap); + } + } + }; } + return ic; + } + + @Override + protected List getDescriptorFileLocations(String webAppRoot) { + + List files = new ArrayList(); + + Document doc = null; + NodeList nodes = null; + + String webAppClasspath = webAppRoot + File.separator + "WEB-INF" + File.separator + "classes" + + File.separator; + String fileName = "struts.xml"; + File file = new File(webAppClasspath + fileName); + + if (!file.exists()) { + return files; + } + + files.add(webAppClasspath + fileName); + + try { + doc = this.getDocumentBuilder().parse(file); + nodes = (NodeList) this.xpath.evaluate("/struts/include/@file", doc, XPathConstants.NODESET); + } + catch (IOException e) { + if (this.logger.isLogEnabled()) { + this.logger.warn("Load DescriptorFile[" + file.getPath() + "] FAILs.", e); + } + } + catch (SAXException e) { + if (this.logger.isLogEnabled()) { + this.logger.warn("Load DescriptorFile[" + file.getPath() + "] FAILs.", e); + } + } + catch (XPathExpressionException e) { + if (this.logger.isLogEnabled()) { + this.logger.warn("Load DescriptorFile[" + file.getPath() + "] FAILs.", e); + } + } + + if (nodes != null) { + for (int i = 0; i < nodes.getLength(); i++) { + Node node = nodes.item(i); + files.add(webAppClasspath + node.getTextContent()); + } + } + + return files; + } + + @Override + public void parseToPEI(final ProfileElementInstance inst, String webAppRoot, String xpath, + XMLNodeType... xmlNodeTypes) { + + final DescriptorProcessor dp = this; + + XMLParseHandler handler = new XMLParseHandler() { + + @Override + public boolean parse(DescriptorCollector dc, Node node) { + + Node extensionNode = dp.selectXMLNode("/struts/constant[@name='struts.action.extension']/@value"); + String extensionStr = "action"; + + if (extensionNode != null) { + extensionStr = extensionNode.getNodeValue(); + } + + Node pNode = node.getParentNode(); + + Node namespaceNode = pNode.getAttributes().getNamedItem("namespace"); + String namespaceStr = ""; + if (null != namespaceNode) { + namespaceStr = namespaceNode.getNodeValue(); + } + + Node nameNode = node.getAttributes().getNamedItem("name"); + Node methodNode = node.getAttributes().getNamedItem("method"); + Node classNode = node.getAttributes().getNamedItem("class"); + if (classNode == null) { + return true; + } + + String methodStr = "execute"; + String nameStr = nameNode.getNodeValue(); + String classStr = classNode.getNodeValue(); + + if (methodNode != null) { + methodStr = methodNode.getNodeValue(); + } + + Map actionMap = new HashMap(); + + actionMap.put("namespace", namespaceStr); + actionMap.put("name", nameStr); + actionMap.put("method", methodStr); + actionMap.put("class", classStr); + actionMap.put("extension", extensionStr); + + dc.setProfileElement(inst).loadInfo(classStr, "", actionMap); + + return true; + } + + }; + + this.parse(webAppRoot, xpath, handler, xmlNodeTypes); } + } + + private static abstract class ComponentProcessor { @SuppressWarnings("rawtypes") protected Class[] loadAnnoClasses(ProfileContext context, String... classNames) { @@ -1190,9 +1329,93 @@ protected Class[] loadAnnoClasses(ProfileContext context, String... classNames) return annoClasses; } + } + + // ----------------------------------------------Interface based component + // processor------------------------------------------------------------- + + private static abstract class ComponentInterfaceProcessor extends ComponentProcessor { + + public abstract Map process(Class comCls, ProfileContext context); } + private static class Struts2ActionInfoProcessor extends ComponentInterfaceProcessor { + + @SuppressWarnings("rawtypes") + @Override + public Map process(Class comCls, ProfileContext context) { + + Map info = new LinkedHashMap(); + + Class[] annoClasses = this.loadAnnoClasses(context, + new String[] { "org.apache.struts2.convention.annotation.Namespace", + "org.apache.struts2.convention.annotation.Namespaces", + "org.apache.struts2.convention.annotation.Action", + "org.apache.struts2.convention.annotation.Actions" }); + + if (null == annoClasses || annoClasses.length == 0) { + return info; + } + + getClassAnnoInfo(comCls, info, annoClasses[0], annoClasses[1]); + + // get method info + getMethodInfo(comCls, info, annoClasses[2], annoClasses[3]); + + // 这里是一处special处理,替换注解中的转义字符 + return encodeAnnoInfo(info); + } + + /** + * 将类似下面的注解信息中的带转义引号(\")替换为单引号 + * + * @Action(value = "downloadModel", results = { @Result(type = "stream", params = {"inputName", "inputStream", + * "contentDisposition", "attachment;filename=\"${downloadFileName}\"","bufferSize", "512" }) }) + * + * @param annoInfo + * @return + */ + @SuppressWarnings("unchecked") + private Map encodeAnnoInfo(Map annoInfo) { + + String annoInfoJSON = JSONHelper.toString(annoInfo); + + annoInfoJSON = annoInfoJSON.replace("\\\"", "'"); + + return JSONHelper.toObject(annoInfoJSON, Map.class); + } + } + + // ----------------------------------------------annotation based component + // processor------------------------------------------------------------- + + /** + * ComponentAnnotationProcessor is the interface to process component class to get the info via annotations + * + * @author zhen zhang + * + */ + private static abstract class ComponentAnnotationProcessor extends ComponentProcessor { + + public final static String DEFAULT_VALUE = "_default_value"; + + @SuppressWarnings("rawtypes") + public abstract Map process(Class annoCls, Class comCls, ProfileContext context); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected void putAnnoValue(Class c, Class annoCls, String configName, Class configCls, + String keyName, Map info) { + + T value = (T) ReflectHelper.getAnnotationValue(c, annoCls, configName); + + if (null == value || DEFAULT_VALUE.equals(value)) { + return; + } + + } + } + /** * @WebSerice * @@ -1654,6 +1877,10 @@ public Map process(Class annoCls, Class c, ProfileContext con }; + private static final String[] componentInterfaceNames = new String[] { + // struts2 + "com.opensymphony.xwork2.Action" }; + /** * we should exclude the methods from Object */ @@ -1662,9 +1889,11 @@ public Map process(Class annoCls, Class c, ProfileContext con private static final Map annoProcessors = new HashMap(); + private static final Map interfaceProcessors = new HashMap(); + private static final Map> xpathProcessors = new LinkedHashMap>(); - private static final Map anno2xpath = new HashMap(); + private static final Map component2xpath = new HashMap(); private static final Map methodBlackListMap = new HashMap(); @@ -1675,11 +1904,13 @@ public Map process(Class annoCls, Class c, ProfileContext con /** * init annotation to descriptor's xpath */ - anno2xpath.put("javax.servlet.annotation.WebServlet", new String[] { "/web-app/servlet/servlet-class" }); - anno2xpath.put("javax.servlet.annotation.WebFilter", new String[] { "/web-app/filter/filter-class" }); - anno2xpath.put("javax.servlet.annotation.WebListener", new String[] { "/web-app/listener/listener-class" }); - anno2xpath.put("javax.jws.WebService", + component2xpath.put("javax.servlet.annotation.WebServlet", new String[] { "/web-app/servlet/servlet-class" }); + component2xpath.put("javax.servlet.annotation.WebFilter", new String[] { "/web-app/filter/filter-class" }); + component2xpath.put("javax.servlet.annotation.WebListener", + new String[] { "/web-app/listener/listener-class" }); + component2xpath.put("javax.jws.WebService", new String[] { "/beans/endpoint/@id", "/beans/server/@id", "/endpoints/endpoint/@implementation" }); + component2xpath.put("com.opensymphony.xwork2.Action", new String[] { "/struts/package/action" }); /** * init the mapping of anno class to their info processor @@ -1693,6 +1924,12 @@ public Map process(Class annoCls, Class c, ProfileContext con annoProcessors.put("org.springframework.stereotype.Controller", new SpringMVCInfoProcessor()); annoProcessors.put("org.springframework.web.bind.annotation.RestController", new SpringMVCInfoProcessor()); annoProcessors.put("org.springframework.context.annotation.ImportResource", new SpringResourceInfoProcessor()); + + /** + * init the mapping of interface class to their info processor + */ + interfaceProcessors.put("com.opensymphony.xwork2.Action", new Struts2ActionInfoProcessor()); + /** * init xpath processors */ @@ -1703,6 +1940,7 @@ public Map process(Class annoCls, Class c, ProfileContext con xpathProcessors.put("/beans/endpoint/@id", SpringXmlProcessor.class); xpathProcessors.put("/beans/server/@id", SpringXmlProcessor.class); xpathProcessors.put("/endpoints/endpoint/@implementation", SunJaxWSXmlProcessor.class); + xpathProcessors.put("/struts/package/action", Struts2XmlProcessor.class); /** * init methodBlackListMap @@ -1777,6 +2015,25 @@ public void doProfiling(ProfileElement elem, ProfileContext context) { } } + /** + * 2.1 load available interface classes + */ + Map> interfaceAvailableClasses = new HashMap>(); + + for (String interfaceClsName : componentInterfaceNames) { + try { + Class c = webappclsLoader.loadClass(interfaceClsName); + interfaceAvailableClasses.put(interfaceClsName, c); + } + catch (ClassNotFoundException e) { + // ignore + if (this.logger.isDebugable()) { + this.logger.warn("Interface Class [" + interfaceClsName + "] is not found in web application [" + + elem.getRepository().getProfile().getId() + "]", e); + } + } + } + /** * 3. see what kind of components we could get via annotations */ @@ -1802,7 +2059,7 @@ public void doProfiling(ProfileElement elem, ProfileContext context) { else { scanPackage[0] = ""; } - + FastClasspathScanner fcs = new FastClasspathScanner(classLoaders, scanPackage); fcs.scan(); // store FastClasspathScanner instance into ProfileContext @@ -1826,6 +2083,27 @@ public void doProfiling(ProfileElement elem, ProfileContext context) { // load componentsByAnno first loadComponentsByAnno(context, webappclsLoader, fcs, annoAvailableClasses, componentClassName, inst); + } + + for (String componentClassName : componentInterfaceNames) { + + // set the instance id = simple name of the annotation class + ProfileElementInstance inst = elem.getInstance(componentClassName); + + // load componentsByInterface + loadComponentsByInterface(context, webappclsLoader, fcs, interfaceAvailableClasses, componentClassName, + inst); + } + + String[] allComponentNames = new String[componentClassNames.length + componentInterfaceNames.length]; + System.arraycopy(componentClassNames, 0, allComponentNames, 0, componentClassNames.length); + System.arraycopy(componentInterfaceNames, 0, allComponentNames, componentClassNames.length, + componentInterfaceNames.length); + + for (String componentClassName : allComponentNames) { + + ProfileElementInstance inst = elem.getInstance(componentClassName); + // try to load componentsByDescriptor loadComponentsByDescriptor(dpInstances, webAppRoot, context, componentClassName, inst); @@ -1839,6 +2117,7 @@ public void doProfiling(ProfileElement elem, ProfileContext context) { if (componentClassName.equalsIgnoreCase("javax.servlet.annotation.WebServlet")) { collectServletInfoForMonitor(inst); + } /** @@ -1916,9 +2195,209 @@ else if (componentClassName.equalsIgnoreCase("org.springframework.stereotype.Con "org.springframework.web.bind.annotation.RequestMapping", "value", "org.springframework.web.bind.annotation.RequestMapping", false); } + // Struts2 + else if (componentClassName.equalsIgnoreCase("com.opensymphony.xwork2.Action")) { + addStruts2URLMapBinding(smgr, inst, appid, className, classInfo); + } + } + } + + @SuppressWarnings("unchecked") + private Set getStruts2URLExtension(Map strutsAction) { + + Set extSet = new HashSet(); + + for (Map.Entry entry : strutsAction.entrySet()) { + + String key = entry.getKey(); + Object value = entry.getValue(); + + if ("com.opensymphony.xwork2.ActionSupport".equals(key)) { + continue; + } + + Map valueMap = (Map) value; + + List desList = (List) valueMap.get("des"); + + if (desList == null) { + continue; + } + + for (Object desObj : desList) { + Map aMap = (Map) desObj; + Object extObj = aMap.get("extension"); + if (extObj == null) { + continue; + } + + String[] extArr = ((String) extObj).split(","); + + List extList = Arrays.asList(extArr); + + extSet.addAll(extList); + + return extSet; + } + } + + if (extSet.size() <= 0) { + extSet.add("action"); + } + + return extSet; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private void addStruts2URLMapBindingByAnno(ProfileServiceMapMgr smgr, String appid, String className, + Map classInfo, Set extension) { + + Map methodsMap = (Map) classInfo.get("methods"); + Map classAnnoMap = (Map) classInfo.get("anno"); + + // get namespaces + Set namespaces = new HashSet(); + + if (classAnnoMap != null && classAnnoMap.size() > 0) { + for (Map.Entry classAnno : classAnnoMap.entrySet()) { + + String annoKey = classAnno.getKey(); + Object annoValue = classAnno.getValue(); + + if ("org.apache.struts2.convention.annotation.Namespaces".equals(annoKey)) { + + List aList = (List) ((Map) annoValue).get("value"); + + for (Object obj : aList) { + namespaces.add((String) ((Map) obj).get("value")); + } + + } + + if ("org.apache.struts2.convention.annotation.Namespace".equals(annoKey)) { + namespaces.add((String) ((Map) annoValue).get("value")); + } + + } + } + else { + namespaces.add("/"); + } + + // add moitor urls + HashSet murls = (HashSet) UAVServer.instance().getServerInfo("monitor.urls"); + murls.addAll(namespaces); + + // get actions + Set actionNames = new HashSet(); + + if (methodsMap != null) { + for (Map.Entry methodEntry : methodsMap.entrySet()) { + + Map map = (Map) methodEntry.getValue(); + if (map.get("anno") == null) { + continue; + } + + Map methodAnnoMap = (Map) map.get("anno"); + for (Map.Entry methodAnno : methodAnnoMap.entrySet()) { + + String annoKey = methodAnno.getKey(); + Object annoValue = methodAnno.getValue(); + + // if have Actions annotation ignore Action annotation + if ("org.apache.struts2.convention.annotation.Actions".equals(annoKey)) { + + List aList = (List) ((Map) annoValue).get("value"); + + for (Object obj : aList) { + actionNames.add((String) ((Map) obj).get("value")); + } + + } + + if ("org.apache.struts2.convention.annotation.Action".equals(annoKey) + && !methodAnnoMap.containsKey("org.apache.struts2.convention.annotation.Actions")) { + actionNames.add((String) ((Map) annoValue).get("value")); + } + } + + Set urlPSet = new HashSet(); + Iterator nsIterator = namespaces.iterator(); + while (nsIterator.hasNext()) { + String ns = nsIterator.next(); + + if (!"/".equals(ns)) { + ns = ns + "/"; + } + + Iterator actionNamesIterator = actionNames.iterator(); + while (actionNamesIterator.hasNext()) { + String actionName = actionNamesIterator.next(); + + Iterator extIterator = extension.iterator(); + while (extIterator.hasNext()) { + String ext = extIterator.next(); + if (!"".equals(ext)) { + ext = "." + ext; + } + urlPSet.add(ns + actionName + ext); + } + } + } + + smgr.addServiceMapBinding(appid, className, methodEntry.getKey(), urlPSet, 0, false); + } + } + } + + @SuppressWarnings("unchecked") + private void addStruts2URLMapBindingByDes(ProfileServiceMapMgr smgr, String appid, String className, + Map classInfo, Set extension) { + + Map valueMap = classInfo; + + List desList = (List) (valueMap.get("des")); + if (desList == null || desList.size() <= 0) { + return; + } + + Iterator extIterator = extension.iterator(); + while (extIterator.hasNext()) { + String ext = extIterator.next(); + if (!"".equals(ext)) { + ext = "." + ext; + } + + for (Object desObj : desList) { + Map aMap = (Map) desObj; + + String ns = (String) aMap.get("namespace"); + + if (!"/".equals(ns)) { + ns = ns + "/"; + } + + Set urlPSet = new HashSet(); + urlPSet.add(ns + aMap.get("name") + ext); + smgr.addServiceMapBinding(appid, className, (String) aMap.get("method"), urlPSet, 0, false); + } } } + private void addStruts2URLMapBinding(ProfileServiceMapMgr smgr, ProfileElementInstance inst, String appid, + String className, Map classInfo) { + + if (className.equalsIgnoreCase("com.opensymphony.xwork2.ActionSupport")) { + return; + } + + Map strutsAction = inst.getValues(); + Set extSet = getStruts2URLExtension(strutsAction); + addStruts2URLMapBindingByAnno(smgr, appid, className, classInfo, extSet); + addStruts2URLMapBindingByDes(smgr, appid, className, classInfo, extSet); + } + /** * * @param smgr @@ -2399,7 +2878,7 @@ private String getServiceURI(String contextpath) { protected void loadComponentsByDescriptor(Map dpInstances, String webAppRoot, ProfileContext context, String componentClassName, ProfileElementInstance inst) { - String[] xpaths = anno2xpath.get(componentClassName); + String[] xpaths = component2xpath.get(componentClassName); if (null == xpaths) { return; @@ -2442,6 +2921,10 @@ protected void loadComponentsByDescriptor(Map dpIns if (SunJaxWSXmlProcessor.class.isAssignableFrom(dpClass)) { context.put(SunJaxWSXmlProcessor.class, (SunJaxWSXmlProcessor) dpInst); } + // put struts.xml processor into profile context + if (Struts2XmlProcessor.class.isAssignableFrom(dpClass)) { + context.put(Struts2XmlProcessor.class, (Struts2XmlProcessor) dpInst); + } } else { dpInst = dpInstances.get(dpClass.getName()); @@ -2502,20 +2985,15 @@ protected void loadComponentsByAnno(ProfileContext context, ClassLoader webappcl continue; } catch (NoClassDefFoundError e) { - // ignore - if (this.logger.isDebugable()) { - this.logger.warn("Component Class [" + com + "] is not found in web application [" - + inst.getProfileElement().getRepository().getProfile().getId() + "]", e); } - continue; - } + try { // get the info of the target component class Map info = cip.process(annoClass, comCls, context); @@ -2533,4 +3011,61 @@ protected void loadComponentsByAnno(ProfileContext context, ClassLoader webappcl } + protected void loadComponentsByInterface(ProfileContext context, ClassLoader webappclsLoader, + FastClasspathScanner fcs, Map> interfaceAvailableClasses, String componentClassName, + ProfileElementInstance inst) { + + if (!interfaceAvailableClasses.containsKey(componentClassName)) { + return; + } + + Class interfaceClass = interfaceAvailableClasses.get(componentClassName); + + // get all classes with the target annotations + List coms = fcs.getNamesOfClassesImplementing(interfaceClass); + + if (null == coms || coms.isEmpty()) { + + return; + } + + // get the ComponentInfoProcessor + ComponentInterfaceProcessor cip = interfaceProcessors.get(interfaceClass.getName()); + + // set the instance values, key=class found,value=info of the class + for (String com : coms) { + + Class comCls = null; + try { + comCls = webappclsLoader.loadClass(com); + } + catch (ClassNotFoundException e) { + // ignore + if (this.logger.isDebugable()) { + this.logger.warn("Component Class [" + com + "] is not found in web application [" + + inst.getProfileElement().getRepository().getProfile().getId() + "]", e); + } + continue; + } + catch (NoClassDefFoundError e) { + // ignore + if (this.logger.isDebugable()) { + this.logger.warn("Component Class [" + com + "] is not found in web application [" + + inst.getProfileElement().getRepository().getProfile().getId() + "]", e); + + } + continue; + } + + try { + // get the info of the target component class + Map info = cip.process(comCls, context); + inst.setValue(com, info); + } + catch (RuntimeException e) { + // ignore + } + } + } + } diff --git a/com.creditease.uav.tomcat.plus.core/src/main/java/com/creditease/tomcat/plus/interceptor/SpringBootTomcatPlusIT.java b/com.creditease.uav.tomcat.plus.core/src/main/java/com/creditease/tomcat/plus/interceptor/SpringBootTomcatPlusIT.java index a550f4a4..7a3bb44a 100644 --- a/com.creditease.uav.tomcat.plus.core/src/main/java/com/creditease/tomcat/plus/interceptor/SpringBootTomcatPlusIT.java +++ b/com.creditease.uav.tomcat.plus.core/src/main/java/com/creditease/tomcat/plus/interceptor/SpringBootTomcatPlusIT.java @@ -301,10 +301,15 @@ public void onAppStop(Object... args) { InterceptSupport iSupport = InterceptSupport.instance(); InterceptContext context = iSupport.createInterceptContext(Event.WEBCONTAINER_STOPPED); - /** + /** * NOTE: spring boot rewrite the tomcat webappclassloader, makes the addURL for nothing, then we can't do * anything on this we may use its webappclassloader's parent as the classloader */ + + if (null == context || null == sc) { + return; + } + context.put(InterceptConstants.WEBAPPLOADER, sc.getLoader().getClassLoader().getParent()); context.put(InterceptConstants.WEBWORKDIR, sc.getWorkPath()); diff --git a/com.creditease.uav.tomcat.plus.core/src/main/java/com/creditease/tomcat/plus/interceptor/TomcatPlusIT.java b/com.creditease.uav.tomcat.plus.core/src/main/java/com/creditease/tomcat/plus/interceptor/TomcatPlusIT.java index 76831dab..09d63857 100644 --- a/com.creditease.uav.tomcat.plus.core/src/main/java/com/creditease/tomcat/plus/interceptor/TomcatPlusIT.java +++ b/com.creditease.uav.tomcat.plus.core/src/main/java/com/creditease/tomcat/plus/interceptor/TomcatPlusIT.java @@ -448,7 +448,7 @@ public void onServletStop(Object... args) { @SuppressWarnings("unused") public void onDeployUAVApp(Object... args) { - if (System.getProperty("com.creditease.uav.iapp.install") != null) { + if (System.getProperty("com.creditease.uav.iapp.install") != null) { return; } @@ -457,46 +457,66 @@ public void onDeployUAVApp(Object... args) { final File appBase = (File) args[2]; final String mofRoot = (String) args[3]; String curVersion = (String) args[4]; + String currentVersionDetailed = (String) args[5]; + String[] versions = currentVersionDetailed.split("\\."); - // Tomcat 6 - if (curVersion.equalsIgnoreCase("6")) { + int action = 0; - File dir = new File(mofRoot + "/com.creditease.uav"); - - ReflectHelper.invoke("org.apache.catalina.startup.HostConfig", hc, "deployDirectory", - new Class[] { String.class, File.class, String.class }, - new Object[] { "com.creditease.uav", dir, mofRoot + "/com.creditease.uav" }, - hc.getClass().getClassLoader()); + if (curVersion.equals("6")) { + /** + * tomcat6 + */ + action = 0; + } + else if (curVersion.equals("7") && versions[1].equals("0") + && (Integer.parseInt(versions[2].substring(0, 1)) < 3)) { + /** + * tomcat7.并且小版本0.30.0 (不包含)以下。小版本号使用substring是因为存在beta版本,取第一位即可。 + */ + action = 0; } - // after Tomcat 7 else { - ExecutorService es = host.getStartStopExecutor(); + action = 1; + } - Future f = es.submit(new Runnable() { + switch (action) { + case 0: + File dir = new File(mofRoot + "/com.creditease.uav"); - @Override - public void run() { + ReflectHelper.invoke("org.apache.catalina.startup.HostConfig", hc, "deployDirectory", + new Class[] { String.class, File.class, String.class }, + new Object[] { "com.creditease.uav", dir, mofRoot + "/com.creditease.uav" }, + hc.getClass().getClassLoader()); + break; + case 1: + ExecutorService es = host.getStartStopExecutor(); - ContextName cn = new ContextName("com.creditease.uav", ""); + Future f = es.submit(new Runnable() { - ReflectHelper.setField(ContextName.class, cn, "baseName", mofRoot + "/com.creditease.uav"); + @Override + public void run() { - File dir = new File(mofRoot + "/com.creditease.uav"); + ContextName cn = new ContextName("com.creditease.uav", ""); - ReflectHelper.invoke("org.apache.catalina.startup.HostConfig", hc, "deployDirectory", - new Class[] { ContextName.class, File.class }, new Object[] { cn, dir }, - hc.getClass().getClassLoader()); + ReflectHelper.setField(ContextName.class, cn, "baseName", mofRoot + "/com.creditease.uav"); - } + File dir = new File(mofRoot + "/com.creditease.uav"); - }); + ReflectHelper.invoke("org.apache.catalina.startup.HostConfig", hc, "deployDirectory", + new Class[] { ContextName.class, File.class }, new Object[] { cn, dir }, + hc.getClass().getClassLoader()); - try { - f.get(); - } - catch (Exception e) { - // ignore - } + } + + }); + + try { + f.get(); + } + catch (Exception e) { + // ignore + } + break; } System.setProperty("com.creditease.uav.iapp.install", "true");