From 9638f15f0ad33ba1ddc16523538477d9f45e7c9e Mon Sep 17 00:00:00 2001 From: chongli8 Date: Thu, 12 Apr 2018 10:44:28 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E4=BC=98=E5=8C=96es=E7=B4=A2=E5=BC=95?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../uav/elasticsearch/client/ESClient.java | 81 ++++++++++++------- .../newlog/HMNewLogIndexMgr.java | 19 +++-- .../uav/invokechain/InvokeChainIndexMgr.java | 33 ++++---- .../uav/invokechain/SlowOperIndexMgr.java | 19 +++-- .../server/ThreadAnalysisIndexMgr.java | 33 ++++---- 5 files changed, 108 insertions(+), 77 deletions(-) diff --git a/com.creditease.uav.elasticsearch.client/src/main/java/com/creditease/uav/elasticsearch/client/ESClient.java b/com.creditease.uav.elasticsearch.client/src/main/java/com/creditease/uav/elasticsearch/client/ESClient.java index 40655776..fbc562a5 100644 --- a/com.creditease.uav.elasticsearch.client/src/main/java/com/creditease/uav/elasticsearch/client/ESClient.java +++ b/com.creditease.uav.elasticsearch.client/src/main/java/com/creditease/uav/elasticsearch/client/ESClient.java @@ -27,7 +27,7 @@ import java.util.Map; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse; -import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest; import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse; @@ -111,11 +111,24 @@ public boolean existIndex(String index) { * * @param index * @return + * @throws IOException */ - public boolean creatIndex(String index) { + public boolean creatIndex(String index) throws IOException { + + return creatIndex(index, null, null, null); + } + + public boolean creatIndex(String index, String type, Map set, + Map> mapping) throws IOException { - CreateIndexRequest cir = new CreateIndexRequest(index); - CreateIndexResponse resp = client.admin().indices().create(cir).actionGet(); + CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(index); + if (type != null && mapping != null) { + createIndexRequestBuilder.addMapping(type, createMapping(type, mapping)); + } + if (set != null) { + createIndexRequestBuilder.setSettings(createSetting(set)); + } + CreateIndexResponse resp = createIndexRequestBuilder.execute().actionGet(); if (resp.isAcknowledged()) { return true; @@ -124,6 +137,42 @@ public boolean creatIndex(String index) { return false; } + private Settings createSetting(Map set) { + + Settings settings = Settings.builder().put(set).build(); + + return settings; + } + + private XContentBuilder createMapping(String type, Map> properties) throws IOException { + + XContentBuilder mapping; + + mapping = jsonBuilder().startObject().startObject(type); + + mapping = mapping.startObject("properties"); + + for (String key : properties.keySet()) { + mapping = mapping.startObject(key); + + Map fv = properties.get(key); + + for (String field : fv.keySet()) { + mapping = mapping.field(field, fv.get(field)); + } + + mapping = mapping.endObject(); + } + + mapping = mapping.endObject(); + + mapping = mapping.endObject(); + + mapping = mapping.endObject(); + + return mapping; + } + /** * existType * @@ -173,29 +222,7 @@ public boolean updateIndexSetting(String index, Map set) { public boolean setIndexTypeMapping(String index, String type, Map> properties) throws IOException { - XContentBuilder mapping; - - mapping = jsonBuilder().startObject(); - - mapping = mapping.startObject("properties"); - - for (String key : properties.keySet()) { - mapping = mapping.startObject(key); - - Map fv = properties.get(key); - - for (String field : fv.keySet()) { - mapping = mapping.field(field, fv.get(field)); - } - - mapping = mapping.endObject(); - } - - mapping = mapping.endObject(); - - mapping = mapping.endObject(); - - PutMappingRequest pmp = Requests.putMappingRequest(index).type(type).source(mapping); + PutMappingRequest pmp = Requests.putMappingRequest(index).type(type).source(createMapping(type, properties)); PutMappingResponse resp = client.admin().indices().putMapping(pmp).actionGet(); return resp.isAcknowledged(); diff --git a/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/healthmanager/newlog/HMNewLogIndexMgr.java b/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/healthmanager/newlog/HMNewLogIndexMgr.java index 6d88149d..bbf3e151 100644 --- a/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/healthmanager/newlog/HMNewLogIndexMgr.java +++ b/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/healthmanager/newlog/HMNewLogIndexMgr.java @@ -52,6 +52,7 @@ public class HMNewLogIndexMgr extends AbstractComponent { private ESClient client; public HMNewLogIndexMgr(String cName, String feature) { + super(cName, feature); client = (ESClient) this.getConfigManager().getComponent(this.feature, "ESClient"); @@ -141,11 +142,16 @@ public String prepareIndex(String appid) { return currentIndex; } - client.creatIndex(currentIndex); - Map set = new HashMap(); - set.put("index.number_of_shards", 2); - set.put("index.number_of_replicas", 0); - client.updateIndexSetting(currentIndex, set); + Map set = new HashMap(); + set.put("index.number_of_shards", "2"); + set.put("index.number_of_replicas", "0"); + + try { + client.creatIndex(currentIndex, null, set, null); + } + catch (Exception e) { + log.err(this, "create ES Index FAIL: ", e); + } String sappid = formatAppid(appid); @@ -188,8 +194,7 @@ public void prepareIndexType(String appid, String type) { // 设置 Map sfields = new HashMap<>(); - sfields.put("type", "string"); - sfields.put("index", "not_analyzed"); + sfields.put("type", "keyword"); mapping.put("ipport", sfields); diff --git a/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/InvokeChainIndexMgr.java b/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/InvokeChainIndexMgr.java index 059a4838..9efa18b3 100644 --- a/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/InvokeChainIndexMgr.java +++ b/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/InvokeChainIndexMgr.java @@ -20,7 +20,6 @@ package com.creditease.uav.invokechain; -import java.io.IOException; import java.util.Calendar; import java.util.Date; import java.util.HashMap; @@ -53,6 +52,7 @@ public class InvokeChainIndexMgr extends AbstractComponent { private ESClient client; public InvokeChainIndexMgr(String cName, String feature) { + super(cName, feature); client = (ESClient) this.getConfigManager().getComponent(this.feature, "ESClient"); @@ -125,18 +125,9 @@ public String prepareIndex() { return currentIndex; } - client.creatIndex(currentIndex); - - Map set = new HashMap(); - set.put("index.number_of_shards", 5); - set.put("index.number_of_replicas", 0); - client.updateIndexSetting(currentIndex, set); - /** - * 变更别名到当前新的Index - */ - String previousIndex = this.getCurrentIndex(Calendar.getInstance(), -1); - client.addIndexAlias(currentIndex, IVC_DB); - client.removeIndexAlias(previousIndex, IVC_DB); + Map set = new HashMap(); + set.put("index.number_of_shards", "5"); + set.put("index.number_of_replicas", "0"); /** * 设置不需要分词的索引字段spanid,parentid,traceid,epinfo(方法级排序使用), appuuid(精确查找应用实例) @@ -145,8 +136,7 @@ public String prepareIndex() { Map fields = new HashMap<>(); - fields.put("type", "string"); - fields.put("index", "not_analyzed"); + fields.put("type", "keyword"); mapping.put("traceid", fields); mapping.put("spanid", fields); @@ -169,11 +159,18 @@ public String prepareIndex() { longType.put("type", "long"); try { - client.setIndexTypeMapping(currentIndex, IVC_Table, mapping); + client.creatIndex(currentIndex, IVC_Table, set, mapping); } - catch (IOException e) { - log.err(this, "Set ES Index Type Mapping FAIL: ", e); + catch (Exception e) { + log.err(this, "create ES Index FAIL: ", e); } + + /** + * 变更别名到当前新的Index + */ + String previousIndex = this.getCurrentIndex(Calendar.getInstance(), -1); + client.addIndexAlias(currentIndex, IVC_DB); + client.removeIndexAlias(previousIndex, IVC_DB); } return currentIndex; diff --git a/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/SlowOperIndexMgr.java b/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/SlowOperIndexMgr.java index 90c87b32..9833428f 100644 --- a/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/SlowOperIndexMgr.java +++ b/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/SlowOperIndexMgr.java @@ -56,6 +56,7 @@ public class SlowOperIndexMgr extends AbstractComponent { } public SlowOperIndexMgr(String cName, String feature) { + super(cName, feature); client = (ESClient) this.getConfigManager().getComponent(this.feature, "ESClient"); @@ -145,11 +146,16 @@ public String prepareIndex(String appid) { return currentIndex; } - client.creatIndex(currentIndex); - Map set = new HashMap(); - set.put("index.number_of_shards", 5); - set.put("index.number_of_replicas", 0); - client.updateIndexSetting(currentIndex, set); + Map set = new HashMap(); + set.put("index.number_of_shards", "5"); + set.put("index.number_of_replicas", "0"); + + try { + client.creatIndex(currentIndex, null, set, null); + } + catch (Exception e) { + log.err(this, "create ES Index FAIL: ", e); + } String sappid = formatAppid(appid); @@ -192,8 +198,7 @@ public void prepareIndexType(String currentIndex, String type) { // 设置 Map sfields = new HashMap<>(); - sfields.put("type", "string"); - sfields.put("index", "not_analyzed"); + sfields.put("type", "keyword"); mapping.put("traceid", sfields); mapping.put("spanid", sfields); diff --git a/com.creditease.uav.threadanalysis/src/main/java/com/creditease/uav/threadanalysis/server/ThreadAnalysisIndexMgr.java b/com.creditease.uav.threadanalysis/src/main/java/com/creditease/uav/threadanalysis/server/ThreadAnalysisIndexMgr.java index 9923aa3b..43b37552 100644 --- a/com.creditease.uav.threadanalysis/src/main/java/com/creditease/uav/threadanalysis/server/ThreadAnalysisIndexMgr.java +++ b/com.creditease.uav.threadanalysis/src/main/java/com/creditease/uav/threadanalysis/server/ThreadAnalysisIndexMgr.java @@ -20,7 +20,6 @@ package com.creditease.uav.threadanalysis.server; -import java.io.IOException; import java.util.Calendar; import java.util.Date; import java.util.HashMap; @@ -44,6 +43,7 @@ public class ThreadAnalysisIndexMgr extends AbstractComponent { private ESClient client; public ThreadAnalysisIndexMgr(String cName, String feature) { + super(cName, feature); client = (ESClient) this.getConfigManager().getComponent(this.feature, "ESClient"); @@ -116,18 +116,9 @@ public String prepareIndex() { return currentIndex; } - client.creatIndex(currentIndex); - - Map set = new HashMap(); - set.put("index.number_of_shards", 5); - set.put("index.number_of_replicas", 0); - client.updateIndexSetting(currentIndex, set); - /** - * 变更别名到当前新的Index - */ - String previousIndex = this.getCurrentIndex(Calendar.getInstance(), -1); - client.addIndexAlias(currentIndex, JTA_DB); - client.removeIndexAlias(previousIndex, JTA_DB); + Map set = new HashMap(); + set.put("index.number_of_shards", "5"); + set.put("index.number_of_replicas", "0"); /** * 就只有pname、info做分词,其他属性不做分词 @@ -135,8 +126,7 @@ public String prepareIndex() { Map> mapping = new HashMap>(); Map stringFields = new HashMap(); - stringFields.put("type", "string"); - stringFields.put("index", "not_analyzed"); + stringFields.put("type", "keyword"); mapping.put("ipport", stringFields); mapping.put("pid", stringFields); @@ -181,11 +171,18 @@ public String prepareIndex() { mapping.put("time", timestamp); try { - client.setIndexTypeMapping(currentIndex, JTA_TABLE, mapping); + client.creatIndex(currentIndex, JTA_TABLE, set, mapping); } - catch (IOException e) { - log.err(this, "Set ES Index Type Mapping FAIL: ", e); + catch (Exception e) { + log.err(this, "create ES Index FAIL: ", e); } + + /** + * 变更别名到当前新的Index + */ + String previousIndex = this.getCurrentIndex(Calendar.getInstance(), -1); + client.addIndexAlias(currentIndex, JTA_DB); + client.removeIndexAlias(previousIndex, JTA_DB); } return currentIndex; From 30f51c80d1f18947d921e17e0000f8193fba1ad1 Mon Sep 17 00:00:00 2001 From: zwq0317 <1065009602@qq.com> Date: Fri, 13 Apr 2018 13:27:48 +0800 Subject: [PATCH 2/6] 1.change '\' to '/',avoid '\' from origin string be replaced, 2.add try catch code. --- .../messaging/AbstractMessageHandler.java | 12 ++++++++++-- .../creditease/agent/helpers/DataStoreHelper.java | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/healthmanager/messaging/AbstractMessageHandler.java b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/healthmanager/messaging/AbstractMessageHandler.java index 19fac22d..9fe54b54 100644 --- a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/healthmanager/messaging/AbstractMessageHandler.java +++ b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/healthmanager/messaging/AbstractMessageHandler.java @@ -79,8 +79,16 @@ public void handle(Message msg) { // pre insert to process DataStoreMsg preInsert(dsMsg); - // do insert - boolean insertR = store.doInsert(dsMsg); + boolean insertR = false; + + try { + // do insert + insertR = store.doInsert(dsMsg); + + } + catch (Exception e) { + log.err(this, "DataStore[" + msgKey + "] INSERT DATA FAIL!", e); + } if (log.isDebugEnable()) { diff --git a/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/DataStoreHelper.java b/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/DataStoreHelper.java index 6ce67663..40f4a65e 100644 --- a/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/DataStoreHelper.java +++ b/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/DataStoreHelper.java @@ -57,13 +57,13 @@ public static String encodeForMongoDB(String s) { for (int i = 0; i < chars.length; i++) { char c = chars[i]; if (chars[i] == '.' || chars[i] == '$') { - sb.append("\\u" + Integer.toHexString(c)); + sb.append("/u" + Integer.toHexString(c)); } else { sb.append(chars[i]); } } - return sb.toString().replace("\\", "/"); + return sb.toString(); } public static String encodeForOpenTSDB(String s) { From c32a5ca4a52724d780b32ca8aab5854496159969 Mon Sep 17 00:00:00 2001 From: xingshengli Date: Fri, 13 Apr 2018 15:55:24 +0800 Subject: [PATCH 3/6] =?UTF-8?q?https://github.com/uavorg/uavstack/issues/2?= =?UTF-8?q?49=20HM=E7=9A=84server=E7=AB=AF=E8=B0=83=E7=94=A8=E9=93=BE?= =?UTF-8?q?=E6=95=B0=E6=8D=AESpan=E6=8A=A5IllegalArgumentException?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=20=E5=AF=B9=E5=88=86=E5=8F=B7=E7=BC=96?= =?UTF-8?q?=E8=A7=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InvokeChainDataCollectHandler.java | 19 ++++++++++++------- .../creditease/uav/invokechain/data/Span.java | 17 +++++++++++++---- .../uav/apm/invokechain/span/Span.java | 19 +++++++++++++++---- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/collect/InvokeChainDataCollectHandler.java b/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/collect/InvokeChainDataCollectHandler.java index 1003fe03..5c85110b 100644 --- a/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/collect/InvokeChainDataCollectHandler.java +++ b/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/collect/InvokeChainDataCollectHandler.java @@ -65,13 +65,18 @@ public void handle(CollectDataFrame frame) { for (Line line : frame.getLines()) { - String content = line.getContent(); - - Span span = new Span(content); - - pushLatestIVCDataToCache(appUUID, span); - - pushSpanToBulkRequest(appUUID, frame.getAppgroup(), span, bulkRequest); + try { + String content = line.getContent(); + + Span span = new Span(content); + + pushLatestIVCDataToCache(appUUID, span); + + pushSpanToBulkRequest(appUUID, frame.getAppgroup(), span, bulkRequest); + } + catch (Exception e) { + this.log.err(this, "unsupported ivc content :" + line.getContent(), e); + } } // cm.submitBatch(); diff --git a/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/data/Span.java b/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/data/Span.java index 392c6146..315ed6b6 100644 --- a/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/data/Span.java +++ b/com.creditease.uav.invokechain/src/main/java/com/creditease/uav/invokechain/data/Span.java @@ -92,7 +92,7 @@ public String toString() { private String methodName = ""; - private String endpointInfo; + private String endpointInfo = ""; private String state = ""; @@ -109,11 +109,11 @@ public Span(String ivcLogSpan) { this.startTime = DataConvertHelper.toLong(info[4], -1); this.cost = DataConvertHelper.toLong(info[5], -1); this.appHostPort = info[6]; - this.appid = info[7]; - this.endpointInfo = info[8]; + this.appid = decodeForIVC(info[7]); + this.endpointInfo = decodeForIVC(info[8]); this.className = info[9]; this.methodName = info[10]; - this.url = info[11]; + this.url = decodeForIVC(info[11]); this.state = EncodeHelper.urlDecode(info[12]); } @@ -289,5 +289,14 @@ public void setAppHostPort(String appHostPort) { this.appHostPort = appHostPort; } + private String decodeForIVC(String s) { + + if (!StringHelper.isEmpty(s) && s.contains("%3b")) { + return s.replace("%3b", ";"); + } + else { + return s; + } + } } diff --git a/com.creditease.uav.monitorframework.apm/src/main/java/com/creditease/uav/apm/invokechain/span/Span.java b/com.creditease.uav.monitorframework.apm/src/main/java/com/creditease/uav/apm/invokechain/span/Span.java index 1e0a6528..c9ec7207 100644 --- a/com.creditease.uav.monitorframework.apm/src/main/java/com/creditease/uav/apm/invokechain/span/Span.java +++ b/com.creditease.uav.monitorframework.apm/src/main/java/com/creditease/uav/apm/invokechain/span/Span.java @@ -74,7 +74,7 @@ public String toString() { private String methodName = ""; - private String endpointInfo; + private String endpointInfo = ""; private String state = ""; @@ -122,7 +122,7 @@ public String getAppid() { public void setAppid(String appid) { - this.appid = appid; + this.appid = encodeForIVC(appid); } public String getEndpointType() { @@ -140,7 +140,7 @@ public void setEndpointInfo(String endpointInfo) { if (StringHelper.isEmpty(endpointInfo)) { return; } - this.endpointInfo = endpointInfo; + this.endpointInfo = encodeForIVC(endpointInfo); } public String getUrl() { @@ -154,7 +154,7 @@ public void setUrl(String url) { return; } - this.url = url; + this.url = encodeForIVC(url); } public long getStartTime() { @@ -279,4 +279,15 @@ public void end() { long endTime = System.currentTimeMillis(); this.cost = endTime - this.startTime; } + + private String encodeForIVC(String s) { + + if (!StringHelper.isEmpty(s) && s.contains(";")) { + return s.replace(";", "%3b"); + } + else { + return s; + } + } + } From 6aa19ef11fe198fe5b6577e263a1e916d2445bb1 Mon Sep 17 00:00:00 2001 From: minglangyang Date: Fri, 13 Apr 2018 16:09:47 +0800 Subject: [PATCH 4/6] https://github.com/uavorg/uavstack/issues/251 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.base/link-relative notify support time_limit(day/time/weekday) 2.support metric's time aggregate value notify 3.support custom aggregate cross instance --- .../notifystgy/css/uav.notifystgy.css | 768 ++-- .../notifystgy/js/notifystgy.win.js | 3130 +++++++++-------- .../feature/runtimenotify/NotifyStrategy.java | 1073 +++--- .../runtimenotify/StrategyJudgement.java | 295 +- .../task/JudgeNotifyTimerTask.java | 500 +-- .../agent/helpers/DateTimeHelper.java | 2007 +++++------ .../rabbitmq/interceptors/RabbitmqIT.java | 730 ++-- 7 files changed, 4483 insertions(+), 4020 deletions(-) diff --git a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/css/uav.notifystgy.css b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/css/uav.notifystgy.css index 0539a3dc..d8110b54 100644 --- a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/css/uav.notifystgy.css +++ b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/css/uav.notifystgy.css @@ -1,375 +1,393 @@ -@CHARSET "UTF-8"; -/*原子布局 BEGINI*/ -html { - height: 100%; -} - -body { - font-size: 14px; - font-family: "微软雅黑"; - margin-top: 0px; - margin-left: 0px; - margin-right: 0px; - margin-bottom: 0px; - text-align: center; - height: 100%; -} - -.ListBG { - background: white; - color: black; - font-size: 14px; -} - -.ObjectBG { - background: white; - color: black; - font-size: 14px; -} - -.ObjectBG input,select,textarea,.selectDiv{ - width: 50%; - height: 34px; - border-radius: 2px; - min-width: 340px; - margin-top:1px; -} - -.selectDiv{ - display: inline-flex; -} - -.ObjectBG textarea{ - resize: none; - height:50px; -} - -.ObjectBG .well{ - width: 50%; - min-width: 340px; - border-radius: 2px; - margin: 0 auto; - padding:0px; - text-align:left; -} - -.well-title{ - float: left; - margin-top:3px; - margin-left:3px; - color: white; -} - -.well-title-div{ - background-color: #009ad6; - text-align: right; - width: 100%; - color: white; -} -.well-add{ - font-size: 18px; - margin-top:3px; - margin-right:7px; -} - -.well-add:hover { - border-radius: 3px; - box-shadow: 0 0 1px 1px white; -} - -.well-list{ - margin-top:2px; - margin-left:3px; - border-bottom: dotted 1px #999; -} -.well-list:hover{ - background: #cae4ff; -} -.well-del{ - font-size: 18px; - float: right; - margin-right:7px; -} -.well-del:hover { - border-radius: 3px; - box-shadow: 0 0 1px 1px #ff0000; -} -.well-edit{ - font-size: 18px; - float: right; - margin-right:20px; -} -.well-edit:hover { - border-radius: 3px; - box-shadow: 0 0 1px 1px #000000; -} -.icon-myout,.icon-myhelp { - float: right; - margin-top: 5px; - margin-right: 15px; - font-size: 2em; -} - -.icon-myout:hover { - border-radius: 3px; - box-shadow: 0 0 4px 4px #ffffff; -} - -.icon-myhelp{ - height: 31.4px; - width: 31.4px; - - } - -.icon-myhelp:hover{ - border-radius: 50px; - box-shadow: 0 0 4px 4px #ffffff; -} - -.titleDiv { - font-size: 16px; - color: #ffffff; - background-color: #009ad6; - height: 43px; - line-height:43px; -} - -.titleDiv-stgy-nodata{ - color: black; - margin-left: -85px; -} - -.conditions select{ - min-width: 200px; - width: 200px; -} - -.conditions input{ - width: 200px; - display: inline -} - - -/*下拉框按钮CSS*/ -.selBut{ - width: 90%; - text-align: left; - padding:0px; -} -.selBut_but{ - width: 10%; -} -.selBut_must{ - width: 90%; - text-align: left; - border:solid 1px red; -} - -.input_must{ - text-align: left; - border:solid 1px red; -} -.input_update{ - text-align: left; - border:solid 1px green; -} - -.input_must:focus{ - border:0px; -} -.defNone{ - display:none; -} - -.displayMsgInput{ - display: inline-block; - text-align: left; - background-color: #cde6c7; - padding-top: 4px; - padding-left: 2px; - border:0px; -} - -.displayMsgTitle{ - border:0px; - font-weight: 900; -} -.listIndex{ - color : black; - border-radius: 3px 3px 3px 3px; - background-color: #dddddd; -} -.listIndex > hr{ - margin:0px; - border-top: 1px solid #ffffff; - -} -.listIndex_server{ - color : #ffffff; - background-color: #0aaaaa; -} -.listIndex_client{ - color : #ffffff; - background-color: #a6c166; -} -.listIndex_log{ - color : #ffffff; - background-color: #c99f32; -} -.listIndex_appmetrics{ - color : #ffffff; - background-color: #970097; -} -/**重写CSS*/ -.table>tbody>tr>td{ - vertical-align:middle; -} - - -.titleMsgDiv{ - margin-top: -34px; - height: 34px; -} - -/**时间控件按钮样式**/ -.control-group { - margin-bottom: 10px; -} - -.control-group input { - background-color: #eeeeee; - border:1px solid #cccccc; - border-radius:4px 0 0 4px; - padding: 4px 6px; - color:#333333 -} -.control-group .add-on { - background-color: #eeeeee; - border:1px solid #cccccc; - border-radius:0 4px 4px 0; - padding: 4.5px 6px; - color:#333333 -} - -/** -*条件定义 -*/ -.btn-default.active:focus{ - color: #333; - background-color: #d4d4d4; - border-color: #8c8c8c; -} - -.btn-default.active, .btn-default:active{ - color: #333; - background-color: #d4d4d4; - border-color: #337ab7; -} - -/** -*触发策略 begin -*/ -.StgyDiv .edit-div-where{ - font-size: 14px; - width: 95%; - border-radius: 2px; - margin: 0 auto; - text-align:left; - padding: 5px; - margin-top: 5px; - margin-bottom: 5px; - border:solid 1px green; -} - -.StgyDiv .edit-div{ - font-size: 14px; - height: 130px; - width: 95%; - min-width: 340px; - border-radius: 2px; - margin: 0 auto; - text-align:left; - padding: 5px; - overflow-y:auto; - color:#000000; -} - -.StgyDiv .edit-div:empty:before{ - content: attr(placeholder); - color:darkgrey; -} - -.StgyDiv .edit-div-option{ - font-size: 14px; - height: 50px; - width: 95%; - min-width: 340px; - border-radius: 2px; - border-color:#000000; - margin: 0 auto; - text-align:left; - padding: 5px; - margin-top: 5px; - overflow-y:auto; - color:#000000; -} - -StgyDiv .edit-div-option:empty:before{ - content: attr(placeholder); - color:darkgrey; -} - -.whereStgyEdit{ - border-radius: 4px; -} -.whereStgyEdit-success{ - background-color: #dddddd; - color:#000000; - display: inline-block; - margin: 1px; -} -.whereStgyEdit-delete{ - text-decoration: line-through; - border: solid 1px red; - color: red; - display: inline-block; - margin: 1px; -} - -.btn-success { - margin: 5px; - color: #000000; - padding: 3px 10px; - background-color: #ffffff; - border-color: #3c763d; -} -.btn-success:hover { - color: #000000; - background-color: #dddddd; -} - -.well-list-display{ - display: -webkit-box; - padding-bottom: 5px; - padding-top: 5px; -} -.action-textarea-delete{ - display: inline-flex; - position: absolute; - margin-top: 17px; - margin-left: 5px; -} - -.action-textarea-delete span{ - border:solid 1px #ffffff; - font-size: 18px; -} -.action-textarea-delete span:hover{ - font-size: 18px; - border:solid 1px red; - border-radius: 2px; -} - -/** -*触发策略 end -*/ +@CHARSET "UTF-8"; +/*原子布局 BEGINI*/ +html { + height: 100%; +} + +body { + font-size: 14px; + font-family: "微软雅黑"; + margin-top: 0px; + margin-left: 0px; + margin-right: 0px; + margin-bottom: 0px; + text-align: center; + height: 100%; +} + +.ListBG { + background: white; + color: black; + font-size: 14px; +} + +.ObjectBG { + background: white; + color: black; + font-size: 14px; +} + +.ObjectBG input,select,textarea,.selectDiv{ + width: 50%; + height: 34px; + border-radius: 2px; + min-width: 340px; + margin-top:1px; +} + +.selectDiv{ + display: inline-flex; +} + +.ObjectBG textarea{ + resize: none; + height:50px; +} + +.ObjectBG .well{ + width: 50%; + min-width: 340px; + border-radius: 2px; + margin: 0 auto; + padding:0px; + text-align:left; +} + +.well-title{ + float: left; + margin-top:3px; + margin-left:3px; + color: white; +} + +.well-title-div{ + background-color: #009ad6; + text-align: right; + width: 100%; + color: white; +} +.well-add{ + font-size: 18px; + margin-top:3px; + margin-right:7px; +} + +.well-add:hover { + border-radius: 3px; + box-shadow: 0 0 1px 1px white; +} + +.well-list{ + margin-top:2px; + margin-left:3px; + border-bottom: dotted 1px #999; +} +.well-list:hover{ + background: #cae4ff; +} +.well-del{ + font-size: 18px; + float: right; + margin-right:7px; +} +.well-del:hover { + border-radius: 3px; + box-shadow: 0 0 1px 1px #ff0000; +} +.well-edit{ + font-size: 18px; + float: right; + margin-right:20px; +} +.well-edit:hover { + border-radius: 3px; + box-shadow: 0 0 1px 1px #000000; +} +.icon-myout,.icon-myhelp { + float: right; + margin-top: 5px; + margin-right: 15px; + font-size: 2em; +} + +.icon-myout:hover { + border-radius: 3px; + box-shadow: 0 0 4px 4px #ffffff; +} + +.icon-myhelp{ + height: 31.4px; + width: 31.4px; + + } + +.icon-myhelp:hover{ + border-radius: 50px; + box-shadow: 0 0 4px 4px #ffffff; +} + +.titleDiv { + font-size: 16px; + color: #ffffff; + background-color: #009ad6; + height: 43px; + line-height:43px; +} + +.titleDiv-stgy-nodata{ + color: black; + margin-left: -85px; +} + +.conditions select{ + min-width: 200px; + width: 200px; +} + +.conditions input{ + width: 200px; + display: inline +} + + +/*下拉框按钮CSS*/ +.selBut{ + width: 90%; + text-align: left; + padding:0px; +} +.selBut_but{ + width: 10%; +} +.selBut_must{ + width: 90%; + text-align: left; + border:solid 1px red; +} + +.input_must{ + text-align: left; + border:solid 1px red; +} +.input_update{ + text-align: left; + border:solid 1px green; +} + +.input_must:focus{ + border:0px; +} +.defNone{ + display:none; +} + +.displayMsgInput{ + display: inline-block; + text-align: left; + background-color: #cde6c7; + padding-top: 4px; + padding-left: 2px; + border:0px; +} + +.displayMsgTitle{ + border:0px; + font-weight: 900; +} +.listIndex{ + color : black; + border-radius: 3px 3px 3px 3px; + background-color: #dddddd; +} +.listIndex > hr{ + margin:0px; + border-top: 1px solid #ffffff; + +} +.listIndex_server{ + color : #ffffff; + background-color: #0aaaaa; +} +.listIndex_client{ + color : #ffffff; + background-color: #a6c166; +} +.listIndex_log{ + color : #ffffff; + background-color: #c99f32; +} +.listIndex_appmetrics{ + color : #ffffff; + background-color: #970097; +} +/**重写CSS*/ +.table>tbody>tr>td{ + vertical-align:middle; +} + + +.titleMsgDiv{ + margin-top: -34px; + height: 34px; +} + +/**时间控件按钮样式**/ +.control-group { + margin-bottom: 10px; +} + +.control-group input { + background-color: #eeeeee; + border:1px solid #cccccc; + border-radius:4px 0 0 4px; + padding: 4px 6px; + color:#333333 +} +.control-group .add-on { + background-color: #eeeeee; + border:1px solid #cccccc; + border-radius:0 4px 4px 0; + padding: 4.5px 6px; + color:#333333 +} + +/** +*条件定义 +*/ +.btn-default.active:focus{ + color: #333; + background-color: #d4d4d4; + border-color: #8c8c8c; +} + +.btn-default.active, .btn-default:active{ + color: #333; + background-color: #d4d4d4; + border-color: #337ab7; +} + +/** +*触发策略 begin +*/ +.StgyDiv .edit-div-where{ + font-size: 14px; + width: 95%; + border-radius: 2px; + margin: 0 auto; + text-align:left; + padding: 5px; + margin-top: 5px; + margin-bottom: 5px; + border:solid 1px green; +} + +.StgyDiv .edit-div{ + font-size: 14px; + height: 130px; + width: 95%; + min-width: 340px; + border-radius: 2px; + margin: 0 auto; + text-align:left; + padding: 5px; + overflow-y:auto; + color:#000000; +} + +.StgyDiv .edit-div:empty:before{ + content: attr(placeholder); + color:darkgrey; +} + +.StgyDiv .edit-div-option{ + font-size: 14px; + height: 50px; + width: 95%; + min-width: 340px; + border-radius: 2px; + border-color:#000000; + margin: 0 auto; + text-align:left; + padding: 5px; + margin-top: 5px; + overflow-y:auto; + color:#000000; +} + +StgyDiv .edit-div-option:empty:before{ + content: attr(placeholder); + color:darkgrey; +} + +.whereStgyEdit{ + border-radius: 4px; +} +.whereStgyEdit-success{ + background-color: #dddddd; + color:#000000; + display: inline-block; + margin: 1px; +} +.whereStgyEdit-delete{ + text-decoration: line-through; + border: solid 1px red; + color: red; + display: inline-block; + margin: 1px; +} + +.btn-success { + margin: 5px; + color: #000000; + padding: 3px 10px; + background-color: #ffffff; + border-color: #3c763d; +} +.btn-success:hover { + color: #000000; + background-color: #dddddd; +} + +.well-list-display{ + display: -webkit-box; + padding-bottom: 5px; + padding-top: 5px; +} +.action-textarea-delete{ + display: inline-flex; + position: absolute; + margin-top: 17px; + margin-left: 5px; +} + +.action-textarea-delete span{ + border:solid 1px #ffffff; + font-size: 18px; +} +.action-textarea-delete span:hover{ + font-size: 18px; + border:solid 1px red; + border-radius: 2px; +} + +/** +*触发策略 end +*/ + +.itemTitle { + text-align:left; + color:#333; + border-left:6px solid #57A69C; + padding-left:5px; + margin-bottom:2px; +} + +.itemTip { + color:gray; + font-size:14px; + text-align:left; +} + +.dateTimeInput { + width:120px; +} \ No newline at end of file diff --git a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/js/notifystgy.win.js b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/js/notifystgy.win.js index b0cd5c92..5671d8b0 100644 --- a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/js/notifystgy.win.js +++ b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/js/notifystgy.win.js @@ -1,1480 +1,1652 @@ -/** - * 窗体初始化 - */ -window.winmgr.build({ - id : "notifyList", - height : "auto", - "overflow-y" : "auto", - order : 999, - theme : "ListBG" -}); -window.winmgr.build({ - id : "objectDiv", - height : "auto", - "overflow-y" : "auto", - order : 999, - theme : "ObjectBG" -}); -window.winmgr.build({ - id : "stgyDiv", - height : "auto", - "overflow-y" : "auto", - order : 999, - theme : "StgyDiv" -}); -window.winmgr.build({ - id : "condDiv", - height : "auto", - "overflow-y" : "auto", - order : 999, - theme : "condDiv" -}); -window.winmgr.show("notifyList"); - -/** - * 操作配置 - */ -var actionConf = { - actionObj:null //操作对象 -} -/** - * 下拉框UI - * */ -var selUiConf = { - keys:[ - - {"key":"server","value":"自定义指标"}, - {"key":"server","value":"服务端"}, - {"key":"client","value":"客户端"}, - {"key":"log","value":"日志"} - ], - "server":[ - ["procState","进程状态指标系"], - ["hostState","应用容器状态指标系"], - ["urlResp","服务状态指标系"], - ["appResp","应用状态指标系"], - ["serverResp","应用服务器状态指标系"], - ["procCrash","进程死亡指标系"] - ], - "client":[ - ["clientResp","调用状态指标系"] - ], - "log":[ - ["log","日志"] - ] - , - "userDef":[ - ["jvm","Java虚拟机状态指标系"] - ] - , - userInput:{ - "notifyNameF":"", - "notifyNameM":"", - "notifyNameI":"" - } - -} - -var supportJTA = ["服务状态指标系","应用状态指标系","应用服务器状态指标系","调用状态指标系"]; -/** - * 初始化头部 - */ -function initHeadDiv() { - var divContent = "" - + "
" - - + "" - - + "" - - + "" - - + "
" - + "" - - + "" - + "
" + "
" + ""; - HtmlHelper.id("notifyList").innerHTML += divContent; -} - -/** - * 显示添加策略 - */ -function showAddDiv() { - - var sb=new StringBuffer(); - sb.append( "
"); - sb.append( ""); - sb.append( ""); - sb.append( ""); - sb.append( "添加策略"); - sb.append( "
"); - sb.append( "
"); - sb.append( "
"); - sb.append( "
"); - - sb.append( '
'); - - - sb.append( '
'); - sb.append(''); - sb.append('
'); - sb.append(''); - sb.append(''); - sb.append(''); - sb.append('
'); - sb.append('
'); - - sb.append('
'); - sb.append('
'); - sb.append(''); - sb.append(''); - sb.append(''); - sb.append('
'); - sb.append( '
'); - sb.append('
'); - - sb.append( '
'); - sb.append( "
"); - - - sb.append( '
'); - sb.append( '
'); - - sb.append( '
'); - sb.append( '
条件定义
'); - sb.append( '
'); - - sb.append( '
'); - sb.append( '
触发策略
'); - sb.append( '
'); - - sb.append( '
'); - sb.append( '
触发动作
'); - sb.append( '
'); - - sb.append( '
'); - sb.append( '
'); - - sb.append( ''); - - HtmlHelper.id("objectDiv").innerHTML = sb.toString(); - window.winmgr.hide("notifyList"); - window.winmgr.show("objectDiv"); - initActionDiv($("#isOwner").val()); - -} - - -/** - * 显示编辑策略 - */ -function showEditNotifyDiv(jsonObjParam) { - - var key,jsonObj,isOwner=false;enableThreadAnalysis=false; - //因为只有一对 key:value 获取key(值为id) - $.each(jsonObjParam,function(index,obj){ - key = index; - jsonObj = obj; - }); - - if(jsonObj.owner == window.parent.loginUser.userId - || window.parent.loginUser.groupId == "uav_admin" - || window.parent.loginUser.groupId == "vipgroup" - ){ - isOwner = true; - } - - var names = key.split("@"); - var cssType = "displayMsgInput",cssRedOnly = "displayMsgInput listIndex"; - var sb=new StringBuffer(); - sb.append( "
"); - sb.append( ""); - sb.append( "编辑策略"); - sb.append( "
"); - sb.append( "
"); - sb.append( "
"); - sb.append( "
"); - /** - * 所有渲染内容 div begin - */ - sb.append( '
'); - - sb.append( '
'); - if(window.parent.loginUser.groupId == "uav_admin" - || window.parent.loginUser.groupId == "vipgroup" - ){ - sb.append( '
'); - }else{ - - sb.append( '
'); - } - - - sb.append( '
'); - - //1 - var existsIns = jsonObj.instances.length>0?true:false; - var showNameF = getSelUiConfKeysValue(names[0],names[1]); - if(showNameF=="自定义指标"){ - cssType = "displayMsgInput listIndex_appmetrics"; - }else if(names[1] == "log"){ - showNameF = "日志"; - cssType = "displayMsgInput listIndex_log"; - }else if(names[0] == "server"){ - cssType = "displayMsgInput listIndex_server"; - }else if(names[0] == "client"){ - cssType = "displayMsgInput listIndex_client"; - } - sb.append( '
'); - selUiConf["userInput"]["notifyNameF"]=names[0];//编辑赋值,准备修改数据 - //2 - if(showNameF=="自定义指标"){ - selUiConf["userInput"]["notifyNameM"]=names[1];//编辑赋值,准备修改数据 - }else if(names[1] == "log"){ - sb.append( '
'); - selUiConf["userInput"]["notifyNameM"]=names[1];//编辑赋值,准备修改数据 - }else if(names[1]){ - sb.append( '
'); - selUiConf["userInput"]["notifyNameM"]=names[1];//编辑赋值,准备修改数据 - if($.inArray(getSelUiConfigValue(names[1]),supportJTA) >= 0){ - enableThreadAnalysis=true; - } - } - //3 - if(names[2] && names[1] == "log"){ - var nNameIShow = "指定日志:"+names[2]; - sb.append( '
'); - selUiConf["userInput"]["notifyNameI"]=names[2];//编辑赋值,准备修改数据 - }else if(names[1] == "log"){ - sb.append( '
'); - }else if(names[2]){ - var nNameIShow = (existsIns?"实例组:":"实例:")+names[2]; - sb.append( '
'); - selUiConf["userInput"]["notifyNameI"]=names[2];//编辑赋值,准备修改数据 - }else{ - sb.append( '
'); - } - - if(names[2] && isOwner){ - sb.append( "
'); - }else if(names[2] && !isOwner){ - sb.append( "
'); - }else if(isOwner){ - sb.append( "
'); - }else{ - sb.append( "
'); - } - - - sb.append( '
'); - if(isOwner){ - sb.append( '
'); - }else{ - sb.append( '
'); - } - - /** - * 初始化条件 begin - */ - sb.append( '
'); - sb.append( '
'); - sb.append( '条件定义'); - sb.append( '
'); - $.each(jsonObj.conditions,function(index,obj){ - if(obj.func && obj.func.indexOf("count>")>-1){ - obj.cparam = obj.func.substr(6); - obj.func = "count"; - } - - if(!obj.id){ - /** - * 兼容老数据 - */ - obj.id=StgyClass.randomId()+"_stgySpan"; - } - var html; - if(isOwner){ - html = '
'+StgyClass.formatShowWhere(obj)+'
'; - }else{ - html = '
'+StgyClass.formatShowWhere(obj)+'
'; - } - sb.append( html); - }); - sb.append( '
'); - sb.append( '
'); - /** - * 初始化条件 end - */ - - /** - * 初始化触发策略 begin - */ - sb.append( '
'); - - if(isOwner){ - sb.append( '
触发策略
'); - }else{ - sb.append( '
触发策略
'); - } - - if(jsonObj.relationsHtmls){ - $.each(jsonObj.relationsHtmls,function(index,html){ - var convergenceVal = ""; - if(jsonObj.hasOwnProperty("convergences")){ - convergenceVal = jsonObj.convergences[index]; - } - - var appendHtml = - '
'+ - '
'+ - '
'+html+'
'+ - '
'+convergenceVal+'
'+ - '
'; - - if(isOwner){ - appendHtml+=''; - }else{ - appendHtml+=''; - } - appendHtml+='
'+ - '
'+ - '
'; - sb.append(appendHtml); - }); - } - sb.append( '
'); - /** - * 初始化触发策略 begin - */ - - sb.append( '
'); - sb.append( '
触发动作
'); - var actionSum = 0; - initActionDiv(isOwner?"true":"false"); - if (jsonObj.action!=undefined) { - $.each(jsonObj.action,function(index,value){ - actionSum++; - var josnSpan ={ - "type":index, - "value":value - } - - var html ; - - if(isOwner){ - if("threadanalysis" == josnSpan.type){ - var html = '
'+josnSpan.type+''+JSON.stringify(josnSpan)+'
'; - }else{ - html = '
'+josnSpan.type+''+JSON.stringify(josnSpan)+'
'; - } - }else{ - html = '
'+josnSpan.type+''+JSON.stringify(josnSpan)+'
'; - } - sb.append( '
'); - sb.append( html); - sb.append( '
'); - - /** - * 计算下拉选项 - */ - $("#actionTypeSel option[value="+josnSpan.type+"]").remove(); - - }); - } - sb.append( '
'); - /** - * 初始化触发动作 end - */ - - if(isOwner){ - //按钮 - sb.append( '
'); - sb.append( '
'); - } - - sb.append( '
'); - /** - * 所有渲染内容 div end - */ - sb.append( ""); - HtmlHelper.id("objectDiv").innerHTML = sb.toString(); - - /** - * 判断出发条件:不是归属者不能添加 - */ - if(!isOwner){ - $("#whereAddButton").attr("class","well-add"); - $("#whereAddButton").click(function(){}); - } - /** - * 判断触发动作按钮 begin(类型都已经存在值,则不能再添加) - * 不是归属者也不能添加 - */ - var selTypeSize = $("#actionTypeSel option").size(); - if(selTypeSize == 0 || !isOwner){ - $("#actionAddButton").attr("class","well-add"); - $("#actionAddButton").click(function(){}); - } - /** - * 判断触发动作按钮 end - */ - window.winmgr.hide("notifyList"); - window.winmgr.show("objectDiv"); - - hideShowConStgy(names[1]); -} - - - -/** - * 触发动作添加窗口 - */ -function initActionDiv(isOwner) { - - var old = document.getElementById("actionDiv"); - if(old){ - var node = old.parentNode; - node.removeChild(old); - } - - var sb=new StringBuffer(); - - sb.append(''); - var div = document.createElement('div'); - div.innerHTML = sb.toString(); - document.body.appendChild(div); -} - -/** - * 显示添加条件窗口 - * @param thisObj - * @param type - */ -function showCon(thisObj,type){ - actionConf.actionObj=thisObj.parentNode; - if(selUiConf["userInput"]["notifyNameM"]=="log"){ - $("#condType").attr("disabled","disabled"); - } - $("#pageType").val(type); - if("EDIT" == type){ - var jsonValue = JSON.parse(thisObj.parentNode.getElementsByTagName("span")[0].textContent); - $("#condType").attr("disabled","disabled"); - var isOwner = $("#isOwner").val(); - if(!jsonValue.type||jsonValue.type=="stream"){ - $("#condType").val("stream"); - $("#contExpr").val(jsonValue.expr); - $("#conRange").val(jsonValue.range); - $("#conFunc").val((null == jsonValue.func?0:jsonValue.func)); - if("count" == jsonValue.func){ - $("#conFuncParam").val(jsonValue.cparam); - $("#conFuncParam").show(); - } - //不是归属用户,则只读 - if(isOwner!="true"){ - $("#whereSaveButton").hide(); - $("#contExpr").attr("readonly","readonly"); - $("#conRange").attr("readonly","readonly"); - $("#conFunc").attr("disabled","disabled"); - $("#conFuncParam").attr("readonly","readonly"); - - //只读CSS - $("#contExpr").attr("class","form-control"); - $("#conRange").attr("class","form-control"); - $("#conFuncParam").attr("class","form-control"); - $("#whereSaveButton").hide(); - } - - }else{ - var type; - if(jsonValue.interval){ - type="link-relative"; - }else{ - type="base-relative"; - } - $("#condType").val(type); - typeChangeShow(type); - - var hour=jsonValue.time_from.split(':')[0]; - var min=jsonValue.time_from.split(':')[1]; - $('#time_start').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); - hour=jsonValue.time_to.split(':')[0]; - min=jsonValue.time_to.split(':')[1]; - $('#time_end').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); - - $("#conMetric").val(jsonValue.metric); - $("#conUpperLimit").val(jsonValue.upperLimit); - $("#conLowerLimit").val(jsonValue.lowerLimit); - $("#conAggr").val(jsonValue.aggr); - if(type=="link-relative"){ - $("#conInterval").val(jsonValue.interval); - showUnit(jsonValue.unit); - }else{ - showUnit(jsonValue.unit); - } - if(isOwner!="true"){ - $("#time_from").attr("readonly","readonly"); - $("#time_to").attr("readonly","readonly"); - $("#conMetric").attr("readonly","readonly"); - $("#conUpperLimit").attr("readonly","readonly"); - $("#conLowerLimit").attr("readonly","readonly"); - $("#conMetric").attr("class","form-control"); - $("#conUpperLimit").attr("class","form-control"); - $("#conLowerLimit").attr("class","form-control"); - $("#conAggr").attr("disabled","disabled"); - if(type=="link-relative"){ - $("#conInterval").attr("readonly","readonly"); - $("#conInterval").attr("class","form-control"); - } - $("#whereSaveButton").hide(); - } - } - - } - -} - -function showUnit(unit){ - $("#unit").val(unit); - $("#opt"+unit).attr("class","btn btn-default active"); -} -/** - * 条件定义页面 - */ -function showCondDiv(thisObj,type) { - - var isOwner = $("#isOwner").val(); - /** - * 显示条件定义(弹出新元素) - */ - actionConf.actionObj=thisObj.parentNode; - - var sb = new StringBuffer(); - sb.append("
"); - sb.append("条件定义"); - sb.append("
"); - sb.append("
"); - sb.append( "
'); - - sb.append( '
'); - /** - * 普通预警条件编辑 - */ - sb.append( '
'); - - sb.append( '
'); - sb.append( '
'); - sb.append( "
'); - sb.append( ')\" style="display:none" onkeyup="this.value=this.value.replace(\/\\D/g,\'\')" onafterpaste="this.value=this.value.replace(\/\\D/g,\'\')">
'); - sb.append( '
'); - - /** - * 同环比预警条件编辑 - */ - sb.append( ''); - sb.append( ''); - - /** - * 保存按钮 - */ - sb.append( '
'); - sb.append( ''); - sb.append( ''); - sb.append( '
'); - - HtmlHelper.id("condDiv").innerHTML = sb.toString(); - initTimeControl(); - showCon(thisObj,type); - window.winmgr.hide("objectDiv"); - window.winmgr.show("condDiv"); - -} - -function funcChangeShow(thisObj,showId){ - if("count" == thisObj.value){ - $("#"+showId).show(); - }else{ - $("#"+showId).hide(); - } -} - -function typeChangeShow(type){ - var divs=["stream","timer","link-relative","base-relative"]; - divs.forEach(div=>{ - $("#"+div).hide(); - }) - if("stream"!=type){ - $("#timer").show(); - } - $("#"+type).show(); - -} -/** - * 初始化时间控件 - */ -function initTimeControl(){ - $('#time_start').datetimepicker({ - pickDate: false, - pickSeconds: false - }); - - - $('#time_end').datetimepicker({ - pickDate: false, - pickSeconds: false - }); - - -} - -function changeTimeUnit(value){ - $("#unit").val(value); -} - - - -function actionChangeShow(type){ - if("ADD" == type){ - if("threadanalysis" == $("#actionTypeSel").val()){ - $("textarea[name='actionValue']").val("10101").hide(); - $(".btn-addPriority").hide(); - }else{ - $("textarea[name='actionValue']").val("").show(); - $(".btn-addPriority").show(); - } - }else{ - $("textarea[name='actionValue']").show(); - $(".btn-addPriority").show(); - } -} - -function selServerChangeShow(type,value,text){ - var selId = type+"_notifyNameF"; - $("#"+selId).html(text); - $("#"+selId).css("padding-left","2px"); - $("#"+type+"_notifyNameF").css("color","black"); - - hideShowConStgy("show"); - - if(text == "自定义指标"){ - $("#"+type+"_appName_div").hide(); - $("#"+type+"_notifyNameM_div").attr("class","btn-group selectDiv defNone"); - selUiConf["userInput"]["notifyNameF"]=value; - selUiConf["userInput"]["notifyNameM"]="jvm"; - $("#notifyNameI").attr("placeholder","输入监控实例名或者实例组名"); - $("#enableThreadAnalysis").val(false); - removeChoosedJTA(); - }else if(value=="log"){ - $("#"+type+"_appName_div").show(); - $("#"+type+"_notifyNameM_div").attr("class","btn-group selectDiv defNone"); - $("#notifyNameI").attr("placeholder","输入指定日志"); - selUiConf["userInput"]["notifyNameF"]=""; - selUiConf["userInput"]["notifyNameM"]=value; - $("#enableThreadAnalysis").val(false); - removeChoosedJTA(); - }else{ - $("#"+type+"_appName_div").hide(); - $("#"+type+"_notifyNameM_div").attr("class","btn-group selectDiv"); - $("#notifyNameI").attr("placeholder","输入监控实例名或者实例组名"); - $("#"+type+"_notifyNameM").css("color","darkgrey"); - $("#"+type+"_notifyNameM").html("选择监控组指标"); - document.getElementById(type+"_notifyNameM_body").innerHTML =""; - $.each(selUiConf[value],function(index,obj){ - var li = document.createElement("li"); - var a = document.createElement("a"); - a.innerHTML=obj[1]; - a.onclick=function(){selIndexChangeShow(type,obj[0],obj[1]);}; - a.href="#"; - li.appendChild(a); - document.getElementById(type+"_notifyNameM_body").appendChild(li); - }); - selUiConf["userInput"]["notifyNameF"]=value; - } - -} - -function removeChoosedJTA(){ - if(HtmlHelper.id("ChoosedJTA") != null){ - HtmlHelper.id("ChoosedJTA").remove(); - } -} - -function changeJTAStat(text){ - if($.inArray(text,supportJTA) >= 0){ - $("#enableThreadAnalysis").val(true); - if(HtmlHelper.id("ChoosedJTA") == null){ - $("#actionAddButton").attr("class","glyphicon glyphicon-plus well-add"); - $("#actionAddButton").click(function(){showAction(this,'ADD')}); - } - }else{ - $("#enableThreadAnalysis").val(false); - removeChoosedJTA(); - } -} - -function hideShowConStgy(value){ - if(value == "procCrash"){ - $("#conFatDiv").hide(); - $("#stgyFatDiv").hide(); - } - else{ - $("#conFatDiv").show(); - $("#stgyFatDiv").show(); - } -} - -function selIndexChangeShow(type,value,text){ - changeJTAStat(text); - hideShowConStgy(value); - - $("#"+type+"_notifyNameM").html(text); - $("#"+type+"_notifyNameM").css("padding-left","2px"); - $("#"+type+"_notifyNameM").css("color","black"); - selUiConf["userInput"]["notifyNameM"]=value; -} - -function appNameChange(obj){ - selUiConf["userInput"]["notifyNameF"]=obj.value; -} -function getSelUiConfigValue(indexValue){ - var result =""; - $.each(selUiConf.keys,function(value,obj1){ - $.each(selUiConf[obj1.key],function(index,obj2){ - if(obj2[0]==indexValue){ - result=obj2[1]; - return false; - } - }); - if(result!==""){ - return false; - } - }); - - return result; -} -function getSelUiConfKeysValue(a, b) { - var result = ""; - if (b == "log") { - result="日志"; - } else if (a == "server" && b == "jvm") { - result="自定义指标"; - } else if (a == "server") { - result="服务端"; - } else if (a == "client") { - result="客户端"; - } - return result; -} -function conditionsAppend(){ - if(checkFunc()){ - var jsonObject; - if("stream"==$("#condType").val()){ - jsonObject = {"type":"stream","expr":HtmlHelper.inputXSSFilter($("#contExpr").val()),"range":HtmlHelper.inputXSSFilter($("#conRange").val()),"func":HtmlHelper.inputXSSFilter($("#conFunc").val()),"cparam":HtmlHelper.inputXSSFilter($("#conFuncParam").val())}; - }else{ - jsonObject = {"type":"timer","time_from":HtmlHelper.inputXSSFilter($("#time_from").val()),"time_to":HtmlHelper.inputXSSFilter($("#time_to").val()),"metric":HtmlHelper.inputXSSFilter($("#conMetric").val()),"upperLimit":HtmlHelper.inputXSSFilter($("#conUpperLimit").val()),"lowerLimit":HtmlHelper.inputXSSFilter($("#conLowerLimit").val()),"aggr":HtmlHelper.inputXSSFilter($("#conAggr").val())}; - if("link-relative"==$("#condType").val()){ - jsonObject["interval"]=HtmlHelper.inputXSSFilter($("#conInterval").val()); - jsonObject["unit"]=HtmlHelper.inputXSSFilter($("#unit").val()); - }else{ - jsonObject["unit"]=HtmlHelper.inputXSSFilter($("#unit").val()); - } - } - appendConditions(jsonObject); - window.winmgr.hide("condDiv"); - window.winmgr.show("objectDiv"); - } -} - -function checkFunc(){ - - var result = true; - if("stream"==$("#condType").val()){ - if(!$("#contExpr").val()){ - result = false; - }else if("count" == $("#conFunc").val() && !$("#conFuncParam").val()){ - result = false; - } - }else{ - if(!$("#time_from").val()||!$("#time_to").val()||!$("#conMetric").val()||!$("#conUpperLimit").val()||!$("#conLowerLimit").val()||!$("#conAggr").val()){ - result = false; - } - if("link-relative"==$("#condType").val()){ - if(!$("#conInterval").val()||!$("#unit").val()){ - result = false; - } - }else{ - if(!$("#unit").val()){ - result = false; - } - } - } - - - if(result){ - $("#conditionsErrMsg").hide(); - }else{ - $("#conditionsErrMsg").show(); - } - - return result; -} -function appendConditions(jsonObj) { - var type = $("#pageType").val(); - if("ADD"==type){ - var newNode = document.createElement("div"); - var stgyDivId = StgyClass.randomId()+"_stgySpan"; - html = '
'+getHtmlAndSetId(stgyDivId)+'
'; - newNode.innerHTML = html; - actionConf.actionObj.parentNode.appendChild(newNode); - }else if("EDIT"==type){ - var oldId = actionConf.actionObj.getElementsByTagName("span")[0].id; - actionConf.actionObj.innerHTML= getHtmlAndSetId(oldId); - StgyClass.updateWhereToStgyAppend(jsonObj); - } - - function getHtmlAndSetId(stgyDivId){ - jsonObj.id = stgyDivId;//赋值id - var html = StgyClass.formatShowWhere(jsonObj)+''; - return html; - } -} -/** - * 条件窗口操作 end - */ - - -/** - * 触发动作操作 begin - */ -function showAction(thisObj,type){ - actionConf.actionObj=thisObj.parentNode; - checkJTAAction(); - $("#actiontype").val(type); - $.each($("textarea[name='actionValue']"),function(index,obj){ - if(index>0){ - removeActonTextarea(obj); - }else{ - obj.value=""; - } - }); - $("#actionDiv").modal({backdrop: 'static', keyboard: false}); - $("#actionDiv").modal(); - //还原只读 - $("#actionSaveButton").show(); - $("#actionValue").removeAttr("readonly"); - - - if("EDIT"==type){ - //不是归属用户,则只读 - var isOwner = $("#isOwner").val(); - $("#actionTypeSel").hide(); - var spanJson = JSON.parse(thisObj.parentNode.getElementsByTagName('span')[0].textContent); - - $.each(spanJson.value,function(index,value){ - /** - * 第一次循环:追加渲染 - */ - if(index>0){ - appendActionTextarea(); - } - }); - var actionTextValues = $("textarea[name='actionValue']"); - $.each(spanJson.value,function(index,value){ - /** - * 第二次循环:赋值 - */ - actionTextValues[index].value=value; - }); - - $("#actionEditType").val(spanJson.type); - - actionChangeShow("EDIT"); - if(isOwner!="true"){ - $("#actionSaveButton").hide(); - } - }else{ - $("#actionTypeSel").show(); - actionChangeShow("ADD"); - } -} - -function checkJTAAction(){ - if($("#enableThreadAnalysis").val() =="true"&& $("#actionTypeSel").find("option[value='threadanalysis']").size() == 0 && $("#ChoosedJTA").size() == 0){ - $("#actionTypeSel").append(""); - } - else if($("#enableThreadAnalysis").val() == "false" && $("#actionTypeSel").find("option[value='threadanalysis']").size() == 1){ - $("#actionTypeSel option[value=threadanalysis]").remove(); - } -} - -function actionAppend(){ - - $("#ActionErrMsg").hide(); - - if(checkAction()){ - appendActions(); - $("#actionDiv").modal('hide'); - }else{ - $("#ActionErrMsg").show(); - } -} - -function appendActionTextarea(thisObj){ - var isOwner = $("#isOwner").val(); - - var html = ''; - if(isOwner == "true"){ - html = ''; - html+= '
'; - }else{ - html = ''; - } - - var newNode = document.createElement("div"); - newNode.innerHTML = html; - document.getElementById("actionBodyDiv").appendChild(newNode); -} -function removeActonTextarea(thisObj){ - var node = thisObj.parentNode.parentNode; - node.removeChild(thisObj.parentNode); -} - -function checkAction(){ - var actionTextValues = $("textarea[name='actionValue']"); - - var checkValue = $.trim(actionTextValues[0].value); //只校验第一个必须输入 - var type = $("#actiontype").val(); - if("ADD"==type && !checkValue){ - return false; - }else if(!checkValue){ - return false; - } - - var result = false; - var actionValues = new Array(); - $.each(actionTextValues,function(index,obj){ - var values = format(obj.value); - obj.value = values; - if(values!=""){ - actionValues.push(values); - result = true; - } - }); - - if(!result){ - $("#ActionErrMsg").show(); - } - - return result; - - function format(_values){ - var result = new Array(); - var values = _values.split(","); - $.each(values,function(index,value){ - value = $.trim(value); - if(value!=""){ - result.push(value); - } - }); - - if(!result || result.length==0){ - return ""; - }else{ - return result.join(","); - } - } -} - -function appendActions() { - var type = $("#actiontype").val(); - var html = getAppendHtml(type); - - if("threadanalysis" == $("#actionTypeSel").val()){ - $("#enableThreadAnalysis").val(false); - } - if("ADD"==type){ - var newNode = document.createElement("div"); - newNode.innerHTML = html; - actionConf.actionObj.parentNode.appendChild(newNode); - - /** - * 计算下拉菜单:删除当前选项 - */ - $("#actionTypeSel option[value="+$("#actionTypeSel").val()+"]").remove(); - - /** - * 计算是否还有添加类型:添加按钮控制 - */ - var actionTypeSelect = document.getElementById("actionTypeSel"); - if(actionTypeSelect.length == 0){ - $("#actionAddButton").attr("class","well-add"); - $("#actionAddButton").click(function(){}); - } - - - }else if("EDIT"==type){ - actionConf.actionObj.parentNode.innerHTML = html; - } - - function getAppendHtml(){ - var result = new Array(); - var actionTextValues = $("textarea[name='actionValue']"); - $.each(actionTextValues,function(index,obj){ - result.push(obj.value); - }); - - var actionType =""; - if(type=="ADD"){ - actionType = $("#actionTypeSel").val(); - }else if(type=="EDIT"){ - actionType = $("#actionEditType").val(); - } - - var jsonObj = {type:HtmlHelper.inputXSSFilter(actionType),value:HtmlHelper.inputXSSFilter(result)}; - if("threadanalysis" == jsonObj.type){ - var html = '
'+jsonObj.type+''+JSON.stringify(jsonObj)+'
'; - }else{ - var html = '
'+jsonObj.type+''+JSON.stringify(jsonObj)+'
'; - } - return html; - } -} -/** - * 触发动作操作 end - */ - - -function delThisObj(thisObj) { - var node = thisObj.parentNode.parentNode; - node.removeChild(thisObj.parentNode); - StgyClass.deleteWhereToStgyAppend(thisObj); -} - -function delThisActionObj(thisObj) { - - /** - * 还原当前选项 - */ - var spanJson = JSON.parse(thisObj.parentNode.getElementsByTagName('span')[0].innerHTML); - if(spanJson.type == "threadanalysis"){ - $("#enableThreadAnalysis").val(true); - } - $('#actionTypeSel').append(""); - $("#actionAddButton").attr("class","glyphicon glyphicon-plus well-add"); - $("#actionAddButton").click(function(){showAction(this,'ADD')}); - /** - * 删除显示 - */ - var node = thisObj.parentNode.parentNode; - node.removeChild(thisObj.parentNode); -} - -function checkNameIShow(){ - if($("#notifyNameI").val()){ - $("#notifyInstances").show(); - }else{ - $("#notifyInstances").val(""); - $("#notifyInstances").hide(); - } - selUiConf["userInput"]["notifyNameI"] = $("#notifyNameI").val(); -} - -function closeObjectDiv() { - window.winmgr.hide("objectDiv"); - window.winmgr.show("notifyList"); -} - -function openHelpDiv() { - window.open("https://uavorg.github.io/documents/uavdoc_useroperation/28.html#%E5%88%9B%E5%BB%BA","apphub.help"); -} - - -/** - * 策略表达式处理类 - */ -var StgyClass = { - datas:{//数据原型 - where:new Array() - }, - initDatas:function(){//初始化数据原型 - StgyClass.datas.where = new Array(); - }, - checkWhereExists : function() { - /** - * 判断条件是否存在 - */ - StgyClass.initDatas(); - var conditions = new Array(), exists = false; - var div = document.getElementById("objectDiv"); - var spans = div.getElementsByTagName("span"); - $.each(spans, function(index, obj) { - if(obj.id && obj.id.indexOf("_stgySpan")>=0){ - exists=true - /** - * 同时将条件数据打包 - */ - StgyClass.datas.where.push(JSON.parse(obj.textContent)); - } - }); - - return exists; - }, - showStgyDiv : function(thisObj,type) { - - var isOwner = $("#isOwner").val(); - /** - * 显示策略编辑(弹出新元素) - */ - actionConf.actionObj=thisObj.parentNode; - - var sb = new StringBuffer(); - sb.append("
"); - sb.append("触发策略"); - sb.append("
"); - sb.append("
"); - - if(StgyClass.checkWhereExists()){ //渲染触发策略页面 - sb.append( '
'); - $.each(StgyClass.datas.where,function(index,data){ - - if(isOwner=="true"){ - sb.append( ''); - }else{ - sb.append( ''); - } - }); - sb.append( '
'); - - - if(isOwner=="true"){ - sb.append( '
'); - }else{ - sb.append( '
'); - } - - if(type=="edit"){ - sb.append(thisObj.parentNode.parentNode.getElementsByTagName("div")[0].innerHTML); - } - sb.append( '
'); - - if(isOwner=="true"){ - sb.append( '
'); - }else{ - sb.append( '
'); - } - - if(type=="edit"){ - sb.append(thisObj.parentNode.parentNode.getElementsByTagName("div")[1].innerHTML); - } - sb.append( '
'); - - if(isOwner=="true"){ - sb.append( '
'); - } - - }else{ - sb.append("
没有可用条件
"); - } - - HtmlHelper.id("stgyDiv").innerHTML = sb.toString(); - window.winmgr.hide("objectDiv"); - window.winmgr.show("stgyDiv"); - - }, - closeStgyDiv : function() { - /** - * 关闭策略编辑(关闭元素) - */ - window.winmgr.hide("stgyDiv"); - window.winmgr.show("objectDiv"); - }, - appendWhereToStgy:function(thisObj) { - /** - * 在策略编辑:将选中条件追加到策略表达式 - */ - var whereId = thisObj.id + "_exp"; - - var html = '  ' - + thisObj.innerText + '  '; - /** - * 必须要focus一下目标元素,不然会跟随光标而追加html内容。 - */ - document.getElementById("stgy_exp").focus(); - var sel = window.getSelection(); - if (sel.getRangeAt && sel.rangeCount) { - var range = sel.getRangeAt(0); - range.deleteContents(); - - var el = document.createElement("div"); - el.innerHTML = html; - var frag = document.createDocumentFragment(), node, lastNode; - while ((node = el.firstChild)) { - lastNode = frag.appendChild(node); - } - range.insertNode(frag); - - // Preserve the selection - if (lastNode) { - range = range.cloneRange(); - range.setStartAfter(lastNode); - range.collapse(true); - sel.removeAllRanges(); - sel.addRange(range); - } - } - }, - saveStgyToAppend : function(type){ - /** - * 策略编辑,保存按钮:关闭编辑,并且将策略结果追加到页面 - */ - var html = document.getElementById("stgy_exp").innerHTML; - var htmlConvergence = document.getElementById("convergence_exp").innerHTML.replace(/<\/?[^>]*>/g,''); - - if(html.length>0 && type=="add"){ - html = '
'+ - '
'+html+'
'+ - '
'+htmlConvergence+'
'+ - '
'+ - ''; - '
'+ - '
'; - - var newNode = document.createElement("div"); - newNode.innerHTML = html; - actionConf.actionObj.parentNode.appendChild(newNode); - - }else if(html.length>0 && type=="edit"){ - actionConf.actionObj.parentNode.getElementsByTagName("div")[0].innerHTML = html; - actionConf.actionObj.parentNode.getElementsByTagName("div")[1].innerHTML = htmlConvergence; - } - - StgyClass.closeStgyDiv(); - - }, - deleteStgyToAppend : function(thisObj){ - /** - * 删除策略结果 - */ - var node = thisObj.parentNode.parentNode.parentNode; - node.removeChild(thisObj.parentNode.parentNode); - }, - updateWhereToStgyAppend : function(json){ - /** - *修改策略结果 - */ - var updateId = json.id+"_exp"; - var stgys = $("span[name='"+updateId+"']"); - $.each(stgys,function(index,obj){ - obj.innerHTML = " "+StgyClass.formatShowWhere(json)+" "; - }); - }, - deleteWhereToStgyAppend : function(thisObj){ - /** - * 删除条件时: 给对应策略添加删除线 - */ - var divId = thisObj.parentNode.getElementsByTagName("span")[0].id+"_exp"; - var stgys = $("span[name='"+divId+"']"); - $.each(stgys,function(index,obj){ - obj.className = "whereStgyEdit whereStgyEdit-delete"; - }); - - }, - /** - * 格式化条件,显示格式(除去id不显示) - * - * @param json - * @returns {String} - */ - formatShowWhere : function(json) { - - if(!json){ - return ""; - } - - var result; - - if(!json.type||json.type=="stream"){ - result = json.expr; - - if(json.range && json.range!=""){ - result += ","+json.range; - } - - if(json.func && json.func!=0 && json.func=="count"){ - result += ","+json.func+">"+json.cparam; - }else if(json.func && json.func!=0){ - result += ","+json.func; - } - }else{ - result = json.metric+","+json.time_from+"-"+json.time_to+","+json.aggr+","; - if(json.interval){ - result+=json.interval+" "; - - } - switch(json.unit){ - case "6": - result+="min"; - break; - case "5": - result+="hour"; - break; - case "1": - result+="day"; - break; - case "2": - result+="week"; - break; - case "3": - result+="month"; - break; - case "4": - result+="year"; - break; - } - } - - return result; - }, - randomId : function(x, y) { - if (!x) { - x = 9999; - } - if (!y) { - y = 1; - } - var d = [ "a", "b", "c", "d", "e", "f", "g", "h", "i" ]; - - var rand = parseInt(Math.random() * (x - y + 1) + y) - + d[parseInt(Math.random() * d.length + 0)] - + parseInt(Math.random() * 1000) - + d[parseInt(Math.random() * d.length + 0)] - + parseInt(Math.random() * 1000); - return rand; - } +/** + * 窗体初始化 + */ +window.winmgr.build({ + id : "notifyList", + height : "auto", + "overflow-y" : "auto", + order : 999, + theme : "ListBG" +}); +window.winmgr.build({ + id : "objectDiv", + height : "auto", + "overflow-y" : "auto", + order : 999, + theme : "ObjectBG" +}); +window.winmgr.build({ + id : "stgyDiv", + height : "auto", + "overflow-y" : "auto", + order : 999, + theme : "StgyDiv" +}); +window.winmgr.build({ + id : "condDiv", + height : "auto", + "overflow-y" : "auto", + order : 999, + theme : "condDiv" +}); +window.winmgr.show("notifyList"); + +/** + * 操作配置 + */ +var actionConf = { + actionObj:null //操作对象 +} +/** + * 下拉框UI + * */ +var selUiConf = { + keys:[ + + {"key":"server","value":"自定义指标"}, + {"key":"server","value":"服务端"}, + {"key":"client","value":"客户端"}, + {"key":"log","value":"日志"} + ], + "server":[ + ["procState","进程状态指标系"], + ["hostState","应用容器状态指标系"], + ["urlResp","服务状态指标系"], + ["appResp","应用状态指标系"], + ["serverResp","应用服务器状态指标系"], + ["procCrash","进程死亡指标系"] + ], + "client":[ + ["clientResp","调用状态指标系"] + ], + "log":[ + ["log","日志"] + ] + , + "userDef":[ + ["jvm","Java虚拟机状态指标系"] + ] + , + userInput:{ + "notifyNameF":"", + "notifyNameM":"", + "notifyNameI":"" + } + +} + +var supportJTA = ["服务状态指标系","应用状态指标系","应用服务器状态指标系","调用状态指标系"]; +/** + * 初始化头部 + */ +function initHeadDiv() { + var divContent = "" + + "
" + + + "" + + + "" + + + "" + + + "
" + + "" + + + "" + + "
" + "
" + ""; + HtmlHelper.id("notifyList").innerHTML += divContent; +} + +/** + * 显示添加策略 + */ +function showAddDiv() { + + var sb=new StringBuffer(); + sb.append( "
"); + sb.append( ""); + sb.append( ""); + sb.append( ""); + sb.append( "添加策略"); + sb.append( "
"); + sb.append( "
"); + sb.append( "
"); + sb.append( "
"); + + sb.append( '
'); + + + sb.append( '
'); + sb.append(''); + sb.append('
'); + sb.append(''); + sb.append(''); + sb.append(''); + sb.append('
'); + sb.append('
'); + + sb.append('
'); + sb.append('
'); + sb.append(''); + sb.append(''); + sb.append(''); + sb.append('
'); + sb.append( '
'); + sb.append('
'); + + sb.append( '
'); + sb.append( "
"); + + + sb.append( '
'); + sb.append( '
'); + + sb.append( '
'); + sb.append( '
条件定义
'); + sb.append( '
'); + + sb.append( '
'); + sb.append( '
触发策略
'); + sb.append( '
'); + + sb.append( '
'); + sb.append( '
触发动作
'); + sb.append( '
'); + + sb.append( '
'); + sb.append( '
'); + sb.append( '
 
'); + + sb.append( '
'); + + HtmlHelper.id("objectDiv").innerHTML = sb.toString(); + window.winmgr.hide("notifyList"); + window.winmgr.show("objectDiv"); + initActionDiv($("#isOwner").val()); + +} + + +/** + * 显示编辑策略 + */ +function showEditNotifyDiv(jsonObjParam) { + + var key,jsonObj,isOwner=false;enableThreadAnalysis=false; + //因为只有一对 key:value 获取key(值为id) + $.each(jsonObjParam,function(index,obj){ + key = index; + jsonObj = obj; + }); + + if(jsonObj.owner == window.parent.loginUser.userId + || window.parent.loginUser.groupId == "uav_admin" + || window.parent.loginUser.groupId == "vipgroup" + ){ + isOwner = true; + } + + var names = key.split("@"); + var cssType = "displayMsgInput",cssRedOnly = "displayMsgInput listIndex"; + var sb=new StringBuffer(); + sb.append( "
"); + sb.append( ""); + sb.append( "编辑策略"); + sb.append( "
"); + sb.append( "
"); + sb.append( "
"); + sb.append( "
"); + /** + * 所有渲染内容 div begin + */ + sb.append( '
'); + + sb.append( '
'); + if(window.parent.loginUser.groupId == "uav_admin" + || window.parent.loginUser.groupId == "vipgroup" + ){ + sb.append( '
'); + }else{ + + sb.append( '
'); + } + + + sb.append( '
'); + + //1 + var existsIns = jsonObj.instances.length>0?true:false; + var showNameF = getSelUiConfKeysValue(names[0],names[1]); + if(showNameF=="自定义指标"){ + cssType = "displayMsgInput listIndex_appmetrics"; + }else if(names[1] == "log"){ + showNameF = "日志"; + cssType = "displayMsgInput listIndex_log"; + }else if(names[0] == "server"){ + cssType = "displayMsgInput listIndex_server"; + }else if(names[0] == "client"){ + cssType = "displayMsgInput listIndex_client"; + } + sb.append( '
'); + selUiConf["userInput"]["notifyNameF"]=names[0];//编辑赋值,准备修改数据 + //2 + if(showNameF=="自定义指标"){ + selUiConf["userInput"]["notifyNameM"]=names[1];//编辑赋值,准备修改数据 + }else if(names[1] == "log"){ + sb.append( '
'); + selUiConf["userInput"]["notifyNameM"]=names[1];//编辑赋值,准备修改数据 + }else if(names[1]){ + sb.append( '
'); + selUiConf["userInput"]["notifyNameM"]=names[1];//编辑赋值,准备修改数据 + if($.inArray(getSelUiConfigValue(names[1]),supportJTA) >= 0){ + enableThreadAnalysis=true; + } + } + //3 + if(names[2] && names[1] == "log"){ + var nNameIShow = "指定日志:"+names[2]; + sb.append( '
'); + selUiConf["userInput"]["notifyNameI"]=names[2];//编辑赋值,准备修改数据 + }else if(names[1] == "log"){ + sb.append( '
'); + }else if(names[2]){ + var nNameIShow = (existsIns?"实例组:":"实例:")+names[2]; + sb.append( '
'); + selUiConf["userInput"]["notifyNameI"]=names[2];//编辑赋值,准备修改数据 + }else{ + sb.append( '
'); + } + + if(names[2] && isOwner){ + sb.append( "
'); + }else if(names[2] && !isOwner){ + sb.append( "
'); + }else if(isOwner){ + sb.append( "
'); + }else{ + sb.append( "
'); + } + + + sb.append( '
'); + if(isOwner){ + sb.append( '
'); + }else{ + sb.append( '
'); + } + + /** + * 初始化条件 begin + */ + sb.append( '
'); + sb.append( '
'); + sb.append( '条件定义'); + sb.append( '
'); + $.each(jsonObj.conditions,function(index,obj){ + if(obj.func && obj.func.indexOf("count>")>-1){ + obj.cparam = obj.func.substr(6); + obj.func = "count"; + } + + if(!obj.id){ + /** + * 兼容老数据 + */ + obj.id=StgyClass.randomId()+"_stgySpan"; + } + var html; + if(isOwner){ + html = '
'+StgyClass.formatShowWhere(obj)+'
'; + }else{ + html = '
'+StgyClass.formatShowWhere(obj)+'
'; + } + sb.append( html); + }); + sb.append( '
'); + sb.append( '
'); + /** + * 初始化条件 end + */ + + /** + * 初始化触发策略 begin + */ + sb.append( '
'); + + if(isOwner){ + sb.append( '
触发策略
'); + }else{ + sb.append( '
触发策略
'); + } + + if(jsonObj.relationsHtmls){ + $.each(jsonObj.relationsHtmls,function(index,html){ + var convergenceVal = ""; + if(jsonObj.hasOwnProperty("convergences")){ + convergenceVal = jsonObj.convergences[index]; + } + + var appendHtml = + '
'+ + '
'+ + '
'+html+'
'+ + '
'+convergenceVal+'
'+ + '
'; + + if(isOwner){ + appendHtml+=''; + }else{ + appendHtml+=''; + } + appendHtml+='
'+ + '
'+ + '
'; + sb.append(appendHtml); + }); + } + sb.append( '
'); + /** + * 初始化触发策略 begin + */ + + sb.append( '
'); + sb.append( '
触发动作
'); + var actionSum = 0; + initActionDiv(isOwner?"true":"false"); + if (jsonObj.action!=undefined) { + $.each(jsonObj.action,function(index,value){ + actionSum++; + var josnSpan ={ + "type":index, + "value":value + } + + var html ; + + if(isOwner){ + if("threadanalysis" == josnSpan.type){ + var html = '
'+josnSpan.type+''+JSON.stringify(josnSpan)+'
'; + }else{ + html = '
'+josnSpan.type+''+JSON.stringify(josnSpan)+'
'; + } + }else{ + html = '
'+josnSpan.type+''+JSON.stringify(josnSpan)+'
'; + } + sb.append( '
'); + sb.append( html); + sb.append( '
'); + + /** + * 计算下拉选项 + */ + $("#actionTypeSel option[value="+josnSpan.type+"]").remove(); + + }); + } + sb.append( '
'); + /** + * 初始化触发动作 end + */ + + if(isOwner){ + //按钮 + sb.append( '
'); + sb.append( '
'); + sb.append( '
 
'); + } + + sb.append( '
'); + /** + * 所有渲染内容 div end + */ + sb.append( ""); + HtmlHelper.id("objectDiv").innerHTML = sb.toString(); + + /** + * 判断出发条件:不是归属者不能添加 + */ + if(!isOwner){ + $("#whereAddButton").attr("class","well-add"); + $("#whereAddButton").click(function(){}); + } + /** + * 判断触发动作按钮 begin(类型都已经存在值,则不能再添加) + * 不是归属者也不能添加 + */ + var selTypeSize = $("#actionTypeSel option").size(); + if(selTypeSize == 0 || !isOwner){ + $("#actionAddButton").attr("class","well-add"); + $("#actionAddButton").click(function(){}); + } + /** + * 判断触发动作按钮 end + */ + window.winmgr.hide("notifyList"); + window.winmgr.show("objectDiv"); + + hideShowConStgy(names[1]); +} + + + +/** + * 触发动作添加窗口 + */ +function initActionDiv(isOwner) { + + var old = document.getElementById("actionDiv"); + if(old){ + var node = old.parentNode; + node.removeChild(old); + } + + var sb=new StringBuffer(); + + sb.append(''); + var div = document.createElement('div'); + div.innerHTML = sb.toString(); + document.body.appendChild(div); +} + +/** + * 显示添加条件窗口 + * @param thisObj + * @param type + */ +function showCon(thisObj,type){ + actionConf.actionObj=thisObj.parentNode; + if(selUiConf["userInput"]["notifyNameM"]=="log"){ + $("#condType").attr("disabled","disabled"); + } + $("#pageType").val(type); + if("EDIT" == type){ + var jsonValue = JSON.parse(thisObj.parentNode.getElementsByTagName("span")[0].textContent); + $("#condType").attr("disabled","disabled"); + var isOwner = $("#isOwner").val(); + if(!jsonValue.type||jsonValue.type=="stream"){ + $("#condType").val("stream"); + $("#contExpr").val(jsonValue.expr); + $("#conRange").val(jsonValue.range); + $("#conFunc").val((null == jsonValue.func?0:jsonValue.func)); + if("count" == jsonValue.func){ + $("#conFuncParam").val(jsonValue.cparam); + $("#conFuncParam").show(); + } + //不是归属用户,则只读 + if(isOwner!="true"){ + $("#whereSaveButton").hide(); + $("#contExpr").attr("readonly","readonly"); + $("#conRange").attr("readonly","readonly"); + $("#conFunc").attr("disabled","disabled"); + $("#conFuncParam").attr("readonly","readonly"); + + //只读CSS + $("#contExpr").attr("class","form-control"); + $("#conRange").attr("class","form-control"); + $("#conFuncParam").attr("class","form-control"); + $("#whereSaveButton").hide(); + } + + }else{ + var type; + if(jsonValue.interval){ + type="link-relative"; + }else{ + type="base-relative"; + } + $("#condType").val(type); + typeChangeShow(type); + + var hour=jsonValue.time_from.split(':')[0]; + var min=jsonValue.time_from.split(':')[1]; + $('#time_from_div').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); + hour=jsonValue.time_to.split(':')[0]; + min=jsonValue.time_to.split(':')[1]; + $('#time_to_div').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); + + if(jsonValue.time_start!=undefined&&jsonValue.time_end!=undefined){ + hour=jsonValue.time_start.split(':')[0]; + min=jsonValue.time_start.split(':')[1]; + $('#time_start_div').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); + hour=jsonValue.time_end.split(':')[0]; + min=jsonValue.time_end.split(':')[1]; + $('#time_end_div').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); + } + + if(jsonValue.day_start!=undefined&&jsonValue.day_end!=undefined){ + var year=jsonValue.day_start.split('-')[0]; + var month=jsonValue.day_start.split('-')[1]; + var day=jsonValue.day_start.split('-')[2]; + $('#day_start_div').data('datetimepicker').setLocalDate(new Date(year, month-1, day, 0, 0)); + year=jsonValue.day_end.split('-')[0]; + month=jsonValue.day_end.split('-')[1]; + day=jsonValue.day_end.split('-')[2]; + $('#day_end_div').data('datetimepicker').setLocalDate(new Date(year, month-1, day, 0, 0)); + } + + showWeekDay(jsonValue.weekdayLimit); + + $("#conMetric").val(jsonValue.metric); + $("#conUpperLimit").val(jsonValue.upperLimit); + $("#conLowerLimit").val(jsonValue.lowerLimit); + $("#conAggr").val(jsonValue.aggr); + $("#conDownSample").val(jsonValue.downsample); + if(type=="link-relative"){ + $("#conInterval").val(jsonValue.interval); + } + showUnit(jsonValue.unit); + + if(isOwner!="true"){ + $("#time_from").attr("readonly","readonly"); + $("#time_to").attr("readonly","readonly"); + $("#time_start").attr("readonly","readonly"); + $("#time_end").attr("readonly","readonly"); + $("#day_start").attr("readonly","readonly"); + $("#day_end").attr("readonly","readonly"); + $("#conMetric").attr("readonly","readonly"); + $("#conUpperLimit").attr("readonly","readonly"); + $("#conLowerLimit").attr("readonly","readonly"); + $("#conMetric").attr("class","form-control"); + $("#conUpperLimit").attr("class","form-control"); + $("#conLowerLimit").attr("class","form-control"); + $("#conAggr").attr("disabled","disabled"); + $("#conDownSample").attr("disabled","disabled"); + if(type=="link-relative"){ + $("#conInterval").attr("readonly","readonly"); + $("#conInterval").attr("class","form-control"); + } + $("#whereSaveButton").hide(); + } + } + + } + +} + +function showUnit(unit){ + $("#unit").val(unit); + $("#opt"+unit).attr("class","btn btn-default active"); +} + +function showWeekDay(weekdayLimit){ + + for(var i=0;i"); + sb.append("条件定义"); + sb.append("
"); + sb.append("
"); + sb.append( "
'); + + sb.append( '
'); + /** + * 普通预警条件编辑 + */ + sb.append( '
'); + + sb.append( '
触发表达式

'); + sb.append( '
持续时间(秒)

'); + sb.append( "
聚集操作

'); + sb.append( ')\" style="display:none" onkeyup="this.value=this.value.replace(\/\\D/g,\'\')" onafterpaste="this.value=this.value.replace(\/\\D/g,\'\')">
'); + sb.append( '
'); + + /** + * 同环比预警条件编辑 + */ + sb.append( ''); + sb.append( ''); + + /** + * 保存按钮 + */ + sb.append( '
'); + sb.append( ''); + sb.append( ''); + sb.append( '
'); + + HtmlHelper.id("condDiv").innerHTML = sb.toString(); + initTimeControl(); + showCon(thisObj,type); + window.winmgr.hide("objectDiv"); + window.winmgr.show("condDiv"); + +} + +function funcChangeShow(thisObj,showId){ + if("count" == thisObj.value){ + $("#"+showId).show(); + }else{ + $("#"+showId).hide(); + } +} + +function typeChangeShow(type){ + var divs=["stream","timer","link-relative","base-relative"]; + divs.forEach(div=>{ + $("#"+div).hide(); + }) + if("stream"!=type){ + $("#timer").show(); + } + $("#"+type).show(); + +} +/** + * 初始化时间控件 + */ +function initTimeControl(){ + $('#time_from_div').datetimepicker({ + pickDate: false, + pickSeconds: false + }); + + + $('#time_to_div').datetimepicker({ + pickDate: false, + pickSeconds: false + }); + + $('#time_start_div').datetimepicker({ + pickDate: false, + pickSeconds: false + }); + + + $('#time_end_div').datetimepicker({ + pickDate: false, + pickSeconds: false + }); + + $('#day_start_div').datetimepicker({ + pickHour: false, + pickMin: false, + pickSeconds: false + }); + + + $('#day_end_div').datetimepicker({ + pickHour: false, + pickMin: false, + pickSeconds: false + }); + + +} + +function changeTimeUnit(value){ + $("#unit").val(value); +} + + + +function actionChangeShow(type){ + if("ADD" == type){ + if("threadanalysis" == $("#actionTypeSel").val()){ + $("textarea[name='actionValue']").val("10101").hide(); + $(".btn-addPriority").hide(); + }else{ + $("textarea[name='actionValue']").val("").show(); + $(".btn-addPriority").show(); + } + }else{ + $("textarea[name='actionValue']").show(); + $(".btn-addPriority").show(); + } +} + +function selServerChangeShow(type,value,text){ + var selId = type+"_notifyNameF"; + $("#"+selId).html(text); + $("#"+selId).css("padding-left","2px"); + $("#"+type+"_notifyNameF").css("color","black"); + + hideShowConStgy("show"); + + if(text == "自定义指标"){ + $("#"+type+"_appName_div").hide(); + $("#"+type+"_notifyNameM_div").attr("class","btn-group selectDiv defNone"); + selUiConf["userInput"]["notifyNameF"]=value; + selUiConf["userInput"]["notifyNameM"]="jvm"; + $("#notifyNameI").attr("placeholder","输入监控实例名或者实例组名"); + $("#enableThreadAnalysis").val(false); + removeChoosedJTA(); + }else if(value=="log"){ + $("#"+type+"_appName_div").show(); + $("#"+type+"_notifyNameM_div").attr("class","btn-group selectDiv defNone"); + $("#notifyNameI").attr("placeholder","输入指定日志"); + selUiConf["userInput"]["notifyNameF"]=""; + selUiConf["userInput"]["notifyNameM"]=value; + $("#enableThreadAnalysis").val(false); + removeChoosedJTA(); + }else{ + $("#"+type+"_appName_div").hide(); + $("#"+type+"_notifyNameM_div").attr("class","btn-group selectDiv"); + $("#notifyNameI").attr("placeholder","输入监控实例名或者实例组名"); + $("#"+type+"_notifyNameM").css("color","darkgrey"); + $("#"+type+"_notifyNameM").html("选择监控组指标"); + document.getElementById(type+"_notifyNameM_body").innerHTML =""; + $.each(selUiConf[value],function(index,obj){ + var li = document.createElement("li"); + var a = document.createElement("a"); + a.innerHTML=obj[1]; + a.onclick=function(){selIndexChangeShow(type,obj[0],obj[1]);}; + a.href="#"; + li.appendChild(a); + document.getElementById(type+"_notifyNameM_body").appendChild(li); + }); + selUiConf["userInput"]["notifyNameF"]=value; + } + +} + +function removeChoosedJTA(){ + if(HtmlHelper.id("ChoosedJTA") != null){ + HtmlHelper.id("ChoosedJTA").remove(); + } +} + +function changeJTAStat(text){ + if($.inArray(text,supportJTA) >= 0){ + $("#enableThreadAnalysis").val(true); + if(HtmlHelper.id("ChoosedJTA") == null){ + $("#actionAddButton").attr("class","glyphicon glyphicon-plus well-add"); + $("#actionAddButton").click(function(){showAction(this,'ADD')}); + } + }else{ + $("#enableThreadAnalysis").val(false); + removeChoosedJTA(); + } +} + +function hideShowConStgy(value){ + if(value == "procCrash"){ + $("#conFatDiv").hide(); + $("#stgyFatDiv").hide(); + } + else{ + $("#conFatDiv").show(); + $("#stgyFatDiv").show(); + } +} + +function selIndexChangeShow(type,value,text){ + changeJTAStat(text); + hideShowConStgy(value); + + $("#"+type+"_notifyNameM").html(text); + $("#"+type+"_notifyNameM").css("padding-left","2px"); + $("#"+type+"_notifyNameM").css("color","black"); + selUiConf["userInput"]["notifyNameM"]=value; +} + +function appNameChange(obj){ + selUiConf["userInput"]["notifyNameF"]=obj.value; +} +function getSelUiConfigValue(indexValue){ + var result =""; + $.each(selUiConf.keys,function(value,obj1){ + $.each(selUiConf[obj1.key],function(index,obj2){ + if(obj2[0]==indexValue){ + result=obj2[1]; + return false; + } + }); + if(result!==""){ + return false; + } + }); + + return result; +} +function getSelUiConfKeysValue(a, b) { + var result = ""; + if (b == "log") { + result="日志"; + } else if (a == "server" && b == "jvm") { + result="自定义指标"; + } else if (a == "server") { + result="服务端"; + } else if (a == "client") { + result="客户端"; + } + return result; +} +function conditionsAppend(){ + if(checkFunc()){ + var jsonObject; + if("stream"==$("#condType").val()){ + jsonObject = {"type":"stream","expr":HtmlHelper.inputXSSFilter($("#contExpr").val()),"range":HtmlHelper.inputXSSFilter($("#conRange").val()),"func":HtmlHelper.inputXSSFilter($("#conFunc").val()),"cparam":HtmlHelper.inputXSSFilter($("#conFuncParam").val())}; + }else{ + jsonObject = {"type":"timer","time_from":HtmlHelper.inputXSSFilter($("#time_from").val()),"time_to":HtmlHelper.inputXSSFilter($("#time_to").val()),"metric":HtmlHelper.inputXSSFilter($("#conMetric").val()),"upperLimit":HtmlHelper.inputXSSFilter($("#conUpperLimit").val()),"lowerLimit":HtmlHelper.inputXSSFilter($("#conLowerLimit").val())}; + + if(HtmlHelper.inputXSSFilter($("#conAggr").val())!="0"){ + jsonObject["aggr"]=HtmlHelper.inputXSSFilter($("#conAggr").val()); + }else{ + jsonObject["aggr"]="avg"; + } + + if(HtmlHelper.inputXSSFilter($("#conDownSample").val())!="0"){ + jsonObject["downsample"]=HtmlHelper.inputXSSFilter($("#conDownSample").val()); + }else{ + jsonObject["downsample"]="all-avg"; + } + + if("link-relative"==$("#condType").val()){ + jsonObject["interval"]=HtmlHelper.inputXSSFilter($("#conInterval").val()); + jsonObject["unit"]=HtmlHelper.inputXSSFilter($("#unit").val()); + }else{ + jsonObject["unit"]=HtmlHelper.inputXSSFilter($("#unit").val()); + } + + if($("#time_start").val()&&$("#time_end").val()){ + jsonObject["time_start"]=HtmlHelper.inputXSSFilter($("#time_start").val()); + jsonObject["time_end"]=HtmlHelper.inputXSSFilter($("#time_end").val()); + } + + if($("#day_start").val()&&$("#day_end").val()){ + jsonObject["day_start"]=HtmlHelper.inputXSSFilter($("#day_start").val()); + jsonObject["day_end"]=HtmlHelper.inputXSSFilter($("#day_end").val()); + } + + var weekdayLimit=[]; + for(var i=0;i<7;i++){ + weekdayLimit[i]=($("#weekday"+i).attr("class")=="btn btn-default active") + } + jsonObject["weekdayLimit"]=weekdayLimit; + + } + appendConditions(jsonObject); + window.winmgr.hide("condDiv"); + window.winmgr.show("objectDiv"); + } +} + +function checkFunc(){ + + var result = true; + if("stream"==$("#condType").val()){ + if(!$("#contExpr").val()){ + result = false; + }else if("count" == $("#conFunc").val() && !$("#conFuncParam").val()){ + result = false; + } + }else{ + if(!$("#time_from").val()||!$("#time_to").val()||!$("#conMetric").val()||!$("#conUpperLimit").val()||!$("#conLowerLimit").val()){ + result = false; + } + if("link-relative"==$("#condType").val()){ + if(!$("#conInterval").val()||!$("#unit").val()){ + result = false; + } + }else{ + if(!$("#unit").val()){ + result = false; + } + } + } + + + if(result){ + $("#conditionsErrMsg").hide(); + }else{ + $("#conditionsErrMsg").show(); + } + + return result; +} +function appendConditions(jsonObj) { + var type = $("#pageType").val(); + if("ADD"==type){ + var newNode = document.createElement("div"); + var stgyDivId = StgyClass.randomId()+"_stgySpan"; + html = '
'+getHtmlAndSetId(stgyDivId)+'
'; + newNode.innerHTML = html; + actionConf.actionObj.parentNode.appendChild(newNode); + }else if("EDIT"==type){ + var oldId = actionConf.actionObj.getElementsByTagName("span")[0].id; + actionConf.actionObj.innerHTML= getHtmlAndSetId(oldId); + StgyClass.updateWhereToStgyAppend(jsonObj); + } + + function getHtmlAndSetId(stgyDivId){ + jsonObj.id = stgyDivId;//赋值id + var html = StgyClass.formatShowWhere(jsonObj)+''; + return html; + } +} +/** + * 条件窗口操作 end + */ + + +/** + * 触发动作操作 begin + */ +function showAction(thisObj,type){ + actionConf.actionObj=thisObj.parentNode; + checkJTAAction(); + $("#actiontype").val(type); + $.each($("textarea[name='actionValue']"),function(index,obj){ + if(index>0){ + removeActonTextarea(obj); + }else{ + obj.value=""; + } + }); + $("#actionDiv").modal({backdrop: 'static', keyboard: false}); + $("#actionDiv").modal(); + //还原只读 + $("#actionSaveButton").show(); + $("#actionValue").removeAttr("readonly"); + + + if("EDIT"==type){ + //不是归属用户,则只读 + var isOwner = $("#isOwner").val(); + $("#actionTypeSel").hide(); + var spanJson = JSON.parse(thisObj.parentNode.getElementsByTagName('span')[0].textContent); + + $.each(spanJson.value,function(index,value){ + /** + * 第一次循环:追加渲染 + */ + if(index>0){ + appendActionTextarea(); + } + }); + var actionTextValues = $("textarea[name='actionValue']"); + $.each(spanJson.value,function(index,value){ + /** + * 第二次循环:赋值 + */ + actionTextValues[index].value=value; + }); + + $("#actionEditType").val(spanJson.type); + + actionChangeShow("EDIT"); + if(isOwner!="true"){ + $("#actionSaveButton").hide(); + } + }else{ + $("#actionTypeSel").show(); + actionChangeShow("ADD"); + } +} + +function checkJTAAction(){ + if($("#enableThreadAnalysis").val() =="true"&& $("#actionTypeSel").find("option[value='threadanalysis']").size() == 0 && $("#ChoosedJTA").size() == 0){ + $("#actionTypeSel").append(""); + } + else if($("#enableThreadAnalysis").val() == "false" && $("#actionTypeSel").find("option[value='threadanalysis']").size() == 1){ + $("#actionTypeSel option[value=threadanalysis]").remove(); + } +} + +function actionAppend(){ + + $("#ActionErrMsg").hide(); + + if(checkAction()){ + appendActions(); + $("#actionDiv").modal('hide'); + }else{ + $("#ActionErrMsg").show(); + } +} + +function appendActionTextarea(thisObj){ + var isOwner = $("#isOwner").val(); + + var html = ''; + if(isOwner == "true"){ + html = ''; + html+= '
'; + }else{ + html = ''; + } + + var newNode = document.createElement("div"); + newNode.innerHTML = html; + document.getElementById("actionBodyDiv").appendChild(newNode); +} +function removeActonTextarea(thisObj){ + var node = thisObj.parentNode.parentNode; + node.removeChild(thisObj.parentNode); +} + +function checkAction(){ + var actionTextValues = $("textarea[name='actionValue']"); + + var checkValue = $.trim(actionTextValues[0].value); //只校验第一个必须输入 + var type = $("#actiontype").val(); + if("ADD"==type && !checkValue){ + return false; + }else if(!checkValue){ + return false; + } + + var result = false; + var actionValues = new Array(); + $.each(actionTextValues,function(index,obj){ + var values = format(obj.value); + obj.value = values; + if(values!=""){ + actionValues.push(values); + result = true; + } + }); + + if(!result){ + $("#ActionErrMsg").show(); + } + + return result; + + function format(_values){ + var result = new Array(); + var values = _values.split(","); + $.each(values,function(index,value){ + value = $.trim(value); + if(value!=""){ + result.push(value); + } + }); + + if(!result || result.length==0){ + return ""; + }else{ + return result.join(","); + } + } +} + +function appendActions() { + var type = $("#actiontype").val(); + var html = getAppendHtml(type); + + if("threadanalysis" == $("#actionTypeSel").val()){ + $("#enableThreadAnalysis").val(false); + } + if("ADD"==type){ + var newNode = document.createElement("div"); + newNode.innerHTML = html; + actionConf.actionObj.parentNode.appendChild(newNode); + + /** + * 计算下拉菜单:删除当前选项 + */ + $("#actionTypeSel option[value="+$("#actionTypeSel").val()+"]").remove(); + + /** + * 计算是否还有添加类型:添加按钮控制 + */ + var actionTypeSelect = document.getElementById("actionTypeSel"); + if(actionTypeSelect.length == 0){ + $("#actionAddButton").attr("class","well-add"); + $("#actionAddButton").click(function(){}); + } + + + }else if("EDIT"==type){ + actionConf.actionObj.parentNode.innerHTML = html; + } + + function getAppendHtml(){ + var result = new Array(); + var actionTextValues = $("textarea[name='actionValue']"); + $.each(actionTextValues,function(index,obj){ + result.push(obj.value); + }); + + var actionType =""; + if(type=="ADD"){ + actionType = $("#actionTypeSel").val(); + }else if(type=="EDIT"){ + actionType = $("#actionEditType").val(); + } + + var jsonObj = {type:HtmlHelper.inputXSSFilter(actionType),value:HtmlHelper.inputXSSFilter(result)}; + if("threadanalysis" == jsonObj.type){ + var html = '
'+jsonObj.type+''+JSON.stringify(jsonObj)+'
'; + }else{ + var html = '
'+jsonObj.type+''+JSON.stringify(jsonObj)+'
'; + } + return html; + } +} +/** + * 触发动作操作 end + */ + + +function delThisObj(thisObj) { + var node = thisObj.parentNode.parentNode; + node.removeChild(thisObj.parentNode); + StgyClass.deleteWhereToStgyAppend(thisObj); +} + +function delThisActionObj(thisObj) { + + /** + * 还原当前选项 + */ + var spanJson = JSON.parse(thisObj.parentNode.getElementsByTagName('span')[0].innerHTML); + if(spanJson.type == "threadanalysis"){ + $("#enableThreadAnalysis").val(true); + } + $('#actionTypeSel').append(""); + $("#actionAddButton").attr("class","glyphicon glyphicon-plus well-add"); + $("#actionAddButton").click(function(){showAction(this,'ADD')}); + /** + * 删除显示 + */ + var node = thisObj.parentNode.parentNode; + node.removeChild(thisObj.parentNode); +} + +function checkNameIShow(){ + if($("#notifyNameI").val()){ + $("#notifyInstances").show(); + }else{ + $("#notifyInstances").val(""); + $("#notifyInstances").hide(); + } + selUiConf["userInput"]["notifyNameI"] = $("#notifyNameI").val(); +} + +function closeObjectDiv() { + window.winmgr.hide("objectDiv"); + window.winmgr.show("notifyList"); +} + +function openHelpDiv() { + window.open("https://uavorg.github.io/documents/uavdoc_useroperation/28.html#%E5%88%9B%E5%BB%BA","apphub.help"); +} + + +/** + * 策略表达式处理类 + */ +var StgyClass = { + datas:{//数据原型 + where:new Array() + }, + initDatas:function(){//初始化数据原型 + StgyClass.datas.where = new Array(); + }, + checkWhereExists : function() { + /** + * 判断条件是否存在 + */ + StgyClass.initDatas(); + var conditions = new Array(), exists = false; + var div = document.getElementById("objectDiv"); + var spans = div.getElementsByTagName("span"); + $.each(spans, function(index, obj) { + if(obj.id && obj.id.indexOf("_stgySpan")>=0){ + exists=true + /** + * 同时将条件数据打包 + */ + StgyClass.datas.where.push(JSON.parse(obj.textContent)); + } + }); + + return exists; + }, + showStgyDiv : function(thisObj,type) { + + var isOwner = $("#isOwner").val(); + /** + * 显示策略编辑(弹出新元素) + */ + actionConf.actionObj=thisObj.parentNode; + + var sb = new StringBuffer(); + sb.append("
"); + sb.append("触发策略"); + sb.append("
"); + sb.append("
"); + + if(StgyClass.checkWhereExists()){ //渲染触发策略页面 + sb.append( '
'); + $.each(StgyClass.datas.where,function(index,data){ + + if(isOwner=="true"){ + sb.append( ''); + }else{ + sb.append( ''); + } + }); + sb.append( '
'); + + + if(isOwner=="true"){ + sb.append( '
'); + }else{ + sb.append( '
'); + } + + if(type=="edit"){ + sb.append(thisObj.parentNode.parentNode.getElementsByTagName("div")[0].innerHTML); + } + sb.append( '
'); + + if(isOwner=="true"){ + sb.append( '
'); + }else{ + sb.append( '
'); + } + + if(type=="edit"){ + sb.append(thisObj.parentNode.parentNode.getElementsByTagName("div")[1].innerHTML); + } + sb.append( '
'); + + if(isOwner=="true"){ + sb.append( '
'); + } + + }else{ + sb.append("
没有可用条件
"); + } + + HtmlHelper.id("stgyDiv").innerHTML = sb.toString(); + window.winmgr.hide("objectDiv"); + window.winmgr.show("stgyDiv"); + + }, + closeStgyDiv : function() { + /** + * 关闭策略编辑(关闭元素) + */ + window.winmgr.hide("stgyDiv"); + window.winmgr.show("objectDiv"); + }, + appendWhereToStgy:function(thisObj) { + /** + * 在策略编辑:将选中条件追加到策略表达式 + */ + var whereId = thisObj.id + "_exp"; + + var html = '  ' + + thisObj.innerText + '  '; + /** + * 必须要focus一下目标元素,不然会跟随光标而追加html内容。 + */ + document.getElementById("stgy_exp").focus(); + var sel = window.getSelection(); + if (sel.getRangeAt && sel.rangeCount) { + var range = sel.getRangeAt(0); + range.deleteContents(); + + var el = document.createElement("div"); + el.innerHTML = html; + var frag = document.createDocumentFragment(), node, lastNode; + while ((node = el.firstChild)) { + lastNode = frag.appendChild(node); + } + range.insertNode(frag); + + // Preserve the selection + if (lastNode) { + range = range.cloneRange(); + range.setStartAfter(lastNode); + range.collapse(true); + sel.removeAllRanges(); + sel.addRange(range); + } + } + }, + saveStgyToAppend : function(type){ + /** + * 策略编辑,保存按钮:关闭编辑,并且将策略结果追加到页面 + */ + var html = document.getElementById("stgy_exp").innerHTML; + var htmlConvergence = document.getElementById("convergence_exp").innerHTML.replace(/<\/?[^>]*>/g,''); + + if(html.length>0 && type=="add"){ + html = '
'+ + '
'+html+'
'+ + '
'+htmlConvergence+'
'+ + '
'+ + ''; + '
'+ + '
'; + + var newNode = document.createElement("div"); + newNode.innerHTML = html; + actionConf.actionObj.parentNode.appendChild(newNode); + + }else if(html.length>0 && type=="edit"){ + actionConf.actionObj.parentNode.getElementsByTagName("div")[0].innerHTML = html; + actionConf.actionObj.parentNode.getElementsByTagName("div")[1].innerHTML = htmlConvergence; + } + + StgyClass.closeStgyDiv(); + + }, + deleteStgyToAppend : function(thisObj){ + /** + * 删除策略结果 + */ + var node = thisObj.parentNode.parentNode.parentNode; + node.removeChild(thisObj.parentNode.parentNode); + }, + updateWhereToStgyAppend : function(json){ + /** + *修改策略结果 + */ + var updateId = json.id+"_exp"; + var stgys = $("span[name='"+updateId+"']"); + $.each(stgys,function(index,obj){ + obj.innerHTML = " "+StgyClass.formatShowWhere(json)+" "; + }); + }, + deleteWhereToStgyAppend : function(thisObj){ + /** + * 删除条件时: 给对应策略添加删除线 + */ + var divId = thisObj.parentNode.getElementsByTagName("span")[0].id+"_exp"; + var stgys = $("span[name='"+divId+"']"); + $.each(stgys,function(index,obj){ + obj.className = "whereStgyEdit whereStgyEdit-delete"; + }); + + }, + /** + * 格式化条件,显示格式(除去id不显示) + * + * @param json + * @returns {String} + */ + formatShowWhere : function(json) { + + if(!json){ + return ""; + } + + var result; + + if(!json.type||json.type=="stream"){ + result = json.expr; + + if(json.range && json.range!=""){ + result += ","+json.range; + } + + if(json.func && json.func!=0 && json.func=="count"){ + result += ","+json.func+">"+json.cparam; + }else if(json.func && json.func!=0){ + result += ","+json.func; + } + }else{ + result = json.metric+","+json.time_from+"-"+json.time_to+","+json.downsample+","+json.aggr+","; + if(json.interval){ + result+=json.interval+" "; + + } + switch(json.unit){ + case "6": + result+="min"; + break; + case "5": + result+="hour"; + break; + case "1": + result+="day"; + break; + case "2": + result+="week"; + break; + case "3": + result+="month"; + break; + case "4": + result+="year"; + break; + } + if(json.time_start!=undefined&&json.time_end!=undefined){ + result+=","+json.time_start+"-"+json.time_end; + } + if(json.day_start!=undefined&&json.day_end!=undefined){ + result+=","+json.day_start+"-"+json.day_end; + } + } + + return result; + }, + randomId : function(x, y) { + if (!x) { + x = 9999; + } + if (!y) { + y = 1; + } + var d = [ "a", "b", "c", "d", "e", "f", "g", "h", "i" ]; + + var rand = parseInt(Math.random() * (x - y + 1) + y) + + d[parseInt(Math.random() * d.length + 0)] + + parseInt(Math.random() * 1000) + + d[parseInt(Math.random() * d.length + 0)] + + parseInt(Math.random() * 1000); + return rand; + } } \ No newline at end of file diff --git a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/NotifyStrategy.java b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/NotifyStrategy.java index 147218cc..f5b420c1 100644 --- a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/NotifyStrategy.java +++ b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/NotifyStrategy.java @@ -1,511 +1,562 @@ -/*- - * << - * UAVStack - * == - * Copyright (C) 2016 - 2017 UAVStack - * == - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * >> - */ - -package com.creditease.uav.feature.runtimenotify; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.creditease.agent.helpers.DateTimeHelper; -import com.creditease.agent.helpers.EncodeHelper; -import com.creditease.agent.helpers.JSONHelper; - -/** - * notify strategy ds - */ -public class NotifyStrategy { - - public enum Type { - STREAM("stream"), TIMER("timer"); - - private String name; - - Type(String name) { - this.name = name; - } - - @Override - public String toString() { - - return name; - } - } - - private static final String[] OPERATORS = { ":=", "!=", ">", "<", "=" }; - - private static final Pattern INDEX_PATTERN = Pattern.compile("\\[\\d+\\]"); - - private Type type; - - private String scope; - - private List condtions; - - private List convergences; - - private String msgTemplate; - - private Map action = Collections.emptyMap(); - - private List context = Collections.emptyList(); - - private List instances = Collections.emptyList(); - - private long maxRange = 0; - - private String name; - - public NotifyStrategy() { - } - - public NotifyStrategy(String name, String scope, List context, Map action, - List instances, String msgTemplate, List convergences) { - this.name = name; - this.scope = scope; - if (context != null && context.size() != 0) { - this.context = context; - } - if (action != null && action.size() != 0) { - this.action = action; - } - if (instances != null && instances.size() != 0) { - this.instances = instances; - } - this.convergences = convergences; - this.msgTemplate = msgTemplate; - } - - public void setConditions(List conditions, List relations) { - - int idx = 0; // expression count - List exprs = new ArrayList<>(); - for (Object o : conditions) { - - // condition is simple string: "arg>123" - if (String.class.isAssignableFrom(o.getClass())) { - Expression expression = new Expression((String) o); - expression.setIdx(idx++); - exprs.add(expression); - } - else { - @SuppressWarnings("unchecked") - Map cond = (Map) o; - Expression expression; - if (cond.get("type") == null || cond.get("type").equals(Type.STREAM.name)) { - String expr = (String) cond.get("expr"); - String func = (String) cond.get("func"); - Long range = cond.get("range") == null ? null : Long.valueOf(cond.get("range").toString()); - Float sampling = cond.get("sampling") == null ? null - : Float.valueOf(cond.get("sampling").toString()); - expression = new Expression(expr, func, range, sampling); - } - else { - String metricPrefix = name.substring(name.indexOf('@') + 1, name.lastIndexOf('@')); - cond.put("metric", metricPrefix + "." + cond.get("metric")); - expression = new Expression(cond); - this.type = Type.TIMER; - } - expression.setIdx(idx++); - exprs.add(expression); - } - } - - idx = 1; // reuse for condition count, start from 1 - List conds = null; - if (relations == null || relations.isEmpty()) { - conds = new ArrayList<>(conditions.size()); - - for (Expression expr : exprs) { - conds.add(new Condition(idx++, expr)); - } - } - else { - conds = new ArrayList<>(relations.size()); - for (String relation : relations) { - - Matcher m = INDEX_PATTERN.matcher(relation); - Set set = new HashSet<>(); - while (m.find()) { - String idxHolder = m.group(); - int i = Integer.parseInt(idxHolder.substring(1, idxHolder.length() - 1)); - if (i >= exprs.size()) { // IndexOutOfBoundsException - continue; - } - set.add(exprs.get(i)); - relation = relation.replace(idxHolder, "{" + i + "}"); // temp i - } - - List list = new ArrayList<>(set); - for (int i = 0; i < list.size(); i++) { - relation = relation.replace("{" + list.get(i).getIdx() + "}", "[" + i + "]"); - } - conds.add(new Condition(idx++, list, relation)); - } - } - - this.condtions = conds; - - /** init max range */ - for (Condition cond : this.condtions) { - for (Expression expr : cond.expressions) { - maxRange = Math.max(maxRange, expr.range); - } - } - - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public static NotifyStrategy parse(String name, String json) { - - Map m = JSONHelper.toObject(json, Map.class); - String scope = (String) m.get("scope"); - List context = (List) m.get("context"); - List conditions = (List) m.get("conditions"); - List relations = (List) m.get("relations"); - List convergences = (List) m.get("convergences"); - Map action = (Map) m.get("action"); - String msgTemplate = (String) m.get("msgTemplate"); - List instances = (List) m.get("instances"); - - NotifyStrategy stra = new NotifyStrategy(name, scope, context, action, instances, msgTemplate, convergences); - - stra.setConditions(conditions, relations); - - return stra; - } - - public long getMaxRange() { - - return maxRange; - } - - public String getMsgTemplate() { - - return msgTemplate; - } - - public void setMsgTemplate(String msgTemplate) { - - this.msgTemplate = msgTemplate; - } - - public Map getAction() { - - return action; - } - - public void setAction(Map action) { - - this.action = action; - } - - public List getContext() { - - return context; - } - - public void setContext(List context) { - - this.context = context; - } - - public String getScope() { - - return scope; - } - - public void setScope(String scope) { - - this.scope = scope; - } - - public List getInstances() { - - return instances; - } - - public void setInstances(List instances) { - - this.instances = instances; - } - - public String getName() { - - return name; - } - - public Type getType() { - - return type; - } - - public List getCondtions() { - - return condtions; - } - - public List getConvergences() { - - return convergences; - } - - protected static class Expression { - - private int idx; - private Type type; - private String arg; - private String operator; - private String expectedValue; - private long range = 0; - private String func; - private float sampling = 1; - - private Set matchArgExpr = new HashSet(); - - private long time_from; - private long time_to; - private long interval; - private int unit; - private String upperLimit; - private String lowerLimit; - - public Expression(String exprStr) { - for (String op : OPERATORS) { - if (exprStr.contains(op)) { - String[] exprs = exprStr.split(op); - this.arg = exprs[0].trim(); - - // suport * as a match - initMatchArgExpr(); - - this.operator = op; - this.expectedValue = exprs[1]; - break; - } - } - this.type = Type.STREAM; - } - - public Expression(String exprStr, String func, Long range, Float sampling) { - this(exprStr); - if (range != null && range > 0) { - this.range = range * 1000; // second to ms - } - this.func = func; - if (sampling != null) { - this.sampling = sampling; - } - - } - - public Expression(Map cond) { - - this.arg = (String) cond.get("metric"); - this.unit = Integer.parseInt((String) cond.get("unit")); - this.time_from = DateTimeHelper - .dateFormat(DateTimeHelper.getToday("yyyy-MM-dd") + " " + cond.get("time_from"), "yyyy-MM-dd HH:mm") - .getTime(); - this.time_to = DateTimeHelper - .dateFormat(DateTimeHelper.getToday("yyyy-MM-dd") + " " + cond.get("time_to"), "yyyy-MM-dd HH:mm") - .getTime(); - if (cond.get("interval") != null) { - long interval = Long.parseLong((String) cond.get("interval")); - switch (unit) { - case DateTimeHelper.INTERVAL_DAY: - interval = interval * 24 * 3600 * 1000; - break; - case DateTimeHelper.INTERVAL_HOUR: - interval = interval * 3600 * 1000; - break; - case DateTimeHelper.INTERVAL_MINUTE: - interval = interval * 60000; - break; - } - this.interval = interval; - } - - this.upperLimit = (String) cond.get("upperLimit"); - this.lowerLimit = (String) cond.get("lowerLimit"); - this.func = (String) cond.get("aggr"); - this.type = Type.TIMER; - } - - private void initMatchArgExpr() { - - if (this.arg.indexOf("*") > -1) { - String[] tmps = this.arg.split("\\*"); - for (String tmp : tmps) { - matchArgExpr.add(tmp); - } - } - } - - public boolean isMatchExpr() { - - return matchArgExpr.size() > 0; - } - - public Set matchTargetArgs(Set srcArgs) { - - Set targetArgs = new HashSet(); - - for (String arg : srcArgs) { - - int matchCount = 0; - for (String matchField : this.matchArgExpr) { - - if (arg.indexOf(matchField) > -1) { - matchCount++; - } - } - - if (matchCount == this.matchArgExpr.size()) { - targetArgs.add(arg); - } - } - - return targetArgs; - } - - public String getHashCode() { - - return EncodeHelper.encodeMD5(arg + func + lowerLimit + upperLimit + time_from + time_to + interval + unit); - } - - public String getArg() { - - return arg; - } - - public String getOperator() { - - return operator; - } - - public String getExpectedValue() { - - return expectedValue; - } - - public long getRange() { - - return range; - } - - public String getFunc() { - - return func; - } - - public float getSampling() { - - return sampling; - } - - public int getIdx() { - - return idx; - } - - public Type getType() { - - return type; - } - - public long getTime_from() { - - return time_from; - } - - public long getTime_to() { - - return time_to; - } - - public long getInterval() { - - return interval; - } - - public String getUpperLimit() { - - return upperLimit; - } - - public String getLowerLimit() { - - return lowerLimit; - } - - public int getUnit() { - - return unit; - } - - public void setIdx(int idx) { - - this.idx = idx; - } - - } - - protected class Condition { - - private int index; - private List expressions; - private String relation; - - public Condition(int index, Expression expr) { - this.index = index; - List exprs = new ArrayList<>(1); - exprs.add(expr); - this.expressions = exprs; - } - - public Condition(int index, List exprs, String relation) { - this.index = index; - this.expressions = exprs; - this.relation = relation; - } - - public int getIndex() { - - return index; - } - - public List getExpressions() { - - return expressions; - } - - public String getRelation() { - - return relation; - } - - } - -} +/*- + * << + * UAVStack + * == + * Copyright (C) 2016 - 2017 UAVStack + * == + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * >> + */ + +package com.creditease.uav.feature.runtimenotify; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.alibaba.fastjson.JSONArray; +import com.creditease.agent.helpers.DateTimeHelper; +import com.creditease.agent.helpers.EncodeHelper; +import com.creditease.agent.helpers.JSONHelper; + +/** + * notify strategy ds + */ +public class NotifyStrategy { + + public enum Type { + STREAM("stream"), TIMER("timer"); + + private String name; + + Type(String name) { + this.name = name; + } + + @Override + public String toString() { + + return name; + } + } + + private static final String[] OPERATORS = { ":=", "!=", ">", "<", "=" }; + + private static final Pattern INDEX_PATTERN = Pattern.compile("\\[\\d+\\]"); + + private Type type; + + private String scope; + + private List condtions; + + private List convergences; + + private String msgTemplate; + + private Map action = Collections.emptyMap(); + + private List context = Collections.emptyList(); + + private List instances = Collections.emptyList(); + + private long maxRange = 0; + + private String name; + + public NotifyStrategy() { + } + + public NotifyStrategy(String name, String scope, List context, Map action, + List instances, String msgTemplate, List convergences) { + this.name = name; + this.scope = scope; + if (context != null && context.size() != 0) { + this.context = context; + } + if (action != null && action.size() != 0) { + this.action = action; + } + if (instances != null && instances.size() != 0) { + this.instances = instances; + } + this.convergences = convergences; + this.msgTemplate = msgTemplate; + } + + public void setConditions(List conditions, List relations) { + + int idx = 0; // expression count + List exprs = new ArrayList<>(); + for (Object o : conditions) { + + // condition is simple string: "arg>123" + if (String.class.isAssignableFrom(o.getClass())) { + Expression expression = new Expression((String) o); + expression.setIdx(idx++); + exprs.add(expression); + } + else { + @SuppressWarnings("unchecked") + Map cond = (Map) o; + Expression expression; + if (cond.get("type") == null || cond.get("type").equals(Type.STREAM.name)) { + String expr = (String) cond.get("expr"); + String func = (String) cond.get("func"); + Long range = cond.get("range") == null ? null : Long.valueOf(cond.get("range").toString()); + Float sampling = cond.get("sampling") == null ? null + : Float.valueOf(cond.get("sampling").toString()); + expression = new Expression(expr, func, range, sampling); + } + else { + String metricPrefix = name.substring(name.indexOf('@') + 1, name.lastIndexOf('@')); + cond.put("metric", metricPrefix + "." + cond.get("metric")); + expression = new Expression(cond); + this.type = Type.TIMER; + } + expression.setIdx(idx++); + exprs.add(expression); + } + } + + idx = 1; // reuse for condition count, start from 1 + List conds = null; + if (relations == null || relations.isEmpty()) { + conds = new ArrayList<>(conditions.size()); + + for (Expression expr : exprs) { + conds.add(new Condition(idx++, expr)); + } + } + else { + conds = new ArrayList<>(relations.size()); + for (String relation : relations) { + + Matcher m = INDEX_PATTERN.matcher(relation); + Set set = new HashSet<>(); + while (m.find()) { + String idxHolder = m.group(); + int i = Integer.parseInt(idxHolder.substring(1, idxHolder.length() - 1)); + if (i >= exprs.size()) { // IndexOutOfBoundsException + continue; + } + set.add(exprs.get(i)); + relation = relation.replace(idxHolder, "{" + i + "}"); // temp i + } + + List list = new ArrayList<>(set); + for (int i = 0; i < list.size(); i++) { + relation = relation.replace("{" + list.get(i).getIdx() + "}", "[" + i + "]"); + } + conds.add(new Condition(idx++, list, relation)); + } + } + + this.condtions = conds; + + /** init max range */ + for (Condition cond : this.condtions) { + for (Expression expr : cond.expressions) { + maxRange = Math.max(maxRange, expr.range); + } + } + + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static NotifyStrategy parse(String name, String json) { + + Map m = JSONHelper.toObject(json, Map.class); + String scope = (String) m.get("scope"); + List context = (List) m.get("context"); + List conditions = (List) m.get("conditions"); + List relations = (List) m.get("relations"); + List convergences = (List) m.get("convergences"); + Map action = (Map) m.get("action"); + String msgTemplate = (String) m.get("msgTemplate"); + List instances = (List) m.get("instances"); + + NotifyStrategy stra = new NotifyStrategy(name, scope, context, action, instances, msgTemplate, convergences); + + stra.setConditions(conditions, relations); + + return stra; + } + + public long getMaxRange() { + + return maxRange; + } + + public String getMsgTemplate() { + + return msgTemplate; + } + + public void setMsgTemplate(String msgTemplate) { + + this.msgTemplate = msgTemplate; + } + + public Map getAction() { + + return action; + } + + public void setAction(Map action) { + + this.action = action; + } + + public List getContext() { + + return context; + } + + public void setContext(List context) { + + this.context = context; + } + + public String getScope() { + + return scope; + } + + public void setScope(String scope) { + + this.scope = scope; + } + + public List getInstances() { + + return instances; + } + + public void setInstances(List instances) { + + this.instances = instances; + } + + public String getName() { + + return name; + } + + public Type getType() { + + return type; + } + + public List getCondtions() { + + return condtions; + } + + public List getConvergences() { + + return convergences; + } + + protected static class Expression { + + private int idx; + private Type type; + private String arg; + private String operator; + private String expectedValue; + private long range = 0; + private String func; + private float sampling = 1; + private String downsample; + private Boolean[] weekdayLimit=new Boolean[] {true,true,true,true,true,true,true}; + + private Set matchArgExpr = new HashSet(); + + private long time_from; + private long time_to; + private long interval; + private int unit; + private String upperLimit; + private String lowerLimit; + private String time_end; + private String time_start; + private String day_start; + private String day_end; + + public Expression(String exprStr) { + for (String op : OPERATORS) { + if (exprStr.contains(op)) { + String[] exprs = exprStr.split(op); + this.arg = exprs[0].trim(); + + // suport * as a match + initMatchArgExpr(); + + this.operator = op; + this.expectedValue = exprs[1]; + break; + } + } + this.type = Type.STREAM; + } + + public Expression(String exprStr, String func, Long range, Float sampling) { + this(exprStr); + if (range != null && range > 0) { + this.range = range * 1000; // second to ms + } + this.func = func; + if (sampling != null) { + this.sampling = sampling; + } + + } + + public Expression(Map cond) { + + this.arg = (String) cond.get("metric"); + this.unit = Integer.parseInt((String) cond.get("unit")); + this.time_from = DateTimeHelper + .dateFormat(DateTimeHelper.getToday("yyyy-MM-dd") + " " + cond.get("time_from"), "yyyy-MM-dd HH:mm") + .getTime(); + this.time_to = DateTimeHelper + .dateFormat(DateTimeHelper.getToday("yyyy-MM-dd") + " " + cond.get("time_to"), "yyyy-MM-dd HH:mm") + .getTime(); + + this.time_start=(String) cond.get("time_start"); + + this.time_end= (String) cond.get("time_end"); + + this.day_start=(String) cond.get("day_start"); + + this.day_end= (String) cond.get("day_end"); + + if(cond.containsKey("weekdayLimit")) { + ((JSONArray)cond.get("weekdayLimit")).toArray(this.weekdayLimit); + } + + if (cond.get("interval") != null) { + long interval = Long.parseLong((String) cond.get("interval")); + switch (unit) { + case DateTimeHelper.INTERVAL_DAY: + interval = interval * 24 * 3600 * 1000; + break; + case DateTimeHelper.INTERVAL_HOUR: + interval = interval * 3600 * 1000; + break; + case DateTimeHelper.INTERVAL_MINUTE: + interval = interval * 60000; + break; + } + this.interval = interval; + } + + this.upperLimit = (String) cond.get("upperLimit"); + this.lowerLimit = (String) cond.get("lowerLimit"); + this.func = (String) cond.get("aggr"); + this.downsample=(String) cond.get("downsample"); + this.type = Type.TIMER; + } + + private void initMatchArgExpr() { + + if (this.arg.indexOf("*") > -1) { + String[] tmps = this.arg.split("\\*"); + for (String tmp : tmps) { + matchArgExpr.add(tmp); + } + } + } + + public boolean isMatchExpr() { + + return matchArgExpr.size() > 0; + } + + public Set matchTargetArgs(Set srcArgs) { + + Set targetArgs = new HashSet(); + + for (String arg : srcArgs) { + + int matchCount = 0; + for (String matchField : this.matchArgExpr) { + + if (arg.indexOf(matchField) > -1) { + matchCount++; + } + } + + if (matchCount == this.matchArgExpr.size()) { + targetArgs.add(arg); + } + } + + return targetArgs; + } + + public String getHashCode() { + + return EncodeHelper.encodeMD5(arg + func + lowerLimit + upperLimit + time_from + time_to + interval + unit); + } + + public String getArg() { + + return arg; + } + + public String getOperator() { + + return operator; + } + + public String getExpectedValue() { + + return expectedValue; + } + + public long getRange() { + + return range; + } + + public String getFunc() { + + return func; + } + + public float getSampling() { + + return sampling; + } + + public int getIdx() { + + return idx; + } + + public Type getType() { + + return type; + } + + public long getTime_from() { + + return time_from; + } + + public long getTime_to() { + + return time_to; + } + + public long getInterval() { + + return interval; + } + + public String getUpperLimit() { + + return upperLimit; + } + + public String getLowerLimit() { + + return lowerLimit; + } + + public int getUnit() { + + return unit; + } + + public void setIdx(int idx) { + + this.idx = idx; + } + + public String getTime_end() { + + return time_end; + } + + public String getTime_start() { + + return time_start; + } + + public String getDownsample() { + + return downsample; + } + + public String getDay_start() { + + return day_start; + } + + public String getDay_end() { + + return day_end; + } + + public Boolean[] getWeekdayLimit() { + + return weekdayLimit; + } + + } + + protected class Condition { + + private int index; + private List expressions; + private String relation; + + public Condition(int index, Expression expr) { + this.index = index; + List exprs = new ArrayList<>(1); + exprs.add(expr); + this.expressions = exprs; + } + + public Condition(int index, List exprs, String relation) { + this.index = index; + this.expressions = exprs; + this.relation = relation; + } + + public int getIndex() { + + return index; + } + + public List getExpressions() { + + return expressions; + } + + public String getRelation() { + + return relation; + } + + } + +} diff --git a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/StrategyJudgement.java b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/StrategyJudgement.java index 78542f67..3615fb7c 100644 --- a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/StrategyJudgement.java +++ b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/StrategyJudgement.java @@ -57,12 +57,30 @@ public class StrategyJudgement extends AbstractComponent { readable.put("all-max", "最大"); readable.put("all-min", "最小"); readable.put("all-sum", "总和"); + readable.put("all-count", "计数"); + readable.put("all-dev", "标准差"); + readable.put("all-first", "开始"); + readable.put("all-last", "末尾"); + readable.put("all-p50", "50th百分位数"); + readable.put("all-p75", "75th百分位数"); + readable.put("all-p90", "90th百分位数"); + readable.put("all-p95", "95th百分位数"); + readable.put("all-p99", "99th百分位数"); + readable.put("all-p999", "999th百分位数"); + readable.put("avg", "平均"); readable.put("max", "最大"); readable.put("min", "最小"); readable.put("sum", "总和"); readable.put("diff", "差"); readable.put("count", "计数"); + readable.put("dev", "标准差"); + readable.put("p50", "50th百分位数"); + readable.put("p75", "75th百分位数"); + readable.put("p90", "90th百分位数"); + readable.put("p95", "95th百分位数"); + readable.put("p99", "99th百分位数"); + readable.put("p999", "999th百分位数"); } private CacheManager cm; @@ -248,10 +266,14 @@ private void judgeTimerExpression(ConditionResult cr, NotifyStrategy.Expression if (judgeResult == null) { judgeResult = new HashMap(); judgeResult.put("fire", false); + }else { + log.debug(this, "judgeTimerExpression judgeResult:" + JSONHelper.toString(judgeResult)); } + Map args = slice.getArgs(); + // if the judge is called by slice stream, just return the last result - if (slice.getKey().indexOf('@') > -1) { + if (args == null || !"timer".equals(args.get("creater"))) { if (judgeResult.get("time_to") != null) { Date date = DateTimeHelper.dateFormat(String.valueOf(judgeResult.get("time_to")), "yyyy-MM-dd HH:mm"); // if the time is not the time expr's judge time,return false @@ -275,12 +297,66 @@ && isOverdue(DateTimeHelper } else if (timeMap != null) { caculateJudgeResult(timeMap, judgeResult, slice.getKey(), expr, cr); + + if((Boolean) judgeResult.get("fire")) { + //add detail info + addDetail(timeMap,slice,expr); + } } - } + } cr.addTimerExprResult((Boolean) judgeResult.get("fire"), expr, judgeResult); } + + private void addDetail(Map timeMap, Slice slice, Expression expr) { + + + Map args=slice.getArgs(); + + String metric=expr.getArg(); + + if(args.containsKey("currentDetailValue_"+metric)) { + return; + } + + Map currentDetailValue = queryDetailValue(slice.getKey(),expr,timeMap.get("time_from"),timeMap.get("time_to")); + + Map lastDetailValue = queryDetailValue(slice.getKey(),expr,timeMap.get("last_time_from"),timeMap.get("last_time_to")); + + args.put("currentDetailValue_"+metric, currentDetailValue); + + args.put("lastDetailValue_"+metric, lastDetailValue); + } + + @SuppressWarnings("rawtypes") + private Map queryDetailValue(String instance, Expression expr, Long startTime, Long endTime) { + + Map detail = new LinkedHashMap(); + + String data = buildQueryJSON(instance,expr,startTime,endTime,true); + + List resultList = queryOpentsdb(data); + + if(resultList==null) { + return detail; + } + + for(Map result:resultList) { + + String instid=String.valueOf(((Map)result.get("tags")).get("instid")); + + for(Object value:((Map)result.get("dps")).values()) { + + detail.put(instid, String.valueOf(value)); + + break; + } + } + + return detail; + + } private void caculateJudgeResult(Map timeMap, Map judgeResult, String instance, Expression expr, ConditionResult cr) { @@ -291,19 +367,23 @@ private void caculateJudgeResult(Map timeMap, Map return; } - Double currentValue = queryOpentsdb(instance, expr.getArg(), expr.getFunc(), timeMap.get("time_from"), + Double currentValue = queryValue(instance, expr, timeMap.get("time_from"), timeMap.get("time_to")); Double lastValue = 0.0; + if ((expr.getLowerLimit().contains("#") || expr.getLowerLimit().contains("*")) + && (expr.getUpperLimit().contains("#") || expr.getUpperLimit().contains("*"))) { + // do nothing + } // if the last judgeResult is really the last judgeTime's result, use it's currentValue as lastValue. - if (judgeResult.get("time_to") != null + else if (judgeResult.get("time_to") != null && judgeResult.get("time_to") .equals(DateTimeHelper.toFormat("yyyy-MM-dd HH:mm", timeMap.get("last_time_to"))) && judgeResult.get("currentValue") != null) { lastValue = Double.parseDouble(String.valueOf(judgeResult.get("currentValue"))); } else { - lastValue = queryOpentsdb(instance, expr.getArg(), expr.getFunc(), timeMap.get("last_time_from"), + lastValue = queryValue(instance, expr, timeMap.get("last_time_from"), timeMap.get("last_time_to")); } @@ -346,68 +426,83 @@ private boolean caculate(double currentValue, double lastValue, NotifyStrategy.E boolean result = false; - String limitString = null; - double diff = currentValue - lastValue; - String prefix = (diff > 0) ? "" : "-"; - - diff = (diff > 0) ? diff : 0 - diff; + String limitString = null; - limitString = (diff >= 0) ? expr.getUpperLimit() : expr.getLowerLimit(); + String upperLimitString = expr.getUpperLimit(); + String lowerLimitString = expr.getLowerLimit(); + // 增幅or降幅 + String upperORlower = ""; + double upperLimit = 0; + double lowerLimit = 0; + // get upperLimit + if (upperLimitString.contains("#")) { + upperLimit = Double.parseDouble(upperLimitString.substring(upperLimitString.indexOf('#') + 1)); + } + else if (upperLimitString.contains("%")) { + upperLimit = Double.parseDouble(upperLimitString.substring(0, upperLimitString.indexOf('%'))); + diff = diff * 100 / lastValue; + } + else if (!upperLimitString.contains("*")) { + upperLimit = Double.parseDouble(upperLimitString); + } - double limit; - String suffix = ""; - if (limitString.endsWith("%")) { - limit = Double.parseDouble(limitString.substring(0, limitString.length() - 1)); + // get lowerLimit + if (lowerLimitString.contains("#")) { + lowerLimit = 0 - Double.parseDouble(lowerLimitString.substring(lowerLimitString.indexOf('#') + 1)); + } + else if (lowerLimitString.contains("%")) { + lowerLimit = Double.parseDouble(lowerLimitString.substring(0, lowerLimitString.indexOf('%'))); diff = diff * 100 / lastValue; - suffix = "%"; } - else { - limit = Double.parseDouble(limitString); + else if (!lowerLimitString.contains("*")) { + lowerLimit = Double.parseDouble(lowerLimitString); } - if (!"-1".equals(limitString) && diff > limit) { + if (!upperLimitString.contains("*") && diff > upperLimit) { + result = true; + upperORlower = "upper"; + limitString = upperLimitString; + } + else if (!lowerLimitString.contains("*") && diff < 0 - lowerLimit) { result = true; + upperORlower = "lower"; + limitString = lowerLimitString; } - judgeResult.put("actualValue", prefix + String.format("%.2f", diff) + suffix); + judgeResult.put("actualValue", String.format("%.2f", diff) + (limitString.contains("%") ? "%" : "")); judgeResult.put("expectedValue", limitString); - + judgeResult.put("upperORlower", upperORlower); return result; } - @SuppressWarnings({ "unchecked", "rawtypes" }) - private Double queryOpentsdb(String instance, String metric, String func, Long startTime, Long endTime) { + @SuppressWarnings({"rawtypes" }) + private Double queryValue(String instance, Expression expr, Long startTime, Long endTime) { Double result = null; - for (int i = 0; i < 3 && result == null; i++) { + for (int i = 0; i < 3; i++) { - try { - UAVHttpMessage message = new UAVHttpMessage(); + try { - String data = String.format( - "{\"start\":%d,\"end\":%d,\"queries\":[{\"aggregator\":\"avg\",\"downsample\":\"%s\",\"metric\":\"%s\",\"filters\":[{\"filter\":\"%s\",\"tagk\":\"instid\",\"type\":\"regexp\",\"groupBy\":false}]}]}", - startTime, endTime, func, metric, - instance.replace(":", "/u003a").replace("%", "/u0025").replace("#", "/u0023")); - message.putRequest("opentsdb.query.json", data); - message.putRequest("datastore.name", MonitorDataFrame.MessageType.Monitor.toString()); + String data = buildQueryJSON(instance,expr,startTime,endTime,false); - String queryResponse = String.valueOf(invoker.invoke(queryServiceName, message, String.class)); - - if (queryResponse.equals("null") || queryResponse.equals("{}") - || queryResponse.equals("{\"rs\":\"[]\"}")) { + List resultList = queryOpentsdb(data); + + if(resultList==null) { continue; } - - Map responseMap = JSONHelper.toObject(queryResponse, Map.class); - - List rsList = JSONHelper.toObjectArray((String) responseMap.get(UAVHttpMessage.RESULT), Map.class); - - for (Object value : ((Map) rsList.get(0).get("dps")).values()) { + + for (Object value : ((Map) resultList.get(0).get("dps")).values()) { + result = ((BigDecimal) value).doubleValue(); - } + + if(result!=null) { + return result; + } + } + } catch (Exception e) { log.err(this, "TimerExpression judgement query opentsdb failed ", e); @@ -416,6 +511,38 @@ private Double queryOpentsdb(String instance, String metric, String func, Long s return result; } + @SuppressWarnings({ "unchecked", "rawtypes" }) + private List queryOpentsdb(String data) { + + UAVHttpMessage message = new UAVHttpMessage(); + + message.putRequest("opentsdb.query.json", data); + message.putRequest("datastore.name", MonitorDataFrame.MessageType.Monitor.toString()); + + String queryResponse = String.valueOf(invoker.invoke(queryServiceName, message, String.class)); + + if (queryResponse.equals("null") || queryResponse.equals("{}") + || queryResponse.equals("{\"rs\":\"[]\"}")) { + return null; + } + + Map responseMap = JSONHelper.toObject(queryResponse, Map.class); + + List rsList = JSONHelper.toObjectArray((String) responseMap.get(UAVHttpMessage.RESULT), Map.class); + + return rsList; + } + + private String buildQueryJSON(String instance, Expression expr, Long startTime, Long endTime, boolean groupBy) { + + String data=String.format( + "{\"start\":%d,\"end\":%d,\"queries\":[{\"aggregator\":\"%s\",\"downsample\":\"%s\",\"metric\":\"%s\",\"filters\":[{\"filter\":\"%s\",\"tagk\":\"instid\",\"type\":\"regexp\",\"groupBy\":%b}]}]}", + startTime, endTime, expr.getFunc(), expr.getDownsample(), expr.getArg(), + instance.replace(":", "/u003a").replace("%", "/u0025").replace("#", "/u0023"),groupBy); + + return data; + } + /** * get judgeResult from redis */ @@ -441,6 +568,11 @@ private Map getJudgeResult(String instance, Expression expr) { * else return null; */ private Map getJudgeTime(Expression expr, long time) { + + + if (!inTimeScope(expr, time)) { + return null; + } Map timeMap = new HashMap(); long time_to = time; @@ -494,6 +626,48 @@ private Map getJudgeTime(Expression expr, long time) { return timeMap; } + + /** + * return true if the time is in judge time scope + */ + private boolean inTimeScope(Expression expr, long time) { + + String time_start = expr.getTime_start(); + String time_end = expr.getTime_end(); + String day_start = expr.getDay_start(); + String day_end = expr.getDay_end(); + + if (!StringHelper.isEmpty(day_start) && !StringHelper.isEmpty(day_end)) { + + long startTime = DateTimeHelper.dateFormat(day_start, "yyyy-MM-dd").getTime(); + long endTime = DateTimeHelper.dateFormat(day_end, "yyyy-MM-dd").getTime(); + + if (time < startTime || time >= endTime + 24 * 3600 * 1000) { + return false; + } + } + + if (!StringHelper.isEmpty(time_start) && !StringHelper.isEmpty(time_end)) { + + long startTime = DateTimeHelper + .dateFormat(DateTimeHelper.getToday("yyyy-MM-dd") + " " + time_start, "yyyy-MM-dd HH:mm").getTime(); + long endTime = DateTimeHelper + .dateFormat(DateTimeHelper.getToday("yyyy-MM-dd") + " " + time_end, "yyyy-MM-dd HH:mm").getTime(); + + if (time < startTime || time >= endTime) { + return false; + } + } + + int weekday = DateTimeHelper.getWeekday(new Date(time)); + + if(expr.getWeekdayLimit()!=null&&!expr.getWeekdayLimit()[weekday]) { + return false; + } + + return true; + } + private List rangeSlices(List slices, Slice cur, long range) { @@ -637,13 +811,33 @@ private String makeReadableString(Map m) { } else if (NotifyStrategy.Type.TIMER.toString().equals(m.get("type"))) { - description = ("true".equals(m.get("fire"))) ? String.format( - "%s在%s至%s时间段的%s值%s比%s至%s%s超过%s,当前值:%s。上期值:%s,本期值:%s", m.get("metric"), m.get("time_from"), - m.get("time_to"), readable.get(m.get("func")), m.get("tag"), m.get("last_time_from"), - m.get("last_time_to"), (m.get("actualValue").contains("-")) ? "降幅" : "增幅", - m.get("expectedValue"), - (m.get("actualValue").contains("-")) ? m.get("actualValue").substring(1) : m.get("actualValue"), - m.get("lastValue"), m.get("currentValue")) : "false"; + if (m.get("expectedValue").contains("#")) { + double expectedValue = Double + .parseDouble(m.get("expectedValue").substring(m.get("expectedValue").indexOf('#') + 1)); + double actualValue = Double.parseDouble(m.get("actualValue")); + description = ("true".equals(m.get("fire"))) ? String.format("%s在%s至%s时间段的%s值%s%s,当前值:%s。", + m.get("metric"), m.get("time_from"), m.get("time_to"), readable.get(m.get("downsample")), + (actualValue > expectedValue) ? ">" : "<", String.valueOf(expectedValue), + String.valueOf(actualValue)) : "false"; + } + else { + description = ("true".equals(m.get("fire"))) ? String.format( + "%s在%s至%s时间段的%s值%s比%s至%s%s%s%s,当前值:%s。上期值:%s,本期值:%s", m.get("metric"), m.get("time_from"), + m.get("time_to"), readable.get(m.get("downsample")), m.get("tag"), m.get("last_time_from"), + m.get("last_time_to"), + (m.get("upperORlower").equals("upper") && !m.get("expectedValue").contains("-")) + || (m.get("upperORlower").equals("lower") && m.get("expectedValue").contains("-")) + ? "增幅" + : "降幅", + m.get("expectedValue").contains("-") ? "低于" : "超过", + (m.get("expectedValue").contains("-")) ? m.get("expectedValue").substring(1) + : m.get("expectedValue"), + (m.get("upperORlower").equals("upper") && m.get("expectedValue").contains("-")) + || (m.get("upperORlower").equals("lower") && !m.get("expectedValue").contains("-")) + ? String.valueOf(0 - Double.parseDouble(m.get("actualValue"))) + : m.get("actualValue"), + m.get("lastValue"), m.get("currentValue")) : "false"; + } } return description; @@ -683,6 +877,7 @@ public void addTimerExprResult(boolean result, NotifyStrategy.Expression expr, M m.put("tag", expr.getInterval() == 0 ? "同" : "环"); m.put("metric", expr.getArg().substring(expr.getArg().indexOf('.') + 1)); m.put("func", expr.getFunc()); + m.put("downsample", expr.getDownsample()); m.put("type", NotifyStrategy.Type.TIMER.toString()); addExprResult(idx++, result, m); } diff --git a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/task/JudgeNotifyTimerTask.java b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/task/JudgeNotifyTimerTask.java index 0a642bd6..08c91657 100644 --- a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/task/JudgeNotifyTimerTask.java +++ b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/task/JudgeNotifyTimerTask.java @@ -1,241 +1,259 @@ -/*- - * << - * UAVStack - * == - * Copyright (C) 2016 - 2017 UAVStack - * == - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * >> - */ - -package com.creditease.uav.feature.runtimenotify.task; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import com.creditease.agent.helpers.JSONHelper; -import com.creditease.agent.helpers.NetworkHelper; -import com.creditease.agent.helpers.StringHelper; -import com.creditease.agent.monitor.api.NotificationEvent; -import com.creditease.uav.cache.api.CacheManager; -import com.creditease.uav.cache.api.CacheManager.CacheLock; -import com.creditease.uav.feature.RuntimeNotifyCatcher; -import com.creditease.uav.feature.runtimenotify.NotifyStrategy; -import com.creditease.uav.feature.runtimenotify.Slice; -import com.creditease.uav.feature.runtimenotify.StrategyJudgement; -import com.creditease.uav.feature.runtimenotify.scheduler.RuntimeNotifyStrategyMgr; - -public class JudgeNotifyTimerTask extends JudgeNotifyCommonTask { - - private NotifyStrategy stra; - private long taskStart = System.currentTimeMillis(); - private long judge_time; - private static final String LOCK_REGION = "lock.region.uav"; - private static final long LOCK_TIMEOUT = 60 * 1000; - private CacheManager cm; - - public JudgeNotifyTimerTask(String name, String feature, long judge_time, NotifyStrategy stra) { - super(name, feature); - this.stra = stra; - this.judge_time = judge_time - judge_time % 60000; - cm = (CacheManager) this.getConfigManager().getComponent(feature, RuntimeNotifyCatcher.CACHE_MANAGER_NAME); - } - - @Override - public void run() { - - CacheLock lock = null; - try { - lock = cm.newCacheLock(LOCK_REGION, stra.getName(), LOCK_TIMEOUT); - - if (!lock.getLock()) { - return; - } - /** - * Step 1:find out instance - */ - for (String instance : stra.getInstances()) { - /** - * Step 2: judge the strategy - */ - - StrategyJudgement judgement = (StrategyJudgement) getConfigManager().getComponent(feature, - "StrategyJudgement"); - Map result = judgement.judge(new Slice(instance, judge_time), stra, null); - - /** - * Step 3: if fire the event, build notification event - */ - if (result != null && !result.isEmpty()) { - NotificationEvent event = this.newNotificationEvent(instance, result, stra.getConvergences()); - - // get context - putContext(event); - - // get action - putNotifyAction(event, stra); - - // get msg tempalte - putNotifyMsg(event, stra); - - if (this.log.isTraceEnable()) { - this.log.info(this, "RuntimeNotify Notification Event Happen: event=" + event.toJSONString()); - } - - this.putNotificationEvent(event); - } - } - - } - catch (Exception e) { - log.err(this, "JudgeNotifyTimerTask" + stra.getName() + " RUN FAIL.", e); - } - finally { - if (lock != null && lock.isLockInHand()) { - lock.releaseLock(); - } - } - - if (log.isDebugEnable()) { - long cost = System.currentTimeMillis() - taskStart; - String detail = cost < 10 ? "" : " detail:strategy=" + JSONHelper.toString(stra); - log.debug(this, "whole task lifecycle COST: (" + cost + ")ms" + detail); - } - } - - /** - * get context - * - * TODO: we need support context param in strategy - */ - private void putContext(NotificationEvent event) { - - } - - /** - * newNotificationEvent - * - * - * @return - */ - private NotificationEvent newNotificationEvent(String instance, Map result, List convergences) { - - String ip = instance; - String host = instance; - String appgroup = "UNKNOWN"; - - instance = formatInstance(instance); - - Map infos = getInfoFromSliceCache(instance); - if (infos != null) { - ip = String.valueOf(infos.get("ip")); - host = String.valueOf(infos.get("host")); - appgroup = String.valueOf(infos.get("appgroup")); - } - - StringBuilder desc = new StringBuilder(); - List conditionIndex = new ArrayList(); - - for (Map.Entry cause : result.entrySet()) { - // description - desc.append(instance + "触发条件[" + cause.getKey() + "]:").append(cause.getValue()).append("\r\n"); - // condition index - conditionIndex.add(cause.getKey()); - } - - String title = ip + "[" + instance + "]触发" + result.size() + "个报警(条件序号: " + conditionIndex.toString().replaceAll("\\[|]|,", "") + ")"; - - // fix  (\u00A0) can be shown in email - String description = desc.toString().replace('\u00A0', ' '); - - NotificationEvent ne = new NotificationEvent(NotificationEvent.EVENT_RT_ALERT_THRESHOLD, title, description, - judge_time, ip, host); - - // add appgroup - ne.addArg("appgroup", appgroup); - - // 兼容不存在convergences属性的旧预警策略 - if(convergences == null || convergences.size() == 0 ) { - return ne; - } - - // 同一个Event由多个策略触发时,梯度收敛以最长的为准 - String conv = obtainConvergenceForEvent(convergences, conditionIndex); - if(!StringHelper.isEmpty(conv)) { - ne.addArg("convergences", conv); - ne.addArg(NotificationEvent.EVENT_Tag_NoBlock, "true"); - } - - return ne; - } - - private String formatInstance(String instance) { - - if (NetworkHelper.isIPV4(instance)) { - instance += "_"; - } - instance = stra.getName().substring(0, stra.getName().lastIndexOf('@') + 1) + instance; - - return instance; - } - - private Map getInfoFromSliceCache(String instance) { - - String cacheKey = "SLICE_" + instance + "_"; - for (int index = 0; index < 60; index++) { - String result = cm.lpop(RuntimeNotifyStrategyMgr.UAV_CACHE_REGION, cacheKey + index); - if (result != null) { - Slice s = new Slice(result); - return s.getArgs(); - } - } - - return null; - } - - private void putNotifyAction(NotificationEvent event, NotifyStrategy stra) { - - Map actions = stra.getAction(); - if (actions == null || actions.isEmpty()) { - return; - } - - for (Entry act : actions.entrySet()) { - event.addArg("action_" + act.getKey(), act.getValue()); - } - } - - private void putNotifyMsg(NotificationEvent event, NotifyStrategy stra) { - - String msgTemplate = stra.getMsgTemplate(); - String msg = makeMsgByTemplate(msgTemplate, stra); - - if (msg != null) { - event.addArg("msg", msg); - } - } - - /** - * - * @param template - * @param slice - * @return - */ - private String makeMsgByTemplate(String template, NotifyStrategy stra) { - - return ""; - } - -} +/*- + * << + * UAVStack + * == + * Copyright (C) 2016 - 2017 UAVStack + * == + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * >> + */ + +package com.creditease.uav.feature.runtimenotify.task; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.creditease.agent.helpers.JSONHelper; +import com.creditease.agent.helpers.NetworkHelper; +import com.creditease.agent.helpers.StringHelper; +import com.creditease.agent.monitor.api.NotificationEvent; +import com.creditease.uav.cache.api.CacheManager; +import com.creditease.uav.cache.api.CacheManager.CacheLock; +import com.creditease.uav.feature.RuntimeNotifyCatcher; +import com.creditease.uav.feature.runtimenotify.NotifyStrategy; +import com.creditease.uav.feature.runtimenotify.Slice; +import com.creditease.uav.feature.runtimenotify.StrategyJudgement; +import com.creditease.uav.feature.runtimenotify.scheduler.RuntimeNotifyStrategyMgr; + +public class JudgeNotifyTimerTask extends JudgeNotifyCommonTask { + + private NotifyStrategy stra; + private long taskStart = System.currentTimeMillis(); + private long judge_time; + private static final String LOCK_REGION = "lock.region.uav"; + private static final long LOCK_TIMEOUT = 60 * 1000; + private CacheManager cm; + + public JudgeNotifyTimerTask(String name, String feature, long judge_time, NotifyStrategy stra) { + super(name, feature); + this.stra = stra; + this.judge_time = judge_time - judge_time % 60000; + cm = (CacheManager) this.getConfigManager().getComponent(feature, RuntimeNotifyCatcher.CACHE_MANAGER_NAME); + } + + @Override + public void run() { + + CacheLock lock = null; + try { + lock = cm.newCacheLock(LOCK_REGION, stra.getName(), LOCK_TIMEOUT); + + if (!lock.getLock()) { + return; + } + /** + * Step 1:find out instance + */ + for (String instance : stra.getInstances()) { + /** + * Step 2: judge the strategy + */ + + StrategyJudgement judgement = (StrategyJudgement) getConfigManager().getComponent(feature, + "StrategyJudgement"); + + Slice slice = new Slice(instance, judge_time); + Map args = new HashMap(); + // 标识该slice由TimerTask创建,为同环比创建,非流式计算创建 + args.put("creater", "timer"); + slice.setArgs(args); + + Map result = judgement.judge(slice, stra, null); + + /** + * Step 3: if fire the event, build notification event + */ + if (result != null && !result.isEmpty()) { + NotificationEvent event = this.newNotificationEvent(instance, result, stra.getConvergences()); + + // get context + putContext(slice,event); + + // get action + putNotifyAction(event, stra); + + // get msg tempalte + putNotifyMsg(event, stra); + + if (this.log.isTraceEnable()) { + this.log.info(this, "RuntimeNotify Notification Event Happen: event=" + event.toJSONString()); + } + + this.putNotificationEvent(event); + } + } + + } + catch (Exception e) { + log.err(this, "JudgeNotifyTimerTask" + stra.getName() + " RUN FAIL.", e); + } + finally { + if (lock != null && lock.isLockInHand()) { + lock.releaseLock(); + } + } + + if (log.isDebugEnable()) { + long cost = System.currentTimeMillis() - taskStart; + String detail = cost < 10 ? "" : " detail:strategy=" + JSONHelper.toString(stra); + log.debug(this, "whole task lifecycle COST: (" + cost + ")ms" + detail); + } + } + + /** + * get context + * + * TODO: we need support context param in strategy + */ + private void putContext(Slice slice, NotificationEvent event) { + + Map args = slice.getArgs(); + + for (String key : args.keySet()) { + + Object argVal = args.get(key); + + String jsonstr = JSONHelper.toString(argVal); + + event.addArg(key, jsonstr); + } + } + + /** + * newNotificationEvent + * + * + * @return + */ + private NotificationEvent newNotificationEvent(String instance, Map result, List convergences) { + + String ip = instance; + String host = instance; + String appgroup = "UNKNOWN"; + + instance = formatInstance(instance); + + Map infos = getInfoFromSliceCache(instance); + if (infos != null) { + ip = String.valueOf(infos.get("ip")); + host = String.valueOf(infos.get("host")); + appgroup = String.valueOf(infos.get("appgroup")); + } + + StringBuilder desc = new StringBuilder(); + List conditionIndex = new ArrayList(); + + for (Map.Entry cause : result.entrySet()) { + // description + desc.append(instance + "触发条件[" + cause.getKey() + "]:").append(cause.getValue()).append("\r\n"); + // condition index + conditionIndex.add(cause.getKey()); + } + + String title = ip + "[" + instance + "]触发" + result.size() + "个报警(条件序号: " + conditionIndex.toString().replaceAll("\\[|]|,", "") + ")"; + + // fix  (\u00A0) can be shown in email + String description = desc.toString().replace('\u00A0', ' '); + + NotificationEvent ne = new NotificationEvent(NotificationEvent.EVENT_RT_ALERT_THRESHOLD, title, description, + judge_time, ip, host); + + // add appgroup + ne.addArg("appgroup", appgroup); + + // 兼容不存在convergences属性的旧预警策略 + if(convergences == null || convergences.size() == 0 ) { + return ne; + } + + // 同一个Event由多个策略触发时,梯度收敛以最长的为准 + String conv = obtainConvergenceForEvent(convergences, conditionIndex); + if(!StringHelper.isEmpty(conv)) { + ne.addArg("convergences", conv); + ne.addArg(NotificationEvent.EVENT_Tag_NoBlock, "true"); + } + + return ne; + } + + private String formatInstance(String instance) { + + if (NetworkHelper.isIPV4(instance)) { + instance += "_"; + } + instance = stra.getName().substring(0, stra.getName().lastIndexOf('@') + 1) + instance; + + return instance; + } + + private Map getInfoFromSliceCache(String instance) { + + String cacheKey = "SLICE_" + instance + "_"; + for (int index = 0; index < 60; index++) { + String result = cm.lpop(RuntimeNotifyStrategyMgr.UAV_CACHE_REGION, cacheKey + index); + if (result != null) { + Slice s = new Slice(result); + return s.getArgs(); + } + } + + return null; + } + + private void putNotifyAction(NotificationEvent event, NotifyStrategy stra) { + + Map actions = stra.getAction(); + if (actions == null || actions.isEmpty()) { + return; + } + + for (Entry act : actions.entrySet()) { + event.addArg("action_" + act.getKey(), act.getValue()); + } + } + + private void putNotifyMsg(NotificationEvent event, NotifyStrategy stra) { + + String msgTemplate = stra.getMsgTemplate(); + String msg = makeMsgByTemplate(msgTemplate, stra); + + if (msg != null) { + event.addArg("msg", msg); + } + } + + /** + * + * @param template + * @param slice + * @return + */ + private String makeMsgByTemplate(String template, NotifyStrategy stra) { + + return ""; + } + +} diff --git a/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/DateTimeHelper.java b/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/DateTimeHelper.java index c8b35dd5..705a8bfe 100644 --- a/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/DateTimeHelper.java +++ b/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/DateTimeHelper.java @@ -1,999 +1,1008 @@ -/*- - * << - * UAVStack - * == - * Copyright (C) 2016 - 2017 UAVStack - * == - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * >> - */ - -package com.creditease.agent.helpers; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; - -public class DateTimeHelper { - - /** - * 日 - */ - public final static int INTERVAL_DAY = 1; - - /** - * 周 - */ - public final static int INTERVAL_WEEK = 2; - - /** - * 月 - */ - public final static int INTERVAL_MONTH = 3; - - /** - * 年 - */ - public final static int INTERVAL_YEAR = 4; - - /** - * 小时 - */ - public final static int INTERVAL_HOUR = 5; - - /** - * 分钟 - */ - public final static int INTERVAL_MINUTE = 6; - - /** - * 秒 - */ - public final static int INTERVAL_SECOND = 7; - - /** - * date = 1901-01-01 - */ - public final static Date tempDate = new Date(new Long("-2177481952000"));; - - private DateTimeHelper() { - } - - /** - * toStandardDateFormat yyyy-MM-dd HH:mm:ss.SSS - * - * @param timestamp - * @return - */ - public static String toStandardDateFormat(long timestamp) { - - return toFormat("yyyy-MM-dd HH:mm:ss.SSS", timestamp); - } - - /** - * toFormat - * - * @param format - * @param timestamp - * @return - */ - public static String toFormat(String format, long timestamp) { - - SimpleDateFormat sdf = new SimpleDateFormat(format); - - return sdf.format(new Date(timestamp)); - } - - /** - * get the time range index in a time span (ms) for 24 hours - * - * @param timeFlag - * @param span - * @return - */ - public static long getTimeRangeIndex(long timeFlag, long span) { - - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - Calendar cl = Calendar.getInstance(); - - int year = cl.get(Calendar.YEAR); - int month = cl.get(Calendar.MONTH) + 1; - int day = cl.get(Calendar.DATE); - - long cTime = 0; - try { - Date d = sdf.parse(year + "-" + month + "-" + day + " 00:00:00"); - cTime = d.getTime(); - } - catch (ParseException e) { - // ignore - } - - long seconds = timeFlag - cTime; - - long timeRangeIndex = seconds / span; - - return timeRangeIndex; - } - - /** - * get the time range index in 1 min for 24 hours - * - * @param timeFlag - * @return - */ - public static long getTimeRangeIndexIn1Min(long timeFlag) { - - return getTimeRangeIndex(timeFlag, 60000); - } - - /** - * 测试是否是当天 - * - * @param date - * 某一日期 - * @return true 今天, false-不是 - */ - @SuppressWarnings("deprecation") - public static boolean isToday(Date date) { - - Date now = new Date(); - boolean result = true; - result &= date.getYear() == now.getYear(); - result &= date.getMonth() == now.getMonth(); - result &= date.getDate() == now.getDate(); - return result; - } - - /** - * 两个日期相减,取天数 - * - * @param date1 - * @param date2 - * @return - */ - public static long DaysBetween(Date date1, Date date2) { - - if (date2 == null) - date2 = new Date(); - long day = (date2.getTime() - date1.getTime()) / (24 * 60 * 60 * 1000); - return day; - } - - /** - * 比较两个日期 if date1<=date2 return true - * - * @param date1 - * @param date2 - * @return - */ - public static boolean compareDate(String date1, String date2) { - - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - Date d1 = format.parse(date1); - Date d2 = format.parse(date2); - return !d1.after(d2); - } - catch (ParseException e) { - e.printStackTrace(); - return false; - } - } - - /** - * 字符型转换成日期型 - * - * @param date - * @param dateFormat - * @return - */ - public static Date dateFormat(String date, String dateFormat) { - - if (date == null) - return null; - SimpleDateFormat format = new SimpleDateFormat(dateFormat); - if (date != null) { - try { - return format.parse(date); - } - catch (Exception ex) { - } - } - return null; - } - - /** - * 使用默认格式 yyyy-MM-dd HH:mm:ss - * - * @param date - * @return - */ - public static Date dateFormat(String date) { - - return dateFormat(date, "yyyy-MM-dd HH:mm:ss"); - } - - /** - * 日期型转换成字符串 - * - * @param date - * @param dateFormat - * @return - */ - public static String dateFormat(Date date, String dateFormat) { - - if (date != null) { - SimpleDateFormat format = new SimpleDateFormat(dateFormat); - if (date != null) { - return format.format(date); - } - } - return ""; - } - - /** - * 由于生日增加保密属性,现决定1900为保密对应值,如果遇到1900的年份,则隐掉年份 - * - * @param date - * @param dateFormat - * @return 不保密显示1981-12-01保密则显示`12-01 - */ - public static String birthdayFormat(Date date) { - - if (date != null) { - SimpleDateFormat format = null; - if (date.before(tempDate)) { - format = new SimpleDateFormat("MM-dd"); - } - else { - format = new SimpleDateFormat("yyyy-MM-dd"); - } - if (date != null) { - return format.format(date); - } - } - return ""; - } - - /** - * 使用默认格式 yyyy-MM-dd HH:mm:ss - * - * @param date - * @return - */ - public static String dateFormat(Date date) { - - return dateFormat(date, "yyyy-MM-dd HH:mm:ss"); - } - - public static boolean isExpiredDay(Date date1) { - - long day = (new Date().getTime() - date1.getTime()) / (24 * 60 * 60 * 1000); - if (day >= 1) - return true; - else - return false; - } - - public static Date getYesterday() { - - Date date = new Date(); - long time = (date.getTime() / 1000) - 60 * 60 * 24; - date.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - date = format.parse(format.format(date)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return date; - } - - public static Date getWeekAgo() { - - Date date = new Date(); - long time = (date.getTime() / 1000) - 7 * 60 * 60 * 24; - date.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - date = format.parse(format.format(date)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return date; - } - - public static String getDaysAgo(int interval) { - - Date date = new Date(); - long time = (date.getTime() / 1000) - interval * 60 * 60 * 24; - date.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - return format.format(date); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return ""; - } - - public static Date getTomorrow() { - - Date date = new Date(); - long time = (date.getTime() / 1000) + 60 * 60 * 24; - date.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - date = format.parse(format.format(date)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return date; - } - - public static Date getBeforeDate(String range) { - - Calendar today = Calendar.getInstance(); - if ("week".equalsIgnoreCase(range)) - today.add(Calendar.WEEK_OF_MONTH, -1); - else if ("month".equalsIgnoreCase(range)) - today.add(Calendar.MONTH, -1); - else - today.clear(); - return today.getTime(); - } - - public static Date getThisWeekStartTime() { - - Calendar today = Calendar.getInstance(); - today.set(Calendar.DAY_OF_WEEK, today.getFirstDayOfWeek()); - Calendar weekFirstDay = Calendar.getInstance(); - weekFirstDay.clear(); - weekFirstDay.set(Calendar.YEAR, today.get(Calendar.YEAR)); - weekFirstDay.set(Calendar.MONTH, today.get(Calendar.MONTH)); - weekFirstDay.set(Calendar.DATE, today.get(Calendar.DATE)); - return weekFirstDay.getTime(); - } - - public static String getToday(String format) { - - String result = ""; - try { - Date today = new Date(); - SimpleDateFormat simpleFormat = new SimpleDateFormat(format); - result = simpleFormat.format(today); - } - catch (Exception e) { - } - return result; - } - - public static Date getStartDay(int year, int month) { - - Calendar today = Calendar.getInstance(); - today.clear(); - today.set(Calendar.YEAR, year); - today.set(Calendar.MONTH, month - 1); - today.set(Calendar.DAY_OF_MONTH, 1); - return today.getTime(); - } - - public static List getBeforeYearList(int before) { - - Calendar today = Calendar.getInstance(); - int theYear = today.get(Calendar.YEAR); - List list = new ArrayList(); - for (int i = before; i >= 0; i--) - list.add(theYear - i); - - return list; - } - - /** - * 增加时间 - * - * @param interval - * [INTERVAL_DAY,INTERVAL_WEEK,INTERVAL_MONTH,INTERVAL_YEAR, INTERVAL_HOUR,INTERVAL_MINUTE] - * @param date - * @param n - * 可以为负数 - * @return - */ - public static Date dateAdd(int interval, Date date, int n) { - - long time = (date.getTime() / 1000); // 单位秒 - switch (interval) { - case INTERVAL_DAY: - time = time + n * 86400;// 60 * 60 * 24; - break; - case INTERVAL_WEEK: - time = time + n * 604800;// 60 * 60 * 24 * 7; - break; - case INTERVAL_MONTH: - time = time + n * 2678400;// 60 * 60 * 24 * 31; - break; - case INTERVAL_YEAR: - time = time + n * 31536000;// 60 * 60 * 24 * 365; - break; - case INTERVAL_HOUR: - time = time + n * 3600;// 60 * 60 ; - break; - case INTERVAL_MINUTE: - time = time + n * 60; - break; - case INTERVAL_SECOND: - time = time + n; - break; - default: - } - - Date result = new Date(); - result.setTime(time * 1000); - return result; - } - - /** - * 计算两个时间间隔 - * - * @param interval - * [INTERVAL_DAY,INTERVAL_WEEK,INTERVAL_MONTH,INTERVAL_YEAR, INTERVAL_HOUR,INTERVAL_MINUTE] - * @param begin - * @param end - * @return - */ - public static int dateDiff(int interval, Date begin, Date end) { - - long beginTime = (begin.getTime() / 1000); // 单位:秒 - long endTime = (end.getTime() / 1000); // 单位: 秒 - long tmp = 0; - if (endTime == beginTime) { - return 0; - } - - // 确定endTime 大于 beginTime 结束时间秒数 大于 开始时间秒数 - if (endTime < beginTime) { - tmp = beginTime; - beginTime = endTime; - endTime = tmp; - } - - long intervalTime = endTime - beginTime; - long result = 0; - switch (interval) { - case INTERVAL_DAY: - result = intervalTime / 86400;// 60 * 60 * 24; - break; - case INTERVAL_WEEK: - result = intervalTime / 604800;// 60 * 60 * 24 * 7; - break; - case INTERVAL_MONTH: - result = intervalTime / 2678400;// 60 * 60 * 24 * 31; - break; - case INTERVAL_YEAR: - result = intervalTime / 31536000;// 60 * 60 * 24 * 365; - break; - case INTERVAL_HOUR: - result = intervalTime / 3600;// 60 * 60 ; - break; - case INTERVAL_MINUTE: - result = intervalTime / 60; - break; - case INTERVAL_SECOND: - result = intervalTime / 1; - break; - default: - } - - // 做过交换 - if (tmp > 0) { - result = 0 - result; - } - return (int) result; - } - - /** - * 当前年份 - * - * @return - */ - public static int getTodayYear() { - - int yyyy = Integer.parseInt(dateFormat(new Date(), "yyyy")); - return yyyy; - } - - public static Date getNow() { - - return new Date(); - } - - /** - * 把日期格式为rss格式兼容的字符串 - * - * @param date - * @return - */ - public static String dateFormatRss(Date date) { - - if (date != null) { - return dateFormat(date, "E, d MMM yyyy H:mm:ss") + " GMT"; - } - return ""; - } - - /** - * 判断当前日期是否在两个日期之间 - * - * @param startDate - * 开始时间 - * @param endDate - * 结束时间 - * @return - */ - public static boolean betweenStartDateAndEndDate(Date startDate, Date endDate) { - - boolean bool = false; - Date curDate = new Date(); - if (curDate.after(startDate) && curDate.before(dateAdd(INTERVAL_DAY, endDate, 1))) { - bool = true; - } - return bool; - - } - - /** - * 判断当前时间是否在在两个时间之间 - * - * @param startDate - * 开始时间 - * @param endDate - * 结束时间 - * @return - */ - public static boolean nowDateBetweenStartDateAndEndDate(Date startDate, Date endDate) { - - boolean bool = false; - Date curDate = new Date(); - if (curDate.after(startDate) && curDate.before(endDate)) { - bool = true; - } - return bool; - } - - /** - * 判断当前时间是否在date之后 - * - * @param date - * @return - */ - public static boolean nowDateAfterDate(Date date) { - - boolean bool = false; - Date curDate = new Date(); - if (curDate.after(date)) { - bool = true; - } - return bool; - } - - /** - * 判断二个日期相隔的天数,结束时间为null时,,取当前时间 - * - * @param startDate - * 开始时间 - * @param endDate - * 结束时间 - * @return - */ - public static int getBetweenTodaysStartDateAndEndDate(Date startDate, Date endDate) { - - int betweentoday = 0; - if (startDate == null) { - return betweentoday; - } - if (endDate == null) { - Calendar calendar = Calendar.getInstance(); - String year = new Integer(calendar.get(Calendar.YEAR)).toString(); - String month = new Integer((calendar.get(Calendar.MONTH) + 1)).toString(); - String day = new Integer(calendar.get(Calendar.DAY_OF_MONTH)).toString(); - String strtodaytime = year + "-" + month + "-" + day; - DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); - try { - endDate = formatter.parse(strtodaytime); - } - catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - if (endDate.after(startDate)) { - betweentoday = (int) ((endDate.getTime() - startDate.getTime()) / 86400000); - } - else { - betweentoday = (int) ((startDate.getTime() - endDate.getTime()) / 86400000); - } - return betweentoday; - } - - /** - * 取得指定长度日期时间字符串{不含格式} - * - * @param format - * 时间格式由常量决定 8: YYMMDDHH 8位 10: YYMMDDHHmm 10位 12: YYMMDDHHmmss 12位 14: YYYYMMDDHHmmss 14位 15: - * YYMMDDHHmmssxxx 15位 (最后的xxx 是毫秒) - */ - public static String getTime(int format) { - - StringBuffer cTime = new StringBuffer(10); - Calendar time = Calendar.getInstance(); - int miltime = time.get(Calendar.MILLISECOND); - int second = time.get(Calendar.SECOND); - int minute = time.get(Calendar.MINUTE); - int hour = time.get(Calendar.HOUR_OF_DAY); - int day = time.get(Calendar.DAY_OF_MONTH); - int month = time.get(Calendar.MONTH) + 1; - int year = time.get(Calendar.YEAR); - if (format != 14) { - if (year >= 2000) - year = year - 2000; - else - year = year - 1900; - } - if (format >= 2) { - if (format == 14) - cTime.append(year); - else - cTime.append(getFormatTime(year, 2)); - } - if (format >= 4) - cTime.append(getFormatTime(month, 2)); - if (format >= 6) - cTime.append(getFormatTime(day, 2)); - if (format >= 8) - cTime.append(getFormatTime(hour, 2)); - if (format >= 10) - cTime.append(getFormatTime(minute, 2)); - if (format >= 12) - cTime.append(getFormatTime(second, 2)); - if (format >= 15) - cTime.append(getFormatTime(miltime, 3)); - return cTime.toString(); - } - - /** - * 产生任意位的字符串 - * - * @param time - * 要转换格式的时间 - * @param format - * 转换的格式 - * @return String 转换的时间 - */ - private static String getFormatTime(int time, int format) { - - StringBuffer numm = new StringBuffer(); - int length = String.valueOf(time).length(); - if (format < length) - return null; - for (int i = 0; i < format - length; i++) { - numm.append("0"); - } - numm.append(time); - return numm.toString().trim(); - } - - /** - * 根据生日去用户年龄 - * - * @param birthday - * @return int - * @exception @Date - * Apr 24, 2008 - */ - public static int getUserAge(Date birthday) { - - if (birthday == null) - return 0; - Calendar cal = Calendar.getInstance(); - if (cal.before(birthday)) { - return 0; - } - int yearNow = cal.get(Calendar.YEAR); - cal.setTime(birthday);// 给时间赋值 - int yearBirth = cal.get(Calendar.YEAR); - return yearNow - yearBirth; - } - - /** - * 将int型时间(1970年至今的秒数)转换成Date型时间 - * - * @param unixTime - * 1970年至今的秒数 - * @return - */ - public static Date getDateByUnixTime(int unixTime) { - - return new Date(unixTime * 1000L); - } - - public static long getUnixTimeLong() { - - return getUnixTimeByDate(new Date()); - } - - public static int getCurrentUnixTime() { - - return getUnixTimeByDate(new Date()); - } - - /** - * 将Date型时间转换成int型时间(1970年至今的秒数) - * - * @param unixTime - * 1970年至今的秒数 - * @return - */ - public static int getUnixTimeByDate(Date date) { - - return (int) (date.getTime() / 1000); - } - - public static long getUnixTimeLong(Date date) { - - return (date.getTime() / 1000); - } - - public static Date getNextDay(Date date) { - - long time = (date.getTime() / 1000) + 60 * 60 * 24; - date.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - date = format.parse(format.format(date)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return date; - - } - - /** - * @param date - * @return 复制新Date,不改变参数 - */ - public static Date nextDay(Date date) { - - Date newDate = (Date) date.clone(); - long time = (newDate.getTime() / 1000) + 60 * 60 * 24; - newDate.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - newDate = format.parse(format.format(newDate)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return newDate; - - } - - public static Date getNowTime() { - - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - Date date = new Date(); - String dateStr = dateFormat(date); - try { - date = format.parse(dateStr); - } - catch (ParseException e) { - e.printStackTrace(); - } - return date; - } - - public static Date getTomorrow(Date date1) { - - // 创建当前时间对象 - Calendar now = Calendar.getInstance(); - now.setTime(date1); - // 日期[+1]day - now.add(Calendar.DATE, 1); - return now.getTime(); - } - - public static Date getWeekAgo(Date date) { - - Date newDate = (Date) date.clone(); - long time = (newDate.getTime() / 1000) - 60 * 60 * 24 * 7; - newDate.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - newDate = format.parse(format.format(newDate)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return newDate; - } - - /** - * @param date - * @return 复制新Date,不改变参数 - */ - public static Date yesterday(Date date) { - - Date newDate = (Date) date.clone(); - long time = (newDate.getTime() / 1000) - 60 * 60 * 24; - newDate.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - newDate = format.parse(format.format(newDate)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return newDate; - } - - public static Date getYesterday(Date date) { - - long time = (date.getTime() / 1000) - 60 * 60 * 24; - date.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - date = format.parse(format.format(date)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return date; - } - - public static String getStringNowTime() { - - Date date = new Date(); - String dateStr = dateFormat(date); - return dateStr; - } - - /** - * 指定时间的秒数 指定时间零点的秒数加指定天数的秒数 - * - * @param time - * 时间 - * @param range - * 天 - * @return - */ - public static long getSpecifyTimeSec(long time, int range) { - - Date date = new Date((time * 1000 + (23 - Calendar.ZONE_OFFSET) * 3600000) / 86400000 * 86400000 - - (23 - Calendar.ZONE_OFFSET) * 3600000); - long zeroTime = date.getTime() / 1000; - long specifyTime = range * 24 * 3600; - return (zeroTime + specifyTime); - } - - /** - * 将int型时间(1970年至今的秒数)转换成指定格式的时间 - * - * @param unixTime - * 1970年至今的秒数 - * @param dateFormat - * 时间格式 - * @return - */ - public static String formatDateByUnixTime(long unixTime, String dateFormat) { - - return dateFormat(new Date(unixTime * 1000), dateFormat); - } - - private static List dateFormats = new ArrayList(12) { - - private static final long serialVersionUID = 2249396579858199535L; - { - add(new SimpleDateFormat("yyyy-MM-dd")); - add(new SimpleDateFormat("yyyy/MM/dd")); - add(new SimpleDateFormat("yyyy.MM.dd")); - add(new SimpleDateFormat("yyyy-MM-dd HH:24:mm:ss")); - add(new SimpleDateFormat("yyyy/MM/dd HH:24:mm:ss")); - add(new SimpleDateFormat("yyyy.MM.dd HH:24:mm:ss")); - add(new SimpleDateFormat("M/dd/yyyy")); - add(new SimpleDateFormat("dd.M.yyyy")); - add(new SimpleDateFormat("M/dd/yyyy hh:mm:ss a")); - add(new SimpleDateFormat("dd.M.yyyy hh:mm:ss a")); - add(new SimpleDateFormat("dd.MMM.yyyy")); - add(new SimpleDateFormat("dd-MMM-yyyy")); - } - }; - - public static Date convertToDate(String input) { - - Date date = null; - if (null == input) { - return null; - } - for (SimpleDateFormat format : dateFormats) { - try { - format.setLenient(false); - date = format.parse(input); - } - catch (ParseException e) { - // Shhh.. try other formats - } - if (date != null) { - break; - } - } - return date; - } - - public static Long getTodayTime() { - - Calendar today = Calendar.getInstance(); - today.set(Calendar.HOUR_OF_DAY, 0); - today.set(Calendar.MINUTE, 0); - today.set(Calendar.SECOND, 0); - return Long.valueOf(String.valueOf(today.getTimeInMillis()).substring(0, 10)); - } - - public static Long getYesterdayTime() { - - Calendar today = Calendar.getInstance(); - today.set(Calendar.HOUR_OF_DAY, -24); - today.set(Calendar.MINUTE, 0); - today.set(Calendar.SECOND, 0); - return Long.valueOf(String.valueOf(today.getTimeInMillis()).substring(0, 10)); - } - - public static Long getTomorrowTime() { - - Calendar tomorrow = Calendar.getInstance(); - tomorrow.set(Calendar.HOUR_OF_DAY, 24); - tomorrow.set(Calendar.MINUTE, 0); - tomorrow.set(Calendar.SECOND, 0); - return Long.valueOf(String.valueOf(tomorrow.getTimeInMillis()).substring(0, 10)); - } - - public static Date getMonthAgo(Date date) { - - Calendar now = Calendar.getInstance(); - now.setTime(date); - - now.add(Calendar.MONTH, -1); - - return now.getTime(); - } - - public static Date getYearAgo(Date date) { - - Calendar now = Calendar.getInstance(); - now.setTime(date); - - now.add(Calendar.YEAR, -1); - - return now.getTime(); - } -} +/*- + * << + * UAVStack + * == + * Copyright (C) 2016 - 2017 UAVStack + * == + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * >> + */ + +package com.creditease.agent.helpers; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +public class DateTimeHelper { + + /** + * 日 + */ + public final static int INTERVAL_DAY = 1; + + /** + * 周 + */ + public final static int INTERVAL_WEEK = 2; + + /** + * 月 + */ + public final static int INTERVAL_MONTH = 3; + + /** + * 年 + */ + public final static int INTERVAL_YEAR = 4; + + /** + * 小时 + */ + public final static int INTERVAL_HOUR = 5; + + /** + * 分钟 + */ + public final static int INTERVAL_MINUTE = 6; + + /** + * 秒 + */ + public final static int INTERVAL_SECOND = 7; + + /** + * date = 1901-01-01 + */ + public final static Date tempDate = new Date(new Long("-2177481952000"));; + + private DateTimeHelper() { + } + + /** + * toStandardDateFormat yyyy-MM-dd HH:mm:ss.SSS + * + * @param timestamp + * @return + */ + public static String toStandardDateFormat(long timestamp) { + + return toFormat("yyyy-MM-dd HH:mm:ss.SSS", timestamp); + } + + /** + * toFormat + * + * @param format + * @param timestamp + * @return + */ + public static String toFormat(String format, long timestamp) { + + SimpleDateFormat sdf = new SimpleDateFormat(format); + + return sdf.format(new Date(timestamp)); + } + + /** + * get the time range index in a time span (ms) for 24 hours + * + * @param timeFlag + * @param span + * @return + */ + public static long getTimeRangeIndex(long timeFlag, long span) { + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + Calendar cl = Calendar.getInstance(); + + int year = cl.get(Calendar.YEAR); + int month = cl.get(Calendar.MONTH) + 1; + int day = cl.get(Calendar.DATE); + + long cTime = 0; + try { + Date d = sdf.parse(year + "-" + month + "-" + day + " 00:00:00"); + cTime = d.getTime(); + } + catch (ParseException e) { + // ignore + } + + long seconds = timeFlag - cTime; + + long timeRangeIndex = seconds / span; + + return timeRangeIndex; + } + + /** + * get the time range index in 1 min for 24 hours + * + * @param timeFlag + * @return + */ + public static long getTimeRangeIndexIn1Min(long timeFlag) { + + return getTimeRangeIndex(timeFlag, 60000); + } + + /** + * 测试是否是当天 + * + * @param date + * 某一日期 + * @return true 今天, false-不是 + */ + @SuppressWarnings("deprecation") + public static boolean isToday(Date date) { + + Date now = new Date(); + boolean result = true; + result &= date.getYear() == now.getYear(); + result &= date.getMonth() == now.getMonth(); + result &= date.getDate() == now.getDate(); + return result; + } + + /** + * 两个日期相减,取天数 + * + * @param date1 + * @param date2 + * @return + */ + public static long DaysBetween(Date date1, Date date2) { + + if (date2 == null) + date2 = new Date(); + long day = (date2.getTime() - date1.getTime()) / (24 * 60 * 60 * 1000); + return day; + } + + /** + * 比较两个日期 if date1<=date2 return true + * + * @param date1 + * @param date2 + * @return + */ + public static boolean compareDate(String date1, String date2) { + + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + Date d1 = format.parse(date1); + Date d2 = format.parse(date2); + return !d1.after(d2); + } + catch (ParseException e) { + e.printStackTrace(); + return false; + } + } + + /** + * 字符型转换成日期型 + * + * @param date + * @param dateFormat + * @return + */ + public static Date dateFormat(String date, String dateFormat) { + + if (date == null) + return null; + SimpleDateFormat format = new SimpleDateFormat(dateFormat); + if (date != null) { + try { + return format.parse(date); + } + catch (Exception ex) { + } + } + return null; + } + + /** + * 使用默认格式 yyyy-MM-dd HH:mm:ss + * + * @param date + * @return + */ + public static Date dateFormat(String date) { + + return dateFormat(date, "yyyy-MM-dd HH:mm:ss"); + } + + /** + * 日期型转换成字符串 + * + * @param date + * @param dateFormat + * @return + */ + public static String dateFormat(Date date, String dateFormat) { + + if (date != null) { + SimpleDateFormat format = new SimpleDateFormat(dateFormat); + if (date != null) { + return format.format(date); + } + } + return ""; + } + + /** + * 由于生日增加保密属性,现决定1900为保密对应值,如果遇到1900的年份,则隐掉年份 + * + * @param date + * @param dateFormat + * @return 不保密显示1981-12-01保密则显示`12-01 + */ + public static String birthdayFormat(Date date) { + + if (date != null) { + SimpleDateFormat format = null; + if (date.before(tempDate)) { + format = new SimpleDateFormat("MM-dd"); + } + else { + format = new SimpleDateFormat("yyyy-MM-dd"); + } + if (date != null) { + return format.format(date); + } + } + return ""; + } + + /** + * 使用默认格式 yyyy-MM-dd HH:mm:ss + * + * @param date + * @return + */ + public static String dateFormat(Date date) { + + return dateFormat(date, "yyyy-MM-dd HH:mm:ss"); + } + + public static boolean isExpiredDay(Date date1) { + + long day = (new Date().getTime() - date1.getTime()) / (24 * 60 * 60 * 1000); + if (day >= 1) + return true; + else + return false; + } + + public static Date getYesterday() { + + Date date = new Date(); + long time = (date.getTime() / 1000) - 60 * 60 * 24; + date.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + date = format.parse(format.format(date)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return date; + } + + public static Date getWeekAgo() { + + Date date = new Date(); + long time = (date.getTime() / 1000) - 7 * 60 * 60 * 24; + date.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + date = format.parse(format.format(date)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return date; + } + + public static String getDaysAgo(int interval) { + + Date date = new Date(); + long time = (date.getTime() / 1000) - interval * 60 * 60 * 24; + date.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + return format.format(date); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return ""; + } + + public static Date getTomorrow() { + + Date date = new Date(); + long time = (date.getTime() / 1000) + 60 * 60 * 24; + date.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + date = format.parse(format.format(date)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return date; + } + + public static Date getBeforeDate(String range) { + + Calendar today = Calendar.getInstance(); + if ("week".equalsIgnoreCase(range)) + today.add(Calendar.WEEK_OF_MONTH, -1); + else if ("month".equalsIgnoreCase(range)) + today.add(Calendar.MONTH, -1); + else + today.clear(); + return today.getTime(); + } + + public static Date getThisWeekStartTime() { + + Calendar today = Calendar.getInstance(); + today.set(Calendar.DAY_OF_WEEK, today.getFirstDayOfWeek()); + Calendar weekFirstDay = Calendar.getInstance(); + weekFirstDay.clear(); + weekFirstDay.set(Calendar.YEAR, today.get(Calendar.YEAR)); + weekFirstDay.set(Calendar.MONTH, today.get(Calendar.MONTH)); + weekFirstDay.set(Calendar.DATE, today.get(Calendar.DATE)); + return weekFirstDay.getTime(); + } + + public static String getToday(String format) { + + String result = ""; + try { + Date today = new Date(); + SimpleDateFormat simpleFormat = new SimpleDateFormat(format); + result = simpleFormat.format(today); + } + catch (Exception e) { + } + return result; + } + + public static Date getStartDay(int year, int month) { + + Calendar today = Calendar.getInstance(); + today.clear(); + today.set(Calendar.YEAR, year); + today.set(Calendar.MONTH, month - 1); + today.set(Calendar.DAY_OF_MONTH, 1); + return today.getTime(); + } + + public static List getBeforeYearList(int before) { + + Calendar today = Calendar.getInstance(); + int theYear = today.get(Calendar.YEAR); + List list = new ArrayList(); + for (int i = before; i >= 0; i--) + list.add(theYear - i); + + return list; + } + + /** + * 增加时间 + * + * @param interval + * [INTERVAL_DAY,INTERVAL_WEEK,INTERVAL_MONTH,INTERVAL_YEAR, INTERVAL_HOUR,INTERVAL_MINUTE] + * @param date + * @param n + * 可以为负数 + * @return + */ + public static Date dateAdd(int interval, Date date, int n) { + + long time = (date.getTime() / 1000); // 单位秒 + switch (interval) { + case INTERVAL_DAY: + time = time + n * 86400;// 60 * 60 * 24; + break; + case INTERVAL_WEEK: + time = time + n * 604800;// 60 * 60 * 24 * 7; + break; + case INTERVAL_MONTH: + time = time + n * 2678400;// 60 * 60 * 24 * 31; + break; + case INTERVAL_YEAR: + time = time + n * 31536000;// 60 * 60 * 24 * 365; + break; + case INTERVAL_HOUR: + time = time + n * 3600;// 60 * 60 ; + break; + case INTERVAL_MINUTE: + time = time + n * 60; + break; + case INTERVAL_SECOND: + time = time + n; + break; + default: + } + + Date result = new Date(); + result.setTime(time * 1000); + return result; + } + + /** + * 计算两个时间间隔 + * + * @param interval + * [INTERVAL_DAY,INTERVAL_WEEK,INTERVAL_MONTH,INTERVAL_YEAR, INTERVAL_HOUR,INTERVAL_MINUTE] + * @param begin + * @param end + * @return + */ + public static int dateDiff(int interval, Date begin, Date end) { + + long beginTime = (begin.getTime() / 1000); // 单位:秒 + long endTime = (end.getTime() / 1000); // 单位: 秒 + long tmp = 0; + if (endTime == beginTime) { + return 0; + } + + // 确定endTime 大于 beginTime 结束时间秒数 大于 开始时间秒数 + if (endTime < beginTime) { + tmp = beginTime; + beginTime = endTime; + endTime = tmp; + } + + long intervalTime = endTime - beginTime; + long result = 0; + switch (interval) { + case INTERVAL_DAY: + result = intervalTime / 86400;// 60 * 60 * 24; + break; + case INTERVAL_WEEK: + result = intervalTime / 604800;// 60 * 60 * 24 * 7; + break; + case INTERVAL_MONTH: + result = intervalTime / 2678400;// 60 * 60 * 24 * 31; + break; + case INTERVAL_YEAR: + result = intervalTime / 31536000;// 60 * 60 * 24 * 365; + break; + case INTERVAL_HOUR: + result = intervalTime / 3600;// 60 * 60 ; + break; + case INTERVAL_MINUTE: + result = intervalTime / 60; + break; + case INTERVAL_SECOND: + result = intervalTime / 1; + break; + default: + } + + // 做过交换 + if (tmp > 0) { + result = 0 - result; + } + return (int) result; + } + + /** + * 当前年份 + * + * @return + */ + public static int getTodayYear() { + + int yyyy = Integer.parseInt(dateFormat(new Date(), "yyyy")); + return yyyy; + } + + public static Date getNow() { + + return new Date(); + } + + /** + * 把日期格式为rss格式兼容的字符串 + * + * @param date + * @return + */ + public static String dateFormatRss(Date date) { + + if (date != null) { + return dateFormat(date, "E, d MMM yyyy H:mm:ss") + " GMT"; + } + return ""; + } + + /** + * 判断当前日期是否在两个日期之间 + * + * @param startDate + * 开始时间 + * @param endDate + * 结束时间 + * @return + */ + public static boolean betweenStartDateAndEndDate(Date startDate, Date endDate) { + + boolean bool = false; + Date curDate = new Date(); + if (curDate.after(startDate) && curDate.before(dateAdd(INTERVAL_DAY, endDate, 1))) { + bool = true; + } + return bool; + + } + + /** + * 判断当前时间是否在在两个时间之间 + * + * @param startDate + * 开始时间 + * @param endDate + * 结束时间 + * @return + */ + public static boolean nowDateBetweenStartDateAndEndDate(Date startDate, Date endDate) { + + boolean bool = false; + Date curDate = new Date(); + if (curDate.after(startDate) && curDate.before(endDate)) { + bool = true; + } + return bool; + } + + /** + * 判断当前时间是否在date之后 + * + * @param date + * @return + */ + public static boolean nowDateAfterDate(Date date) { + + boolean bool = false; + Date curDate = new Date(); + if (curDate.after(date)) { + bool = true; + } + return bool; + } + + /** + * 判断二个日期相隔的天数,结束时间为null时,,取当前时间 + * + * @param startDate + * 开始时间 + * @param endDate + * 结束时间 + * @return + */ + public static int getBetweenTodaysStartDateAndEndDate(Date startDate, Date endDate) { + + int betweentoday = 0; + if (startDate == null) { + return betweentoday; + } + if (endDate == null) { + Calendar calendar = Calendar.getInstance(); + String year = new Integer(calendar.get(Calendar.YEAR)).toString(); + String month = new Integer((calendar.get(Calendar.MONTH) + 1)).toString(); + String day = new Integer(calendar.get(Calendar.DAY_OF_MONTH)).toString(); + String strtodaytime = year + "-" + month + "-" + day; + DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + try { + endDate = formatter.parse(strtodaytime); + } + catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + if (endDate.after(startDate)) { + betweentoday = (int) ((endDate.getTime() - startDate.getTime()) / 86400000); + } + else { + betweentoday = (int) ((startDate.getTime() - endDate.getTime()) / 86400000); + } + return betweentoday; + } + + /** + * 取得指定长度日期时间字符串{不含格式} + * + * @param format + * 时间格式由常量决定 8: YYMMDDHH 8位 10: YYMMDDHHmm 10位 12: YYMMDDHHmmss 12位 14: YYYYMMDDHHmmss 14位 15: + * YYMMDDHHmmssxxx 15位 (最后的xxx 是毫秒) + */ + public static String getTime(int format) { + + StringBuffer cTime = new StringBuffer(10); + Calendar time = Calendar.getInstance(); + int miltime = time.get(Calendar.MILLISECOND); + int second = time.get(Calendar.SECOND); + int minute = time.get(Calendar.MINUTE); + int hour = time.get(Calendar.HOUR_OF_DAY); + int day = time.get(Calendar.DAY_OF_MONTH); + int month = time.get(Calendar.MONTH) + 1; + int year = time.get(Calendar.YEAR); + if (format != 14) { + if (year >= 2000) + year = year - 2000; + else + year = year - 1900; + } + if (format >= 2) { + if (format == 14) + cTime.append(year); + else + cTime.append(getFormatTime(year, 2)); + } + if (format >= 4) + cTime.append(getFormatTime(month, 2)); + if (format >= 6) + cTime.append(getFormatTime(day, 2)); + if (format >= 8) + cTime.append(getFormatTime(hour, 2)); + if (format >= 10) + cTime.append(getFormatTime(minute, 2)); + if (format >= 12) + cTime.append(getFormatTime(second, 2)); + if (format >= 15) + cTime.append(getFormatTime(miltime, 3)); + return cTime.toString(); + } + + /** + * 产生任意位的字符串 + * + * @param time + * 要转换格式的时间 + * @param format + * 转换的格式 + * @return String 转换的时间 + */ + private static String getFormatTime(int time, int format) { + + StringBuffer numm = new StringBuffer(); + int length = String.valueOf(time).length(); + if (format < length) + return null; + for (int i = 0; i < format - length; i++) { + numm.append("0"); + } + numm.append(time); + return numm.toString().trim(); + } + + /** + * 根据生日去用户年龄 + * + * @param birthday + * @return int + * @exception @Date + * Apr 24, 2008 + */ + public static int getUserAge(Date birthday) { + + if (birthday == null) + return 0; + Calendar cal = Calendar.getInstance(); + if (cal.before(birthday)) { + return 0; + } + int yearNow = cal.get(Calendar.YEAR); + cal.setTime(birthday);// 给时间赋值 + int yearBirth = cal.get(Calendar.YEAR); + return yearNow - yearBirth; + } + + /** + * 将int型时间(1970年至今的秒数)转换成Date型时间 + * + * @param unixTime + * 1970年至今的秒数 + * @return + */ + public static Date getDateByUnixTime(int unixTime) { + + return new Date(unixTime * 1000L); + } + + public static long getUnixTimeLong() { + + return getUnixTimeByDate(new Date()); + } + + public static int getCurrentUnixTime() { + + return getUnixTimeByDate(new Date()); + } + + /** + * 将Date型时间转换成int型时间(1970年至今的秒数) + * + * @param unixTime + * 1970年至今的秒数 + * @return + */ + public static int getUnixTimeByDate(Date date) { + + return (int) (date.getTime() / 1000); + } + + public static long getUnixTimeLong(Date date) { + + return (date.getTime() / 1000); + } + + public static Date getNextDay(Date date) { + + long time = (date.getTime() / 1000) + 60 * 60 * 24; + date.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + date = format.parse(format.format(date)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return date; + + } + + /** + * @param date + * @return 复制新Date,不改变参数 + */ + public static Date nextDay(Date date) { + + Date newDate = (Date) date.clone(); + long time = (newDate.getTime() / 1000) + 60 * 60 * 24; + newDate.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + newDate = format.parse(format.format(newDate)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return newDate; + + } + + public static Date getNowTime() { + + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(); + String dateStr = dateFormat(date); + try { + date = format.parse(dateStr); + } + catch (ParseException e) { + e.printStackTrace(); + } + return date; + } + + public static Date getTomorrow(Date date1) { + + // 创建当前时间对象 + Calendar now = Calendar.getInstance(); + now.setTime(date1); + // 日期[+1]day + now.add(Calendar.DATE, 1); + return now.getTime(); + } + + public static Date getWeekAgo(Date date) { + + Date newDate = (Date) date.clone(); + long time = (newDate.getTime() / 1000) - 60 * 60 * 24 * 7; + newDate.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + newDate = format.parse(format.format(newDate)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return newDate; + } + + /** + * @param date + * @return 复制新Date,不改变参数 + */ + public static Date yesterday(Date date) { + + Date newDate = (Date) date.clone(); + long time = (newDate.getTime() / 1000) - 60 * 60 * 24; + newDate.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + newDate = format.parse(format.format(newDate)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return newDate; + } + + public static Date getYesterday(Date date) { + + long time = (date.getTime() / 1000) - 60 * 60 * 24; + date.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + date = format.parse(format.format(date)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return date; + } + + public static String getStringNowTime() { + + Date date = new Date(); + String dateStr = dateFormat(date); + return dateStr; + } + + /** + * 指定时间的秒数 指定时间零点的秒数加指定天数的秒数 + * + * @param time + * 时间 + * @param range + * 天 + * @return + */ + public static long getSpecifyTimeSec(long time, int range) { + + Date date = new Date((time * 1000 + (23 - Calendar.ZONE_OFFSET) * 3600000) / 86400000 * 86400000 + - (23 - Calendar.ZONE_OFFSET) * 3600000); + long zeroTime = date.getTime() / 1000; + long specifyTime = range * 24 * 3600; + return (zeroTime + specifyTime); + } + + /** + * 将int型时间(1970年至今的秒数)转换成指定格式的时间 + * + * @param unixTime + * 1970年至今的秒数 + * @param dateFormat + * 时间格式 + * @return + */ + public static String formatDateByUnixTime(long unixTime, String dateFormat) { + + return dateFormat(new Date(unixTime * 1000), dateFormat); + } + + private static List dateFormats = new ArrayList(12) { + + private static final long serialVersionUID = 2249396579858199535L; + { + add(new SimpleDateFormat("yyyy-MM-dd")); + add(new SimpleDateFormat("yyyy/MM/dd")); + add(new SimpleDateFormat("yyyy.MM.dd")); + add(new SimpleDateFormat("yyyy-MM-dd HH:24:mm:ss")); + add(new SimpleDateFormat("yyyy/MM/dd HH:24:mm:ss")); + add(new SimpleDateFormat("yyyy.MM.dd HH:24:mm:ss")); + add(new SimpleDateFormat("M/dd/yyyy")); + add(new SimpleDateFormat("dd.M.yyyy")); + add(new SimpleDateFormat("M/dd/yyyy hh:mm:ss a")); + add(new SimpleDateFormat("dd.M.yyyy hh:mm:ss a")); + add(new SimpleDateFormat("dd.MMM.yyyy")); + add(new SimpleDateFormat("dd-MMM-yyyy")); + } + }; + + public static Date convertToDate(String input) { + + Date date = null; + if (null == input) { + return null; + } + for (SimpleDateFormat format : dateFormats) { + try { + format.setLenient(false); + date = format.parse(input); + } + catch (ParseException e) { + // Shhh.. try other formats + } + if (date != null) { + break; + } + } + return date; + } + + public static Long getTodayTime() { + + Calendar today = Calendar.getInstance(); + today.set(Calendar.HOUR_OF_DAY, 0); + today.set(Calendar.MINUTE, 0); + today.set(Calendar.SECOND, 0); + return Long.valueOf(String.valueOf(today.getTimeInMillis()).substring(0, 10)); + } + + public static Long getYesterdayTime() { + + Calendar today = Calendar.getInstance(); + today.set(Calendar.HOUR_OF_DAY, -24); + today.set(Calendar.MINUTE, 0); + today.set(Calendar.SECOND, 0); + return Long.valueOf(String.valueOf(today.getTimeInMillis()).substring(0, 10)); + } + + public static Long getTomorrowTime() { + + Calendar tomorrow = Calendar.getInstance(); + tomorrow.set(Calendar.HOUR_OF_DAY, 24); + tomorrow.set(Calendar.MINUTE, 0); + tomorrow.set(Calendar.SECOND, 0); + return Long.valueOf(String.valueOf(tomorrow.getTimeInMillis()).substring(0, 10)); + } + + public static Date getMonthAgo(Date date) { + + Calendar now = Calendar.getInstance(); + now.setTime(date); + + now.add(Calendar.MONTH, -1); + + return now.getTime(); + } + + public static Date getYearAgo(Date date) { + + Calendar now = Calendar.getInstance(); + now.setTime(date); + + now.add(Calendar.YEAR, -1); + + return now.getTime(); + } + + public static int getWeekday(Date date) { + + Calendar cal = Calendar.getInstance(); + + cal.setTime(date); + + return cal.get(Calendar.DAY_OF_WEEK) - 1; + } +} diff --git a/com.creditease.uav.hook.mq/src/main/java/com/creditease/uav/hook/rabbitmq/interceptors/RabbitmqIT.java b/com.creditease.uav.hook.mq/src/main/java/com/creditease/uav/hook/rabbitmq/interceptors/RabbitmqIT.java index 6802f694..b14e429f 100644 --- a/com.creditease.uav.hook.mq/src/main/java/com/creditease/uav/hook/rabbitmq/interceptors/RabbitmqIT.java +++ b/com.creditease.uav.hook.mq/src/main/java/com/creditease/uav/hook/rabbitmq/interceptors/RabbitmqIT.java @@ -1,365 +1,365 @@ -/*- - * << - * UAVStack - * == - * Copyright (C) 2016 - 2017 UAVStack - * == - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * >> - */ - -package com.creditease.uav.hook.rabbitmq.interceptors; - -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.creditease.monitor.UAVServer; -import com.creditease.monitor.captureframework.spi.CaptureConstants; -import com.creditease.monitor.captureframework.spi.Monitor; -import com.creditease.monitor.proxy.spi.JDKProxyInvokeHandler; -import com.creditease.monitor.proxy.spi.JDKProxyInvokeProcessor; -import com.creditease.uav.apm.invokechain.spi.InvokeChainConstants; -import com.creditease.uav.common.BaseComponent; -import com.creditease.uav.hook.rabbitmq.adapter.RabbitmqConsumerAdapter; -import com.creditease.uav.hook.rabbitmq.adapter.RabbitmqProducerAdapter; -import com.creditease.uav.util.JDKProxyInvokeUtil; -import com.rabbitmq.client.AMQP; -import com.rabbitmq.client.AMQP.BasicProperties; -import com.rabbitmq.client.Channel; -import com.rabbitmq.client.Connection; -import com.rabbitmq.client.Consumer; - -public class RabbitmqIT extends BaseComponent { - - private String applicationId; - static final Map queueNameIndex = new HashMap(); - static { - queueNameIndex.put("basicPublish", 1); - queueNameIndex.put("queueDeclare", 0); - queueNameIndex.put("queueDeclareNoWait", 0); - queueNameIndex.put("queueDeclarePassive", 0); - queueNameIndex.put("queueDelete", 0); - queueNameIndex.put("queueDeleteNoWait", 0); - queueNameIndex.put("queueBind", 0); - queueNameIndex.put("queueBindNoWait", 0); - queueNameIndex.put("queueUnbind", 0); - queueNameIndex.put("queuePurge", 0); - queueNameIndex.put("basicGet", 0); - queueNameIndex.put("basicConsume", 0); - } - - public RabbitmqIT(String appid) { - this.applicationId = appid; - } - - public Connection doInstall(Connection arg) { - - arg = JDKProxyInvokeUtil.newProxyInstance(Connection.class.getClassLoader(), - new Class[] { Connection.class }, - new JDKProxyInvokeHandler(arg, new ConnectionProxyProcessor())); - - return arg; - } - - /** - * - * ConnectionProxyProcessor description: ConnectionProxyProcessor - * - */ - public class ConnectionProxyProcessor extends JDKProxyInvokeProcessor { - - @Override - public void preProcess(Connection t, Object proxy, Method method, Object[] args) { - - } - - @Override - public Object postProcess(Object res, Connection t, Object proxy, Method method, Object[] args) { - - if (method.getName().equals("createChannel")) { - return JDKProxyInvokeUtil.newProxyInstance(Channel.class.getClassLoader(), - new Class[] { Channel.class }, - new JDKProxyInvokeHandler((Channel) res, new ChannelProxyProcessor())); - } - return null; - } - - } - - /** - * - * ChannelProxyProcessor description: ChannelProxyProcessor - * - */ - public class ChannelProxyProcessor extends JDKProxyInvokeProcessor { - - String address; - String targetServer; - private Map ivcContextParams = new HashMap(); - - @SuppressWarnings("unchecked") - @Override - public void preProcess(Channel t, Object proxy, Method method, Object[] args) { - - if (method.getExceptionTypes().length > 0 - && method.getExceptionTypes()[0].getName().equals(IOException.class.getName())) { - String methodName = method.getName(); - String queueName = null; - if (queueNameIndex.containsKey(methodName) && args.length != 0) { - - queueName = (String) args[queueNameIndex.get(methodName)]; - if (isTempQueue(queueName)) { - return; - } - - } - - if (null == address) { - address = t.getConnection().getAddress().getHostAddress() + ":" + t.getConnection().getPort(); - address = "mq:rabbit://" + address; - } - String url = address + ((null == queueName) ? "" : "/" + queueName); - - if ("basicConsume".equals(method.getName())) { - // delegate the consumer - args[args.length - 1] = JDKProxyInvokeUtil.newProxyInstance(Consumer.class.getClassLoader(), - new Class[] { Consumer.class }, new JDKProxyInvokeHandler( - (Consumer) args[args.length - 1], new ConsumerProxyProcessor(t, url))); - - } - - Map params = new HashMap(); - params.put(CaptureConstants.INFO_CLIENT_REQUEST_URL, url); - params.put(CaptureConstants.INFO_CLIENT_REQUEST_ACTION, method.getName()); - params.put(CaptureConstants.INFO_CLIENT_APPID, applicationId); - params.put(CaptureConstants.INFO_CLIENT_TYPE, "rabbitmq.client"); - - if (logger.isDebugable()) { - logger.debug("Invoke START:" + url + ",op=" + method.getName(), null); - } - - UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, - Monitor.CapturePhase.PRECAP, params); - - // 调用链只关心真正的消息通讯 - if (method.getName().equals("basicPublish")) { - - // register adapter - UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", - "registerAdapter", RabbitmqProducerAdapter.class); - - ivcContextParams = (Map) UAVServer.instance().runSupporter( - "com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", - InvokeChainConstants.CHAIN_APP_CLIENT, InvokeChainConstants.CapturePhase.PRECAP, params, - RabbitmqProducerAdapter.class, - new Object[] { (BasicProperties) args[args.length - 2], args[args.length - 1] }); - if (ivcContextParams != null - && ivcContextParams.containsKey(InvokeChainConstants.PARAM_MQHEAD_INFO)) { - args[2] = ivcContextParams.get(InvokeChainConstants.PARAM_MQHEAD_INFO); - } - } - } - } - - @Override - public Object postProcess(Object res, Channel t, Object proxy, Method method, Object[] args) { - - if (needDoCap(method, args)) { - doCap(1, t, method, null); - } - - return null; - } - - @Override - public void catchInvokeException(Channel t, Object proxy, Method method, Object[] args, Throwable e) { - - if (needDoCap(method, args)) { - doCap(-1, t, method, e); - } - - } - - private boolean needDoCap(Method method, Object[] args) { - - if (method.getExceptionTypes().length == 0 - || !method.getExceptionTypes()[0].getName().equals(IOException.class.getName())) { - return false; - } - String methodName = method.getName(); - if (queueNameIndex.containsKey(methodName) && args.length != 0) { - - if (isTempQueue((String) args[queueNameIndex.get(methodName)])) { - return false; - } - } - return true; - } - - private void doCap(int rc, Channel t, Method method, Throwable e) { - - if (null == targetServer) { - Map conn = t.getConnection().getServerProperties(); - String cluster_name = (null == conn.get("cluster_name")) ? "unknown" - : conn.get("cluster_name").toString(); - String version = (null == conn.get("version")) ? "unknown" : conn.get("version").toString(); - targetServer = cluster_name + "@" + version; - } - - Map params = new HashMap(); - - params.put(CaptureConstants.INFO_CLIENT_TARGETSERVER, targetServer); - params.put(CaptureConstants.INFO_CLIENT_RESPONSECODE, rc); - - if (logger.isDebugable()) { - logger.debug("Invoke END: rc=" + rc + "," + targetServer, null); - } - - UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, - Monitor.CapturePhase.DOCAP, params); - - // 调用链只关心真正的消息通讯 - if (method.getName().equals("basicPublish")) { - - if (rc == -1) { - ivcContextParams.put(CaptureConstants.INFO_CLIENT_RESPONSESTATE, e.toString()); - } - if (ivcContextParams != null) { - ivcContextParams.putAll(params); - } - - UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", - InvokeChainConstants.CHAIN_APP_CLIENT, InvokeChainConstants.CapturePhase.DOCAP, - ivcContextParams, RabbitmqProducerAdapter.class, null); - } - - } - - public boolean isTempQueue(String queueName) { - - String regEx = "^([0-9]|[a-f]){8}(-([0-9]|[a-f]){4}){3}-([0-9]|[a-f]){12}$"; - Matcher matcher = Pattern.compile(regEx).matcher(queueName); - return matcher.matches(); - - } - } - - public class ConsumerProxyProcessor extends JDKProxyInvokeProcessor { - - private Channel channel; - private String url; - private String targetServer; - - public ConsumerProxyProcessor(Channel channel, String url) { - this.channel = channel; - this.url = url; - } - - @Override - public void preProcess(Consumer t, Object proxy, Method method, Object[] args) { - - Map params = new HashMap(); - params.put(CaptureConstants.INFO_CLIENT_REQUEST_URL, url); - params.put(CaptureConstants.INFO_CLIENT_REQUEST_ACTION, "Consumer." + method.getName()); - params.put(CaptureConstants.INFO_CLIENT_APPID, applicationId); - params.put(CaptureConstants.INFO_CLIENT_TYPE, "rabbitmq.client"); - - if (logger.isDebugable()) { - logger.debug("Invoke START:" + url + ",op=Consumer." + method.getName(), null); - } - - UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, - Monitor.CapturePhase.PRECAP, params); - // 调用链只关心真正消费消息 - if (method.getName().equals("handleDelivery")) { - - AMQP.BasicProperties props = (BasicProperties) args[2]; - if (props.getHeaders() != null - && props.getHeaders().containsKey(InvokeChainConstants.PARAM_MQHEAD_SPANINFO)) { - params.put(InvokeChainConstants.PARAM_MQHEAD_SPANINFO, - props.getHeaders().get(InvokeChainConstants.PARAM_MQHEAD_SPANINFO) + ""); - params.put(CaptureConstants.INFO_APPSERVER_CONNECTOR_REQUEST_URL, url); - } - - // register adapter - UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", - "registerAdapter", RabbitmqConsumerAdapter.class); - - UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", - InvokeChainConstants.CHAIN_APP_SERVICE, InvokeChainConstants.CapturePhase.PRECAP, params, - RabbitmqConsumerAdapter.class, args); - } - - } - - @Override - public void catchInvokeException(Consumer t, Object proxy, Method method, Object[] args, Throwable e) { - - doCap(-1, channel, t, method, e); - - } - - @Override - public Object postProcess(Object res, Consumer operation, Object proxy, Method method, Object[] args) { - - doCap(1, channel, operation, method, null); - return null; - } - - private void doCap(int rc, Channel channel, Consumer consumer, Method method, Throwable e) { - - if (null == targetServer) { - Map conn = channel.getConnection().getServerProperties(); - String cluster_name = (null == conn.get("cluster_name")) ? "unknown" - : conn.get("cluster_name").toString(); - String version = (null == conn.get("version")) ? "unknown" : conn.get("version").toString(); - targetServer = cluster_name + "@" + version; - } - - Map params = new HashMap(); - - params.put(CaptureConstants.INFO_CLIENT_TARGETSERVER, targetServer); - params.put(CaptureConstants.INFO_CLIENT_RESPONSECODE, rc); - - if (logger.isDebugable()) { - logger.debug("Invoke END: rc=" + rc + "," + targetServer, null); - } - - UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, - Monitor.CapturePhase.DOCAP, params); - - if (method.getName().equals("handleDelivery")) { - params.put(CaptureConstants.INFO_APPSERVER_CONNECTOR_REQUEST_URL, url); - params.put(CaptureConstants.INFO_CLIENT_APPID, applicationId); - params.put(InvokeChainConstants.CLIENT_IT_CLASS, consumer.getClass().getName()); - // 调用链只关心一个方法 - params.put(InvokeChainConstants.CLIENT_IT_METHOD, "handleDelivery"); - params.put(CaptureConstants.INFO_CLIENT_RESPONSECODE, rc); - if (rc == -1) { - params.put(CaptureConstants.INFO_CLIENT_RESPONSESTATE, e.toString()); - } - - // invoke chain - UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", - InvokeChainConstants.CHAIN_APP_SERVICE, InvokeChainConstants.CapturePhase.DOCAP, params, - RabbitmqConsumerAdapter.class, null); - } - } - - } - -} +/*- + * << + * UAVStack + * == + * Copyright (C) 2016 - 2017 UAVStack + * == + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * >> + */ + +package com.creditease.uav.hook.rabbitmq.interceptors; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.creditease.monitor.UAVServer; +import com.creditease.monitor.captureframework.spi.CaptureConstants; +import com.creditease.monitor.captureframework.spi.Monitor; +import com.creditease.monitor.proxy.spi.JDKProxyInvokeHandler; +import com.creditease.monitor.proxy.spi.JDKProxyInvokeProcessor; +import com.creditease.uav.apm.invokechain.spi.InvokeChainConstants; +import com.creditease.uav.common.BaseComponent; +import com.creditease.uav.hook.rabbitmq.adapter.RabbitmqConsumerAdapter; +import com.creditease.uav.hook.rabbitmq.adapter.RabbitmqProducerAdapter; +import com.creditease.uav.util.JDKProxyInvokeUtil; +import com.rabbitmq.client.AMQP; +import com.rabbitmq.client.AMQP.BasicProperties; +import com.rabbitmq.client.Channel; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.Consumer; + +public class RabbitmqIT extends BaseComponent { + + private String applicationId; + static final Map queueNameIndex = new HashMap(); + static { + queueNameIndex.put("basicPublish", 1); + queueNameIndex.put("queueDeclare", 0); + queueNameIndex.put("queueDeclareNoWait", 0); + queueNameIndex.put("queueDeclarePassive", 0); + queueNameIndex.put("queueDelete", 0); + queueNameIndex.put("queueDeleteNoWait", 0); + queueNameIndex.put("queueBind", 0); + queueNameIndex.put("queueBindNoWait", 0); + queueNameIndex.put("queueUnbind", 0); + queueNameIndex.put("queuePurge", 0); + queueNameIndex.put("basicGet", 0); + queueNameIndex.put("basicConsume", 0); + } + + public RabbitmqIT(String appid) { + this.applicationId = appid; + } + + public Connection doInstall(Connection arg) { + + arg = JDKProxyInvokeUtil.newProxyInstance(Connection.class.getClassLoader(), + new Class[] { Connection.class }, + new JDKProxyInvokeHandler(arg, new ConnectionProxyProcessor())); + + return arg; + } + + /** + * + * ConnectionProxyProcessor description: ConnectionProxyProcessor + * + */ + public class ConnectionProxyProcessor extends JDKProxyInvokeProcessor { + + @Override + public void preProcess(Connection t, Object proxy, Method method, Object[] args) { + + } + + @Override + public Object postProcess(Object res, Connection t, Object proxy, Method method, Object[] args) { + + if (method.getName().equals("createChannel")) { + return JDKProxyInvokeUtil.newProxyInstance(Channel.class.getClassLoader(), + new Class[] { Channel.class }, + new JDKProxyInvokeHandler((Channel) res, new ChannelProxyProcessor())); + } + return null; + } + + } + + /** + * + * ChannelProxyProcessor description: ChannelProxyProcessor + * + */ + public class ChannelProxyProcessor extends JDKProxyInvokeProcessor { + + String address; + String targetServer; + private Map ivcContextParams = new HashMap(); + + @SuppressWarnings("unchecked") + @Override + public void preProcess(Channel t, Object proxy, Method method, Object[] args) { + + if (method.getExceptionTypes().length > 0 + && method.getExceptionTypes()[0].getName().equals(IOException.class.getName())) { + String methodName = method.getName(); + String queueName = null; + if (queueNameIndex.containsKey(methodName) && args.length != 0) { + + queueName = (String) args[queueNameIndex.get(methodName)]; + if (isTempQueue(queueName)) { + return; + } + + } + + if (null == address) { + address = t.getConnection().getAddress().getHostAddress() + ":" + t.getConnection().getPort(); + address = "mq:rabbit://" + address; + } + String url = address + ((null == queueName) ? "" : "/" + queueName); + + if ("basicConsume".equals(method.getName())) { + // delegate the consumer + args[args.length - 1] = JDKProxyInvokeUtil.newProxyInstance(Consumer.class.getClassLoader(), + new Class[] { Consumer.class }, new JDKProxyInvokeHandler( + (Consumer) args[args.length - 1], new ConsumerProxyProcessor(t, url))); + + } + + Map params = new HashMap(); + params.put(CaptureConstants.INFO_CLIENT_REQUEST_URL, url); + params.put(CaptureConstants.INFO_CLIENT_REQUEST_ACTION, method.getName()); + params.put(CaptureConstants.INFO_CLIENT_APPID, applicationId); + params.put(CaptureConstants.INFO_CLIENT_TYPE, "rabbitmq.client"); + + if (logger.isDebugable()) { + logger.debug("Invoke START:" + url + ",op=" + method.getName(), null); + } + + UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, + Monitor.CapturePhase.PRECAP, params); + + // 调用链只关心真正的消息通讯 + if (method.getName().equals("basicPublish")) { + + // register adapter + UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", + "registerAdapter", RabbitmqProducerAdapter.class); + + ivcContextParams = (Map) UAVServer.instance().runSupporter( + "com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", + InvokeChainConstants.CHAIN_APP_CLIENT, InvokeChainConstants.CapturePhase.PRECAP, params, + RabbitmqProducerAdapter.class, + new Object[] { (BasicProperties) args[args.length - 2], args[args.length - 1] }); + if (ivcContextParams != null + && ivcContextParams.containsKey(InvokeChainConstants.PARAM_MQHEAD_INFO)) { + args[args.length - 2] = ivcContextParams.get(InvokeChainConstants.PARAM_MQHEAD_INFO); + } + } + } + } + + @Override + public Object postProcess(Object res, Channel t, Object proxy, Method method, Object[] args) { + + if (needDoCap(method, args)) { + doCap(1, t, method, null); + } + + return null; + } + + @Override + public void catchInvokeException(Channel t, Object proxy, Method method, Object[] args, Throwable e) { + + if (needDoCap(method, args)) { + doCap(-1, t, method, e); + } + + } + + private boolean needDoCap(Method method, Object[] args) { + + if (method.getExceptionTypes().length == 0 + || !method.getExceptionTypes()[0].getName().equals(IOException.class.getName())) { + return false; + } + String methodName = method.getName(); + if (queueNameIndex.containsKey(methodName) && args.length != 0) { + + if (isTempQueue((String) args[queueNameIndex.get(methodName)])) { + return false; + } + } + return true; + } + + private void doCap(int rc, Channel t, Method method, Throwable e) { + + if (null == targetServer) { + Map conn = t.getConnection().getServerProperties(); + String cluster_name = (null == conn.get("cluster_name")) ? "unknown" + : conn.get("cluster_name").toString(); + String version = (null == conn.get("version")) ? "unknown" : conn.get("version").toString(); + targetServer = cluster_name + "@" + version; + } + + Map params = new HashMap(); + + params.put(CaptureConstants.INFO_CLIENT_TARGETSERVER, targetServer); + params.put(CaptureConstants.INFO_CLIENT_RESPONSECODE, rc); + + if (logger.isDebugable()) { + logger.debug("Invoke END: rc=" + rc + "," + targetServer, null); + } + + UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, + Monitor.CapturePhase.DOCAP, params); + + // 调用链只关心真正的消息通讯 + if (method.getName().equals("basicPublish")) { + + if (rc == -1) { + ivcContextParams.put(CaptureConstants.INFO_CLIENT_RESPONSESTATE, e.toString()); + } + if (ivcContextParams != null) { + ivcContextParams.putAll(params); + } + + UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", + InvokeChainConstants.CHAIN_APP_CLIENT, InvokeChainConstants.CapturePhase.DOCAP, + ivcContextParams, RabbitmqProducerAdapter.class, null); + } + + } + + public boolean isTempQueue(String queueName) { + + String regEx = "^([0-9]|[a-f]){8}(-([0-9]|[a-f]){4}){3}-([0-9]|[a-f]){12}$"; + Matcher matcher = Pattern.compile(regEx).matcher(queueName); + return matcher.matches(); + + } + } + + public class ConsumerProxyProcessor extends JDKProxyInvokeProcessor { + + private Channel channel; + private String url; + private String targetServer; + + public ConsumerProxyProcessor(Channel channel, String url) { + this.channel = channel; + this.url = url; + } + + @Override + public void preProcess(Consumer t, Object proxy, Method method, Object[] args) { + + Map params = new HashMap(); + params.put(CaptureConstants.INFO_CLIENT_REQUEST_URL, url); + params.put(CaptureConstants.INFO_CLIENT_REQUEST_ACTION, "Consumer." + method.getName()); + params.put(CaptureConstants.INFO_CLIENT_APPID, applicationId); + params.put(CaptureConstants.INFO_CLIENT_TYPE, "rabbitmq.client"); + + if (logger.isDebugable()) { + logger.debug("Invoke START:" + url + ",op=Consumer." + method.getName(), null); + } + + UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, + Monitor.CapturePhase.PRECAP, params); + // 调用链只关心真正消费消息 + if (method.getName().equals("handleDelivery")) { + + AMQP.BasicProperties props = (BasicProperties) args[2]; + if (props.getHeaders() != null + && props.getHeaders().containsKey(InvokeChainConstants.PARAM_MQHEAD_SPANINFO)) { + params.put(InvokeChainConstants.PARAM_MQHEAD_SPANINFO, + props.getHeaders().get(InvokeChainConstants.PARAM_MQHEAD_SPANINFO) + ""); + params.put(CaptureConstants.INFO_APPSERVER_CONNECTOR_REQUEST_URL, url); + } + + // register adapter + UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", + "registerAdapter", RabbitmqConsumerAdapter.class); + + UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", + InvokeChainConstants.CHAIN_APP_SERVICE, InvokeChainConstants.CapturePhase.PRECAP, params, + RabbitmqConsumerAdapter.class, args); + } + + } + + @Override + public void catchInvokeException(Consumer t, Object proxy, Method method, Object[] args, Throwable e) { + + doCap(-1, channel, t, method, e); + + } + + @Override + public Object postProcess(Object res, Consumer operation, Object proxy, Method method, Object[] args) { + + doCap(1, channel, operation, method, null); + return null; + } + + private void doCap(int rc, Channel channel, Consumer consumer, Method method, Throwable e) { + + if (null == targetServer) { + Map conn = channel.getConnection().getServerProperties(); + String cluster_name = (null == conn.get("cluster_name")) ? "unknown" + : conn.get("cluster_name").toString(); + String version = (null == conn.get("version")) ? "unknown" : conn.get("version").toString(); + targetServer = cluster_name + "@" + version; + } + + Map params = new HashMap(); + + params.put(CaptureConstants.INFO_CLIENT_TARGETSERVER, targetServer); + params.put(CaptureConstants.INFO_CLIENT_RESPONSECODE, rc); + + if (logger.isDebugable()) { + logger.debug("Invoke END: rc=" + rc + "," + targetServer, null); + } + + UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, + Monitor.CapturePhase.DOCAP, params); + + if (method.getName().equals("handleDelivery")) { + params.put(CaptureConstants.INFO_APPSERVER_CONNECTOR_REQUEST_URL, url); + params.put(CaptureConstants.INFO_CLIENT_APPID, applicationId); + params.put(InvokeChainConstants.CLIENT_IT_CLASS, consumer.getClass().getName()); + // 调用链只关心一个方法 + params.put(InvokeChainConstants.CLIENT_IT_METHOD, "handleDelivery"); + params.put(CaptureConstants.INFO_CLIENT_RESPONSECODE, rc); + if (rc == -1) { + params.put(CaptureConstants.INFO_CLIENT_RESPONSESTATE, e.toString()); + } + + // invoke chain + UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", + InvokeChainConstants.CHAIN_APP_SERVICE, InvokeChainConstants.CapturePhase.DOCAP, params, + RabbitmqConsumerAdapter.class, null); + } + } + + } + +} From 35734a18a5b5bf871b49ee62ea0a2fe6b1324d92 Mon Sep 17 00:00:00 2001 From: minglangyang Date: Fri, 13 Apr 2018 16:32:28 +0800 Subject: [PATCH 5/6] https://github.com/uavorg/uavstack/issues/251 1.code format --- .../notifystgy/css/uav.notifystgy.css | 784 ++-- .../notifystgy/js/notifystgy.win.js | 3302 ++++++++--------- .../feature/runtimenotify/NotifyStrategy.java | 1124 +++--- .../task/JudgeNotifyTimerTask.java | 518 +-- .../agent/helpers/DateTimeHelper.java | 2016 +++++----- .../rabbitmq/interceptors/RabbitmqIT.java | 730 ++-- 6 files changed, 4237 insertions(+), 4237 deletions(-) diff --git a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/css/uav.notifystgy.css b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/css/uav.notifystgy.css index d8110b54..045c7162 100644 --- a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/css/uav.notifystgy.css +++ b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/css/uav.notifystgy.css @@ -1,393 +1,393 @@ -@CHARSET "UTF-8"; -/*原子布局 BEGINI*/ -html { - height: 100%; -} - -body { - font-size: 14px; - font-family: "微软雅黑"; - margin-top: 0px; - margin-left: 0px; - margin-right: 0px; - margin-bottom: 0px; - text-align: center; - height: 100%; -} - -.ListBG { - background: white; - color: black; - font-size: 14px; -} - -.ObjectBG { - background: white; - color: black; - font-size: 14px; -} - -.ObjectBG input,select,textarea,.selectDiv{ - width: 50%; - height: 34px; - border-radius: 2px; - min-width: 340px; - margin-top:1px; -} - -.selectDiv{ - display: inline-flex; -} - -.ObjectBG textarea{ - resize: none; - height:50px; -} - -.ObjectBG .well{ - width: 50%; - min-width: 340px; - border-radius: 2px; - margin: 0 auto; - padding:0px; - text-align:left; -} - -.well-title{ - float: left; - margin-top:3px; - margin-left:3px; - color: white; -} - -.well-title-div{ - background-color: #009ad6; - text-align: right; - width: 100%; - color: white; -} -.well-add{ - font-size: 18px; - margin-top:3px; - margin-right:7px; -} - -.well-add:hover { - border-radius: 3px; - box-shadow: 0 0 1px 1px white; -} - -.well-list{ - margin-top:2px; - margin-left:3px; - border-bottom: dotted 1px #999; -} -.well-list:hover{ - background: #cae4ff; -} -.well-del{ - font-size: 18px; - float: right; - margin-right:7px; -} -.well-del:hover { - border-radius: 3px; - box-shadow: 0 0 1px 1px #ff0000; -} -.well-edit{ - font-size: 18px; - float: right; - margin-right:20px; -} -.well-edit:hover { - border-radius: 3px; - box-shadow: 0 0 1px 1px #000000; -} -.icon-myout,.icon-myhelp { - float: right; - margin-top: 5px; - margin-right: 15px; - font-size: 2em; -} - -.icon-myout:hover { - border-radius: 3px; - box-shadow: 0 0 4px 4px #ffffff; -} - -.icon-myhelp{ - height: 31.4px; - width: 31.4px; - - } - -.icon-myhelp:hover{ - border-radius: 50px; - box-shadow: 0 0 4px 4px #ffffff; -} - -.titleDiv { - font-size: 16px; - color: #ffffff; - background-color: #009ad6; - height: 43px; - line-height:43px; -} - -.titleDiv-stgy-nodata{ - color: black; - margin-left: -85px; -} - -.conditions select{ - min-width: 200px; - width: 200px; -} - -.conditions input{ - width: 200px; - display: inline -} - - -/*下拉框按钮CSS*/ -.selBut{ - width: 90%; - text-align: left; - padding:0px; -} -.selBut_but{ - width: 10%; -} -.selBut_must{ - width: 90%; - text-align: left; - border:solid 1px red; -} - -.input_must{ - text-align: left; - border:solid 1px red; -} -.input_update{ - text-align: left; - border:solid 1px green; -} - -.input_must:focus{ - border:0px; -} -.defNone{ - display:none; -} - -.displayMsgInput{ - display: inline-block; - text-align: left; - background-color: #cde6c7; - padding-top: 4px; - padding-left: 2px; - border:0px; -} - -.displayMsgTitle{ - border:0px; - font-weight: 900; -} -.listIndex{ - color : black; - border-radius: 3px 3px 3px 3px; - background-color: #dddddd; -} -.listIndex > hr{ - margin:0px; - border-top: 1px solid #ffffff; - -} -.listIndex_server{ - color : #ffffff; - background-color: #0aaaaa; -} -.listIndex_client{ - color : #ffffff; - background-color: #a6c166; -} -.listIndex_log{ - color : #ffffff; - background-color: #c99f32; -} -.listIndex_appmetrics{ - color : #ffffff; - background-color: #970097; -} -/**重写CSS*/ -.table>tbody>tr>td{ - vertical-align:middle; -} - - -.titleMsgDiv{ - margin-top: -34px; - height: 34px; -} - -/**时间控件按钮样式**/ -.control-group { - margin-bottom: 10px; -} - -.control-group input { - background-color: #eeeeee; - border:1px solid #cccccc; - border-radius:4px 0 0 4px; - padding: 4px 6px; - color:#333333 -} -.control-group .add-on { - background-color: #eeeeee; - border:1px solid #cccccc; - border-radius:0 4px 4px 0; - padding: 4.5px 6px; - color:#333333 -} - -/** -*条件定义 -*/ -.btn-default.active:focus{ - color: #333; - background-color: #d4d4d4; - border-color: #8c8c8c; -} - -.btn-default.active, .btn-default:active{ - color: #333; - background-color: #d4d4d4; - border-color: #337ab7; -} - -/** -*触发策略 begin -*/ -.StgyDiv .edit-div-where{ - font-size: 14px; - width: 95%; - border-radius: 2px; - margin: 0 auto; - text-align:left; - padding: 5px; - margin-top: 5px; - margin-bottom: 5px; - border:solid 1px green; -} - -.StgyDiv .edit-div{ - font-size: 14px; - height: 130px; - width: 95%; - min-width: 340px; - border-radius: 2px; - margin: 0 auto; - text-align:left; - padding: 5px; - overflow-y:auto; - color:#000000; -} - -.StgyDiv .edit-div:empty:before{ - content: attr(placeholder); - color:darkgrey; -} - -.StgyDiv .edit-div-option{ - font-size: 14px; - height: 50px; - width: 95%; - min-width: 340px; - border-radius: 2px; - border-color:#000000; - margin: 0 auto; - text-align:left; - padding: 5px; - margin-top: 5px; - overflow-y:auto; - color:#000000; -} - -StgyDiv .edit-div-option:empty:before{ - content: attr(placeholder); - color:darkgrey; -} - -.whereStgyEdit{ - border-radius: 4px; -} -.whereStgyEdit-success{ - background-color: #dddddd; - color:#000000; - display: inline-block; - margin: 1px; -} -.whereStgyEdit-delete{ - text-decoration: line-through; - border: solid 1px red; - color: red; - display: inline-block; - margin: 1px; -} - -.btn-success { - margin: 5px; - color: #000000; - padding: 3px 10px; - background-color: #ffffff; - border-color: #3c763d; -} -.btn-success:hover { - color: #000000; - background-color: #dddddd; -} - -.well-list-display{ - display: -webkit-box; - padding-bottom: 5px; - padding-top: 5px; -} -.action-textarea-delete{ - display: inline-flex; - position: absolute; - margin-top: 17px; - margin-left: 5px; -} - -.action-textarea-delete span{ - border:solid 1px #ffffff; - font-size: 18px; -} -.action-textarea-delete span:hover{ - font-size: 18px; - border:solid 1px red; - border-radius: 2px; -} - -/** -*触发策略 end -*/ - -.itemTitle { - text-align:left; - color:#333; - border-left:6px solid #57A69C; - padding-left:5px; - margin-bottom:2px; -} - -.itemTip { - color:gray; - font-size:14px; - text-align:left; -} - -.dateTimeInput { - width:120px; +@CHARSET "UTF-8"; +/*原子布局 BEGINI*/ +html { + height: 100%; +} + +body { + font-size: 14px; + font-family: "微软雅黑"; + margin-top: 0px; + margin-left: 0px; + margin-right: 0px; + margin-bottom: 0px; + text-align: center; + height: 100%; +} + +.ListBG { + background: white; + color: black; + font-size: 14px; +} + +.ObjectBG { + background: white; + color: black; + font-size: 14px; +} + +.ObjectBG input,select,textarea,.selectDiv{ + width: 50%; + height: 34px; + border-radius: 2px; + min-width: 340px; + margin-top:1px; +} + +.selectDiv{ + display: inline-flex; +} + +.ObjectBG textarea{ + resize: none; + height:50px; +} + +.ObjectBG .well{ + width: 50%; + min-width: 340px; + border-radius: 2px; + margin: 0 auto; + padding:0px; + text-align:left; +} + +.well-title{ + float: left; + margin-top:3px; + margin-left:3px; + color: white; +} + +.well-title-div{ + background-color: #009ad6; + text-align: right; + width: 100%; + color: white; +} +.well-add{ + font-size: 18px; + margin-top:3px; + margin-right:7px; +} + +.well-add:hover { + border-radius: 3px; + box-shadow: 0 0 1px 1px white; +} + +.well-list{ + margin-top:2px; + margin-left:3px; + border-bottom: dotted 1px #999; +} +.well-list:hover{ + background: #cae4ff; +} +.well-del{ + font-size: 18px; + float: right; + margin-right:7px; +} +.well-del:hover { + border-radius: 3px; + box-shadow: 0 0 1px 1px #ff0000; +} +.well-edit{ + font-size: 18px; + float: right; + margin-right:20px; +} +.well-edit:hover { + border-radius: 3px; + box-shadow: 0 0 1px 1px #000000; +} +.icon-myout,.icon-myhelp { + float: right; + margin-top: 5px; + margin-right: 15px; + font-size: 2em; +} + +.icon-myout:hover { + border-radius: 3px; + box-shadow: 0 0 4px 4px #ffffff; +} + +.icon-myhelp{ + height: 31.4px; + width: 31.4px; + + } + +.icon-myhelp:hover{ + border-radius: 50px; + box-shadow: 0 0 4px 4px #ffffff; +} + +.titleDiv { + font-size: 16px; + color: #ffffff; + background-color: #009ad6; + height: 43px; + line-height:43px; +} + +.titleDiv-stgy-nodata{ + color: black; + margin-left: -85px; +} + +.conditions select{ + min-width: 200px; + width: 200px; +} + +.conditions input{ + width: 200px; + display: inline +} + + +/*下拉框按钮CSS*/ +.selBut{ + width: 90%; + text-align: left; + padding:0px; +} +.selBut_but{ + width: 10%; +} +.selBut_must{ + width: 90%; + text-align: left; + border:solid 1px red; +} + +.input_must{ + text-align: left; + border:solid 1px red; +} +.input_update{ + text-align: left; + border:solid 1px green; +} + +.input_must:focus{ + border:0px; +} +.defNone{ + display:none; +} + +.displayMsgInput{ + display: inline-block; + text-align: left; + background-color: #cde6c7; + padding-top: 4px; + padding-left: 2px; + border:0px; +} + +.displayMsgTitle{ + border:0px; + font-weight: 900; +} +.listIndex{ + color : black; + border-radius: 3px 3px 3px 3px; + background-color: #dddddd; +} +.listIndex > hr{ + margin:0px; + border-top: 1px solid #ffffff; + +} +.listIndex_server{ + color : #ffffff; + background-color: #0aaaaa; +} +.listIndex_client{ + color : #ffffff; + background-color: #a6c166; +} +.listIndex_log{ + color : #ffffff; + background-color: #c99f32; +} +.listIndex_appmetrics{ + color : #ffffff; + background-color: #970097; +} +/**重写CSS*/ +.table>tbody>tr>td{ + vertical-align:middle; +} + + +.titleMsgDiv{ + margin-top: -34px; + height: 34px; +} + +/**时间控件按钮样式**/ +.control-group { + margin-bottom: 10px; +} + +.control-group input { + background-color: #eeeeee; + border:1px solid #cccccc; + border-radius:4px 0 0 4px; + padding: 4px 6px; + color:#333333 +} +.control-group .add-on { + background-color: #eeeeee; + border:1px solid #cccccc; + border-radius:0 4px 4px 0; + padding: 4.5px 6px; + color:#333333 +} + +/** +*条件定义 +*/ +.btn-default.active:focus{ + color: #333; + background-color: #d4d4d4; + border-color: #8c8c8c; +} + +.btn-default.active, .btn-default:active{ + color: #333; + background-color: #d4d4d4; + border-color: #337ab7; +} + +/** +*触发策略 begin +*/ +.StgyDiv .edit-div-where{ + font-size: 14px; + width: 95%; + border-radius: 2px; + margin: 0 auto; + text-align:left; + padding: 5px; + margin-top: 5px; + margin-bottom: 5px; + border:solid 1px green; +} + +.StgyDiv .edit-div{ + font-size: 14px; + height: 130px; + width: 95%; + min-width: 340px; + border-radius: 2px; + margin: 0 auto; + text-align:left; + padding: 5px; + overflow-y:auto; + color:#000000; +} + +.StgyDiv .edit-div:empty:before{ + content: attr(placeholder); + color:darkgrey; +} + +.StgyDiv .edit-div-option{ + font-size: 14px; + height: 50px; + width: 95%; + min-width: 340px; + border-radius: 2px; + border-color:#000000; + margin: 0 auto; + text-align:left; + padding: 5px; + margin-top: 5px; + overflow-y:auto; + color:#000000; +} + +StgyDiv .edit-div-option:empty:before{ + content: attr(placeholder); + color:darkgrey; +} + +.whereStgyEdit{ + border-radius: 4px; +} +.whereStgyEdit-success{ + background-color: #dddddd; + color:#000000; + display: inline-block; + margin: 1px; +} +.whereStgyEdit-delete{ + text-decoration: line-through; + border: solid 1px red; + color: red; + display: inline-block; + margin: 1px; +} + +.btn-success { + margin: 5px; + color: #000000; + padding: 3px 10px; + background-color: #ffffff; + border-color: #3c763d; +} +.btn-success:hover { + color: #000000; + background-color: #dddddd; +} + +.well-list-display{ + display: -webkit-box; + padding-bottom: 5px; + padding-top: 5px; +} +.action-textarea-delete{ + display: inline-flex; + position: absolute; + margin-top: 17px; + margin-left: 5px; +} + +.action-textarea-delete span{ + border:solid 1px #ffffff; + font-size: 18px; +} +.action-textarea-delete span:hover{ + font-size: 18px; + border:solid 1px red; + border-radius: 2px; +} + +/** +*触发策略 end +*/ + +.itemTitle { + text-align:left; + color:#333; + border-left:6px solid #57A69C; + padding-left:5px; + margin-bottom:2px; +} + +.itemTip { + color:gray; + font-size:14px; + text-align:left; +} + +.dateTimeInput { + width:120px; } \ No newline at end of file diff --git a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/js/notifystgy.win.js b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/js/notifystgy.win.js index 5671d8b0..2e61cdc8 100644 --- a/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/js/notifystgy.win.js +++ b/com.creditease.uav.console/src/main/webapp/uavapp_godeye/notifystgy/js/notifystgy.win.js @@ -1,1652 +1,1652 @@ -/** - * 窗体初始化 - */ -window.winmgr.build({ - id : "notifyList", - height : "auto", - "overflow-y" : "auto", - order : 999, - theme : "ListBG" -}); -window.winmgr.build({ - id : "objectDiv", - height : "auto", - "overflow-y" : "auto", - order : 999, - theme : "ObjectBG" -}); -window.winmgr.build({ - id : "stgyDiv", - height : "auto", - "overflow-y" : "auto", - order : 999, - theme : "StgyDiv" -}); -window.winmgr.build({ - id : "condDiv", - height : "auto", - "overflow-y" : "auto", - order : 999, - theme : "condDiv" -}); -window.winmgr.show("notifyList"); - -/** - * 操作配置 - */ -var actionConf = { - actionObj:null //操作对象 -} -/** - * 下拉框UI - * */ -var selUiConf = { - keys:[ - - {"key":"server","value":"自定义指标"}, - {"key":"server","value":"服务端"}, - {"key":"client","value":"客户端"}, - {"key":"log","value":"日志"} - ], - "server":[ - ["procState","进程状态指标系"], - ["hostState","应用容器状态指标系"], - ["urlResp","服务状态指标系"], - ["appResp","应用状态指标系"], - ["serverResp","应用服务器状态指标系"], - ["procCrash","进程死亡指标系"] - ], - "client":[ - ["clientResp","调用状态指标系"] - ], - "log":[ - ["log","日志"] - ] - , - "userDef":[ - ["jvm","Java虚拟机状态指标系"] - ] - , - userInput:{ - "notifyNameF":"", - "notifyNameM":"", - "notifyNameI":"" - } - -} - -var supportJTA = ["服务状态指标系","应用状态指标系","应用服务器状态指标系","调用状态指标系"]; -/** - * 初始化头部 - */ -function initHeadDiv() { - var divContent = "" - + "
" - - + "" - - + "" - - + "" - - + "
" - + "" - - + "" - + "
" + "
" + ""; - HtmlHelper.id("notifyList").innerHTML += divContent; -} - -/** - * 显示添加策略 - */ -function showAddDiv() { - - var sb=new StringBuffer(); - sb.append( "
"); - sb.append( ""); - sb.append( ""); - sb.append( ""); - sb.append( "添加策略"); - sb.append( "
"); - sb.append( "
"); - sb.append( "
"); - sb.append( "
"); - - sb.append( '
'); - - - sb.append( '
'); - sb.append(''); - sb.append('
'); - sb.append(''); - sb.append(''); - sb.append(''); - sb.append('
'); - sb.append('
'); - - sb.append('
'); - sb.append('
'); - sb.append(''); - sb.append(''); - sb.append(''); - sb.append('
'); - sb.append( '
'); - sb.append('
'); - - sb.append( '
'); - sb.append( "
"); - - - sb.append( '
'); - sb.append( '
'); - - sb.append( '
'); - sb.append( '
条件定义
'); - sb.append( '
'); - - sb.append( '
'); - sb.append( '
触发策略
'); - sb.append( '
'); - - sb.append( '
'); - sb.append( '
触发动作
'); - sb.append( '
'); - - sb.append( '
'); - sb.append( '
'); - sb.append( '
 
'); - - sb.append( ''); - - HtmlHelper.id("objectDiv").innerHTML = sb.toString(); - window.winmgr.hide("notifyList"); - window.winmgr.show("objectDiv"); - initActionDiv($("#isOwner").val()); - -} - - -/** - * 显示编辑策略 - */ -function showEditNotifyDiv(jsonObjParam) { - - var key,jsonObj,isOwner=false;enableThreadAnalysis=false; - //因为只有一对 key:value 获取key(值为id) - $.each(jsonObjParam,function(index,obj){ - key = index; - jsonObj = obj; - }); - - if(jsonObj.owner == window.parent.loginUser.userId - || window.parent.loginUser.groupId == "uav_admin" - || window.parent.loginUser.groupId == "vipgroup" - ){ - isOwner = true; - } - - var names = key.split("@"); - var cssType = "displayMsgInput",cssRedOnly = "displayMsgInput listIndex"; - var sb=new StringBuffer(); - sb.append( "
"); - sb.append( ""); - sb.append( "编辑策略"); - sb.append( "
"); - sb.append( "
"); - sb.append( "
"); - sb.append( "
"); - /** - * 所有渲染内容 div begin - */ - sb.append( '
'); - - sb.append( '
'); - if(window.parent.loginUser.groupId == "uav_admin" - || window.parent.loginUser.groupId == "vipgroup" - ){ - sb.append( '
'); - }else{ - - sb.append( '
'); - } - - - sb.append( '
'); - - //1 - var existsIns = jsonObj.instances.length>0?true:false; - var showNameF = getSelUiConfKeysValue(names[0],names[1]); - if(showNameF=="自定义指标"){ - cssType = "displayMsgInput listIndex_appmetrics"; - }else if(names[1] == "log"){ - showNameF = "日志"; - cssType = "displayMsgInput listIndex_log"; - }else if(names[0] == "server"){ - cssType = "displayMsgInput listIndex_server"; - }else if(names[0] == "client"){ - cssType = "displayMsgInput listIndex_client"; - } - sb.append( '
'); - selUiConf["userInput"]["notifyNameF"]=names[0];//编辑赋值,准备修改数据 - //2 - if(showNameF=="自定义指标"){ - selUiConf["userInput"]["notifyNameM"]=names[1];//编辑赋值,准备修改数据 - }else if(names[1] == "log"){ - sb.append( '
'); - selUiConf["userInput"]["notifyNameM"]=names[1];//编辑赋值,准备修改数据 - }else if(names[1]){ - sb.append( '
'); - selUiConf["userInput"]["notifyNameM"]=names[1];//编辑赋值,准备修改数据 - if($.inArray(getSelUiConfigValue(names[1]),supportJTA) >= 0){ - enableThreadAnalysis=true; - } - } - //3 - if(names[2] && names[1] == "log"){ - var nNameIShow = "指定日志:"+names[2]; - sb.append( '
'); - selUiConf["userInput"]["notifyNameI"]=names[2];//编辑赋值,准备修改数据 - }else if(names[1] == "log"){ - sb.append( '
'); - }else if(names[2]){ - var nNameIShow = (existsIns?"实例组:":"实例:")+names[2]; - sb.append( '
'); - selUiConf["userInput"]["notifyNameI"]=names[2];//编辑赋值,准备修改数据 - }else{ - sb.append( '
'); - } - - if(names[2] && isOwner){ - sb.append( "
'); - }else if(names[2] && !isOwner){ - sb.append( "
'); - }else if(isOwner){ - sb.append( "
'); - }else{ - sb.append( "
'); - } - - - sb.append( '
'); - if(isOwner){ - sb.append( '
'); - }else{ - sb.append( '
'); - } - - /** - * 初始化条件 begin - */ - sb.append( '
'); - sb.append( '
'); - sb.append( '条件定义'); - sb.append( '
'); - $.each(jsonObj.conditions,function(index,obj){ - if(obj.func && obj.func.indexOf("count>")>-1){ - obj.cparam = obj.func.substr(6); - obj.func = "count"; - } - - if(!obj.id){ - /** - * 兼容老数据 - */ - obj.id=StgyClass.randomId()+"_stgySpan"; - } - var html; - if(isOwner){ - html = '
'+StgyClass.formatShowWhere(obj)+'
'; - }else{ - html = '
'+StgyClass.formatShowWhere(obj)+'
'; - } - sb.append( html); - }); - sb.append( '
'); - sb.append( '
'); - /** - * 初始化条件 end - */ - - /** - * 初始化触发策略 begin - */ - sb.append( '
'); - - if(isOwner){ - sb.append( '
触发策略
'); - }else{ - sb.append( '
触发策略
'); - } - - if(jsonObj.relationsHtmls){ - $.each(jsonObj.relationsHtmls,function(index,html){ - var convergenceVal = ""; - if(jsonObj.hasOwnProperty("convergences")){ - convergenceVal = jsonObj.convergences[index]; - } - - var appendHtml = - '
'+ - '
'+ - '
'+html+'
'+ - '
'+convergenceVal+'
'+ - '
'; - - if(isOwner){ - appendHtml+=''; - }else{ - appendHtml+=''; - } - appendHtml+='
'+ - '
'+ - '
'; - sb.append(appendHtml); - }); - } - sb.append( '
'); - /** - * 初始化触发策略 begin - */ - - sb.append( '
'); - sb.append( '
触发动作
'); - var actionSum = 0; - initActionDiv(isOwner?"true":"false"); - if (jsonObj.action!=undefined) { - $.each(jsonObj.action,function(index,value){ - actionSum++; - var josnSpan ={ - "type":index, - "value":value - } - - var html ; - - if(isOwner){ - if("threadanalysis" == josnSpan.type){ - var html = '
'+josnSpan.type+''+JSON.stringify(josnSpan)+'
'; - }else{ - html = '
'+josnSpan.type+''+JSON.stringify(josnSpan)+'
'; - } - }else{ - html = '
'+josnSpan.type+''+JSON.stringify(josnSpan)+'
'; - } - sb.append( '
'); - sb.append( html); - sb.append( '
'); - - /** - * 计算下拉选项 - */ - $("#actionTypeSel option[value="+josnSpan.type+"]").remove(); - - }); - } - sb.append( '
'); - /** - * 初始化触发动作 end - */ - - if(isOwner){ - //按钮 - sb.append( '
'); - sb.append( '
'); - sb.append( '
 
'); - } - - sb.append( '
'); - /** - * 所有渲染内容 div end - */ - sb.append( ""); - HtmlHelper.id("objectDiv").innerHTML = sb.toString(); - - /** - * 判断出发条件:不是归属者不能添加 - */ - if(!isOwner){ - $("#whereAddButton").attr("class","well-add"); - $("#whereAddButton").click(function(){}); - } - /** - * 判断触发动作按钮 begin(类型都已经存在值,则不能再添加) - * 不是归属者也不能添加 - */ - var selTypeSize = $("#actionTypeSel option").size(); - if(selTypeSize == 0 || !isOwner){ - $("#actionAddButton").attr("class","well-add"); - $("#actionAddButton").click(function(){}); - } - /** - * 判断触发动作按钮 end - */ - window.winmgr.hide("notifyList"); - window.winmgr.show("objectDiv"); - - hideShowConStgy(names[1]); -} - - - -/** - * 触发动作添加窗口 - */ -function initActionDiv(isOwner) { - - var old = document.getElementById("actionDiv"); - if(old){ - var node = old.parentNode; - node.removeChild(old); - } - - var sb=new StringBuffer(); - - sb.append(''); - var div = document.createElement('div'); - div.innerHTML = sb.toString(); - document.body.appendChild(div); -} - -/** - * 显示添加条件窗口 - * @param thisObj - * @param type - */ -function showCon(thisObj,type){ - actionConf.actionObj=thisObj.parentNode; - if(selUiConf["userInput"]["notifyNameM"]=="log"){ - $("#condType").attr("disabled","disabled"); - } - $("#pageType").val(type); - if("EDIT" == type){ - var jsonValue = JSON.parse(thisObj.parentNode.getElementsByTagName("span")[0].textContent); - $("#condType").attr("disabled","disabled"); - var isOwner = $("#isOwner").val(); - if(!jsonValue.type||jsonValue.type=="stream"){ - $("#condType").val("stream"); - $("#contExpr").val(jsonValue.expr); - $("#conRange").val(jsonValue.range); - $("#conFunc").val((null == jsonValue.func?0:jsonValue.func)); - if("count" == jsonValue.func){ - $("#conFuncParam").val(jsonValue.cparam); - $("#conFuncParam").show(); - } - //不是归属用户,则只读 - if(isOwner!="true"){ - $("#whereSaveButton").hide(); - $("#contExpr").attr("readonly","readonly"); - $("#conRange").attr("readonly","readonly"); - $("#conFunc").attr("disabled","disabled"); - $("#conFuncParam").attr("readonly","readonly"); - - //只读CSS - $("#contExpr").attr("class","form-control"); - $("#conRange").attr("class","form-control"); - $("#conFuncParam").attr("class","form-control"); - $("#whereSaveButton").hide(); - } - - }else{ - var type; - if(jsonValue.interval){ - type="link-relative"; - }else{ - type="base-relative"; - } - $("#condType").val(type); - typeChangeShow(type); - - var hour=jsonValue.time_from.split(':')[0]; - var min=jsonValue.time_from.split(':')[1]; - $('#time_from_div').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); - hour=jsonValue.time_to.split(':')[0]; - min=jsonValue.time_to.split(':')[1]; - $('#time_to_div').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); - - if(jsonValue.time_start!=undefined&&jsonValue.time_end!=undefined){ - hour=jsonValue.time_start.split(':')[0]; - min=jsonValue.time_start.split(':')[1]; - $('#time_start_div').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); - hour=jsonValue.time_end.split(':')[0]; - min=jsonValue.time_end.split(':')[1]; - $('#time_end_div').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); - } - - if(jsonValue.day_start!=undefined&&jsonValue.day_end!=undefined){ - var year=jsonValue.day_start.split('-')[0]; - var month=jsonValue.day_start.split('-')[1]; - var day=jsonValue.day_start.split('-')[2]; - $('#day_start_div').data('datetimepicker').setLocalDate(new Date(year, month-1, day, 0, 0)); - year=jsonValue.day_end.split('-')[0]; - month=jsonValue.day_end.split('-')[1]; - day=jsonValue.day_end.split('-')[2]; - $('#day_end_div').data('datetimepicker').setLocalDate(new Date(year, month-1, day, 0, 0)); - } - - showWeekDay(jsonValue.weekdayLimit); - - $("#conMetric").val(jsonValue.metric); - $("#conUpperLimit").val(jsonValue.upperLimit); - $("#conLowerLimit").val(jsonValue.lowerLimit); - $("#conAggr").val(jsonValue.aggr); - $("#conDownSample").val(jsonValue.downsample); - if(type=="link-relative"){ - $("#conInterval").val(jsonValue.interval); - } - showUnit(jsonValue.unit); - - if(isOwner!="true"){ - $("#time_from").attr("readonly","readonly"); - $("#time_to").attr("readonly","readonly"); - $("#time_start").attr("readonly","readonly"); - $("#time_end").attr("readonly","readonly"); - $("#day_start").attr("readonly","readonly"); - $("#day_end").attr("readonly","readonly"); - $("#conMetric").attr("readonly","readonly"); - $("#conUpperLimit").attr("readonly","readonly"); - $("#conLowerLimit").attr("readonly","readonly"); - $("#conMetric").attr("class","form-control"); - $("#conUpperLimit").attr("class","form-control"); - $("#conLowerLimit").attr("class","form-control"); - $("#conAggr").attr("disabled","disabled"); - $("#conDownSample").attr("disabled","disabled"); - if(type=="link-relative"){ - $("#conInterval").attr("readonly","readonly"); - $("#conInterval").attr("class","form-control"); - } - $("#whereSaveButton").hide(); - } - } - - } - -} - -function showUnit(unit){ - $("#unit").val(unit); - $("#opt"+unit).attr("class","btn btn-default active"); -} - -function showWeekDay(weekdayLimit){ - - for(var i=0;i"); - sb.append("条件定义"); - sb.append("
"); - sb.append(""); - sb.append( "
'); - - sb.append( '
'); - /** - * 普通预警条件编辑 - */ - sb.append( '
'); - - sb.append( '
触发表达式

'); - sb.append( '
持续时间(秒)

'); - sb.append( "
聚集操作

'); - sb.append( ')\" style="display:none" onkeyup="this.value=this.value.replace(\/\\D/g,\'\')" onafterpaste="this.value=this.value.replace(\/\\D/g,\'\')">
'); - sb.append( '
'); - - /** - * 同环比预警条件编辑 - */ - sb.append( ''); - sb.append( ''); - - /** - * 保存按钮 - */ - sb.append( '
'); - sb.append( ''); - sb.append( ''); - sb.append( '
'); - - HtmlHelper.id("condDiv").innerHTML = sb.toString(); - initTimeControl(); - showCon(thisObj,type); - window.winmgr.hide("objectDiv"); - window.winmgr.show("condDiv"); - -} - -function funcChangeShow(thisObj,showId){ - if("count" == thisObj.value){ - $("#"+showId).show(); - }else{ - $("#"+showId).hide(); - } -} - -function typeChangeShow(type){ - var divs=["stream","timer","link-relative","base-relative"]; - divs.forEach(div=>{ - $("#"+div).hide(); - }) - if("stream"!=type){ - $("#timer").show(); - } - $("#"+type).show(); - -} -/** - * 初始化时间控件 - */ -function initTimeControl(){ - $('#time_from_div').datetimepicker({ - pickDate: false, - pickSeconds: false - }); - - - $('#time_to_div').datetimepicker({ - pickDate: false, - pickSeconds: false - }); - - $('#time_start_div').datetimepicker({ - pickDate: false, - pickSeconds: false - }); - - - $('#time_end_div').datetimepicker({ - pickDate: false, - pickSeconds: false - }); - - $('#day_start_div').datetimepicker({ - pickHour: false, - pickMin: false, - pickSeconds: false - }); - - - $('#day_end_div').datetimepicker({ - pickHour: false, - pickMin: false, - pickSeconds: false - }); - - -} - -function changeTimeUnit(value){ - $("#unit").val(value); -} - - - -function actionChangeShow(type){ - if("ADD" == type){ - if("threadanalysis" == $("#actionTypeSel").val()){ - $("textarea[name='actionValue']").val("10101").hide(); - $(".btn-addPriority").hide(); - }else{ - $("textarea[name='actionValue']").val("").show(); - $(".btn-addPriority").show(); - } - }else{ - $("textarea[name='actionValue']").show(); - $(".btn-addPriority").show(); - } -} - -function selServerChangeShow(type,value,text){ - var selId = type+"_notifyNameF"; - $("#"+selId).html(text); - $("#"+selId).css("padding-left","2px"); - $("#"+type+"_notifyNameF").css("color","black"); - - hideShowConStgy("show"); - - if(text == "自定义指标"){ - $("#"+type+"_appName_div").hide(); - $("#"+type+"_notifyNameM_div").attr("class","btn-group selectDiv defNone"); - selUiConf["userInput"]["notifyNameF"]=value; - selUiConf["userInput"]["notifyNameM"]="jvm"; - $("#notifyNameI").attr("placeholder","输入监控实例名或者实例组名"); - $("#enableThreadAnalysis").val(false); - removeChoosedJTA(); - }else if(value=="log"){ - $("#"+type+"_appName_div").show(); - $("#"+type+"_notifyNameM_div").attr("class","btn-group selectDiv defNone"); - $("#notifyNameI").attr("placeholder","输入指定日志"); - selUiConf["userInput"]["notifyNameF"]=""; - selUiConf["userInput"]["notifyNameM"]=value; - $("#enableThreadAnalysis").val(false); - removeChoosedJTA(); - }else{ - $("#"+type+"_appName_div").hide(); - $("#"+type+"_notifyNameM_div").attr("class","btn-group selectDiv"); - $("#notifyNameI").attr("placeholder","输入监控实例名或者实例组名"); - $("#"+type+"_notifyNameM").css("color","darkgrey"); - $("#"+type+"_notifyNameM").html("选择监控组指标"); - document.getElementById(type+"_notifyNameM_body").innerHTML =""; - $.each(selUiConf[value],function(index,obj){ - var li = document.createElement("li"); - var a = document.createElement("a"); - a.innerHTML=obj[1]; - a.onclick=function(){selIndexChangeShow(type,obj[0],obj[1]);}; - a.href="#"; - li.appendChild(a); - document.getElementById(type+"_notifyNameM_body").appendChild(li); - }); - selUiConf["userInput"]["notifyNameF"]=value; - } - -} - -function removeChoosedJTA(){ - if(HtmlHelper.id("ChoosedJTA") != null){ - HtmlHelper.id("ChoosedJTA").remove(); - } -} - -function changeJTAStat(text){ - if($.inArray(text,supportJTA) >= 0){ - $("#enableThreadAnalysis").val(true); - if(HtmlHelper.id("ChoosedJTA") == null){ - $("#actionAddButton").attr("class","glyphicon glyphicon-plus well-add"); - $("#actionAddButton").click(function(){showAction(this,'ADD')}); - } - }else{ - $("#enableThreadAnalysis").val(false); - removeChoosedJTA(); - } -} - -function hideShowConStgy(value){ - if(value == "procCrash"){ - $("#conFatDiv").hide(); - $("#stgyFatDiv").hide(); - } - else{ - $("#conFatDiv").show(); - $("#stgyFatDiv").show(); - } -} - -function selIndexChangeShow(type,value,text){ - changeJTAStat(text); - hideShowConStgy(value); - - $("#"+type+"_notifyNameM").html(text); - $("#"+type+"_notifyNameM").css("padding-left","2px"); - $("#"+type+"_notifyNameM").css("color","black"); - selUiConf["userInput"]["notifyNameM"]=value; -} - -function appNameChange(obj){ - selUiConf["userInput"]["notifyNameF"]=obj.value; -} -function getSelUiConfigValue(indexValue){ - var result =""; - $.each(selUiConf.keys,function(value,obj1){ - $.each(selUiConf[obj1.key],function(index,obj2){ - if(obj2[0]==indexValue){ - result=obj2[1]; - return false; - } - }); - if(result!==""){ - return false; - } - }); - - return result; -} -function getSelUiConfKeysValue(a, b) { - var result = ""; - if (b == "log") { - result="日志"; - } else if (a == "server" && b == "jvm") { - result="自定义指标"; - } else if (a == "server") { - result="服务端"; - } else if (a == "client") { - result="客户端"; - } - return result; -} -function conditionsAppend(){ - if(checkFunc()){ - var jsonObject; - if("stream"==$("#condType").val()){ - jsonObject = {"type":"stream","expr":HtmlHelper.inputXSSFilter($("#contExpr").val()),"range":HtmlHelper.inputXSSFilter($("#conRange").val()),"func":HtmlHelper.inputXSSFilter($("#conFunc").val()),"cparam":HtmlHelper.inputXSSFilter($("#conFuncParam").val())}; - }else{ - jsonObject = {"type":"timer","time_from":HtmlHelper.inputXSSFilter($("#time_from").val()),"time_to":HtmlHelper.inputXSSFilter($("#time_to").val()),"metric":HtmlHelper.inputXSSFilter($("#conMetric").val()),"upperLimit":HtmlHelper.inputXSSFilter($("#conUpperLimit").val()),"lowerLimit":HtmlHelper.inputXSSFilter($("#conLowerLimit").val())}; - - if(HtmlHelper.inputXSSFilter($("#conAggr").val())!="0"){ - jsonObject["aggr"]=HtmlHelper.inputXSSFilter($("#conAggr").val()); - }else{ - jsonObject["aggr"]="avg"; - } - - if(HtmlHelper.inputXSSFilter($("#conDownSample").val())!="0"){ - jsonObject["downsample"]=HtmlHelper.inputXSSFilter($("#conDownSample").val()); - }else{ - jsonObject["downsample"]="all-avg"; - } - - if("link-relative"==$("#condType").val()){ - jsonObject["interval"]=HtmlHelper.inputXSSFilter($("#conInterval").val()); - jsonObject["unit"]=HtmlHelper.inputXSSFilter($("#unit").val()); - }else{ - jsonObject["unit"]=HtmlHelper.inputXSSFilter($("#unit").val()); - } - - if($("#time_start").val()&&$("#time_end").val()){ - jsonObject["time_start"]=HtmlHelper.inputXSSFilter($("#time_start").val()); - jsonObject["time_end"]=HtmlHelper.inputXSSFilter($("#time_end").val()); - } - - if($("#day_start").val()&&$("#day_end").val()){ - jsonObject["day_start"]=HtmlHelper.inputXSSFilter($("#day_start").val()); - jsonObject["day_end"]=HtmlHelper.inputXSSFilter($("#day_end").val()); - } - - var weekdayLimit=[]; - for(var i=0;i<7;i++){ - weekdayLimit[i]=($("#weekday"+i).attr("class")=="btn btn-default active") - } - jsonObject["weekdayLimit"]=weekdayLimit; - - } - appendConditions(jsonObject); - window.winmgr.hide("condDiv"); - window.winmgr.show("objectDiv"); - } -} - -function checkFunc(){ - - var result = true; - if("stream"==$("#condType").val()){ - if(!$("#contExpr").val()){ - result = false; - }else if("count" == $("#conFunc").val() && !$("#conFuncParam").val()){ - result = false; - } - }else{ - if(!$("#time_from").val()||!$("#time_to").val()||!$("#conMetric").val()||!$("#conUpperLimit").val()||!$("#conLowerLimit").val()){ - result = false; - } - if("link-relative"==$("#condType").val()){ - if(!$("#conInterval").val()||!$("#unit").val()){ - result = false; - } - }else{ - if(!$("#unit").val()){ - result = false; - } - } - } - - - if(result){ - $("#conditionsErrMsg").hide(); - }else{ - $("#conditionsErrMsg").show(); - } - - return result; -} -function appendConditions(jsonObj) { - var type = $("#pageType").val(); - if("ADD"==type){ - var newNode = document.createElement("div"); - var stgyDivId = StgyClass.randomId()+"_stgySpan"; - html = '
'+getHtmlAndSetId(stgyDivId)+'
'; - newNode.innerHTML = html; - actionConf.actionObj.parentNode.appendChild(newNode); - }else if("EDIT"==type){ - var oldId = actionConf.actionObj.getElementsByTagName("span")[0].id; - actionConf.actionObj.innerHTML= getHtmlAndSetId(oldId); - StgyClass.updateWhereToStgyAppend(jsonObj); - } - - function getHtmlAndSetId(stgyDivId){ - jsonObj.id = stgyDivId;//赋值id - var html = StgyClass.formatShowWhere(jsonObj)+''; - return html; - } -} -/** - * 条件窗口操作 end - */ - - -/** - * 触发动作操作 begin - */ -function showAction(thisObj,type){ - actionConf.actionObj=thisObj.parentNode; - checkJTAAction(); - $("#actiontype").val(type); - $.each($("textarea[name='actionValue']"),function(index,obj){ - if(index>0){ - removeActonTextarea(obj); - }else{ - obj.value=""; - } - }); - $("#actionDiv").modal({backdrop: 'static', keyboard: false}); - $("#actionDiv").modal(); - //还原只读 - $("#actionSaveButton").show(); - $("#actionValue").removeAttr("readonly"); - - - if("EDIT"==type){ - //不是归属用户,则只读 - var isOwner = $("#isOwner").val(); - $("#actionTypeSel").hide(); - var spanJson = JSON.parse(thisObj.parentNode.getElementsByTagName('span')[0].textContent); - - $.each(spanJson.value,function(index,value){ - /** - * 第一次循环:追加渲染 - */ - if(index>0){ - appendActionTextarea(); - } - }); - var actionTextValues = $("textarea[name='actionValue']"); - $.each(spanJson.value,function(index,value){ - /** - * 第二次循环:赋值 - */ - actionTextValues[index].value=value; - }); - - $("#actionEditType").val(spanJson.type); - - actionChangeShow("EDIT"); - if(isOwner!="true"){ - $("#actionSaveButton").hide(); - } - }else{ - $("#actionTypeSel").show(); - actionChangeShow("ADD"); - } -} - -function checkJTAAction(){ - if($("#enableThreadAnalysis").val() =="true"&& $("#actionTypeSel").find("option[value='threadanalysis']").size() == 0 && $("#ChoosedJTA").size() == 0){ - $("#actionTypeSel").append(""); - } - else if($("#enableThreadAnalysis").val() == "false" && $("#actionTypeSel").find("option[value='threadanalysis']").size() == 1){ - $("#actionTypeSel option[value=threadanalysis]").remove(); - } -} - -function actionAppend(){ - - $("#ActionErrMsg").hide(); - - if(checkAction()){ - appendActions(); - $("#actionDiv").modal('hide'); - }else{ - $("#ActionErrMsg").show(); - } -} - -function appendActionTextarea(thisObj){ - var isOwner = $("#isOwner").val(); - - var html = ''; - if(isOwner == "true"){ - html = ''; - html+= '
'; - }else{ - html = ''; - } - - var newNode = document.createElement("div"); - newNode.innerHTML = html; - document.getElementById("actionBodyDiv").appendChild(newNode); -} -function removeActonTextarea(thisObj){ - var node = thisObj.parentNode.parentNode; - node.removeChild(thisObj.parentNode); -} - -function checkAction(){ - var actionTextValues = $("textarea[name='actionValue']"); - - var checkValue = $.trim(actionTextValues[0].value); //只校验第一个必须输入 - var type = $("#actiontype").val(); - if("ADD"==type && !checkValue){ - return false; - }else if(!checkValue){ - return false; - } - - var result = false; - var actionValues = new Array(); - $.each(actionTextValues,function(index,obj){ - var values = format(obj.value); - obj.value = values; - if(values!=""){ - actionValues.push(values); - result = true; - } - }); - - if(!result){ - $("#ActionErrMsg").show(); - } - - return result; - - function format(_values){ - var result = new Array(); - var values = _values.split(","); - $.each(values,function(index,value){ - value = $.trim(value); - if(value!=""){ - result.push(value); - } - }); - - if(!result || result.length==0){ - return ""; - }else{ - return result.join(","); - } - } -} - -function appendActions() { - var type = $("#actiontype").val(); - var html = getAppendHtml(type); - - if("threadanalysis" == $("#actionTypeSel").val()){ - $("#enableThreadAnalysis").val(false); - } - if("ADD"==type){ - var newNode = document.createElement("div"); - newNode.innerHTML = html; - actionConf.actionObj.parentNode.appendChild(newNode); - - /** - * 计算下拉菜单:删除当前选项 - */ - $("#actionTypeSel option[value="+$("#actionTypeSel").val()+"]").remove(); - - /** - * 计算是否还有添加类型:添加按钮控制 - */ - var actionTypeSelect = document.getElementById("actionTypeSel"); - if(actionTypeSelect.length == 0){ - $("#actionAddButton").attr("class","well-add"); - $("#actionAddButton").click(function(){}); - } - - - }else if("EDIT"==type){ - actionConf.actionObj.parentNode.innerHTML = html; - } - - function getAppendHtml(){ - var result = new Array(); - var actionTextValues = $("textarea[name='actionValue']"); - $.each(actionTextValues,function(index,obj){ - result.push(obj.value); - }); - - var actionType =""; - if(type=="ADD"){ - actionType = $("#actionTypeSel").val(); - }else if(type=="EDIT"){ - actionType = $("#actionEditType").val(); - } - - var jsonObj = {type:HtmlHelper.inputXSSFilter(actionType),value:HtmlHelper.inputXSSFilter(result)}; - if("threadanalysis" == jsonObj.type){ - var html = '
'+jsonObj.type+''+JSON.stringify(jsonObj)+'
'; - }else{ - var html = '
'+jsonObj.type+''+JSON.stringify(jsonObj)+'
'; - } - return html; - } -} -/** - * 触发动作操作 end - */ - - -function delThisObj(thisObj) { - var node = thisObj.parentNode.parentNode; - node.removeChild(thisObj.parentNode); - StgyClass.deleteWhereToStgyAppend(thisObj); -} - -function delThisActionObj(thisObj) { - - /** - * 还原当前选项 - */ - var spanJson = JSON.parse(thisObj.parentNode.getElementsByTagName('span')[0].innerHTML); - if(spanJson.type == "threadanalysis"){ - $("#enableThreadAnalysis").val(true); - } - $('#actionTypeSel').append(""); - $("#actionAddButton").attr("class","glyphicon glyphicon-plus well-add"); - $("#actionAddButton").click(function(){showAction(this,'ADD')}); - /** - * 删除显示 - */ - var node = thisObj.parentNode.parentNode; - node.removeChild(thisObj.parentNode); -} - -function checkNameIShow(){ - if($("#notifyNameI").val()){ - $("#notifyInstances").show(); - }else{ - $("#notifyInstances").val(""); - $("#notifyInstances").hide(); - } - selUiConf["userInput"]["notifyNameI"] = $("#notifyNameI").val(); -} - -function closeObjectDiv() { - window.winmgr.hide("objectDiv"); - window.winmgr.show("notifyList"); -} - -function openHelpDiv() { - window.open("https://uavorg.github.io/documents/uavdoc_useroperation/28.html#%E5%88%9B%E5%BB%BA","apphub.help"); -} - - -/** - * 策略表达式处理类 - */ -var StgyClass = { - datas:{//数据原型 - where:new Array() - }, - initDatas:function(){//初始化数据原型 - StgyClass.datas.where = new Array(); - }, - checkWhereExists : function() { - /** - * 判断条件是否存在 - */ - StgyClass.initDatas(); - var conditions = new Array(), exists = false; - var div = document.getElementById("objectDiv"); - var spans = div.getElementsByTagName("span"); - $.each(spans, function(index, obj) { - if(obj.id && obj.id.indexOf("_stgySpan")>=0){ - exists=true - /** - * 同时将条件数据打包 - */ - StgyClass.datas.where.push(JSON.parse(obj.textContent)); - } - }); - - return exists; - }, - showStgyDiv : function(thisObj,type) { - - var isOwner = $("#isOwner").val(); - /** - * 显示策略编辑(弹出新元素) - */ - actionConf.actionObj=thisObj.parentNode; - - var sb = new StringBuffer(); - sb.append("
"); - sb.append("触发策略"); - sb.append("
"); - sb.append("
"); - - if(StgyClass.checkWhereExists()){ //渲染触发策略页面 - sb.append( '
'); - $.each(StgyClass.datas.where,function(index,data){ - - if(isOwner=="true"){ - sb.append( ''); - }else{ - sb.append( ''); - } - }); - sb.append( '
'); - - - if(isOwner=="true"){ - sb.append( '
'); - }else{ - sb.append( '
'); - } - - if(type=="edit"){ - sb.append(thisObj.parentNode.parentNode.getElementsByTagName("div")[0].innerHTML); - } - sb.append( '
'); - - if(isOwner=="true"){ - sb.append( '
'); - }else{ - sb.append( '
'); - } - - if(type=="edit"){ - sb.append(thisObj.parentNode.parentNode.getElementsByTagName("div")[1].innerHTML); - } - sb.append( '
'); - - if(isOwner=="true"){ - sb.append( '
'); - } - - }else{ - sb.append("
没有可用条件
"); - } - - HtmlHelper.id("stgyDiv").innerHTML = sb.toString(); - window.winmgr.hide("objectDiv"); - window.winmgr.show("stgyDiv"); - - }, - closeStgyDiv : function() { - /** - * 关闭策略编辑(关闭元素) - */ - window.winmgr.hide("stgyDiv"); - window.winmgr.show("objectDiv"); - }, - appendWhereToStgy:function(thisObj) { - /** - * 在策略编辑:将选中条件追加到策略表达式 - */ - var whereId = thisObj.id + "_exp"; - - var html = '  ' - + thisObj.innerText + '  '; - /** - * 必须要focus一下目标元素,不然会跟随光标而追加html内容。 - */ - document.getElementById("stgy_exp").focus(); - var sel = window.getSelection(); - if (sel.getRangeAt && sel.rangeCount) { - var range = sel.getRangeAt(0); - range.deleteContents(); - - var el = document.createElement("div"); - el.innerHTML = html; - var frag = document.createDocumentFragment(), node, lastNode; - while ((node = el.firstChild)) { - lastNode = frag.appendChild(node); - } - range.insertNode(frag); - - // Preserve the selection - if (lastNode) { - range = range.cloneRange(); - range.setStartAfter(lastNode); - range.collapse(true); - sel.removeAllRanges(); - sel.addRange(range); - } - } - }, - saveStgyToAppend : function(type){ - /** - * 策略编辑,保存按钮:关闭编辑,并且将策略结果追加到页面 - */ - var html = document.getElementById("stgy_exp").innerHTML; - var htmlConvergence = document.getElementById("convergence_exp").innerHTML.replace(/<\/?[^>]*>/g,''); - - if(html.length>0 && type=="add"){ - html = '
'+ - '
'+html+'
'+ - '
'+htmlConvergence+'
'+ - '
'+ - ''; - '
'+ - '
'; - - var newNode = document.createElement("div"); - newNode.innerHTML = html; - actionConf.actionObj.parentNode.appendChild(newNode); - - }else if(html.length>0 && type=="edit"){ - actionConf.actionObj.parentNode.getElementsByTagName("div")[0].innerHTML = html; - actionConf.actionObj.parentNode.getElementsByTagName("div")[1].innerHTML = htmlConvergence; - } - - StgyClass.closeStgyDiv(); - - }, - deleteStgyToAppend : function(thisObj){ - /** - * 删除策略结果 - */ - var node = thisObj.parentNode.parentNode.parentNode; - node.removeChild(thisObj.parentNode.parentNode); - }, - updateWhereToStgyAppend : function(json){ - /** - *修改策略结果 - */ - var updateId = json.id+"_exp"; - var stgys = $("span[name='"+updateId+"']"); - $.each(stgys,function(index,obj){ - obj.innerHTML = " "+StgyClass.formatShowWhere(json)+" "; - }); - }, - deleteWhereToStgyAppend : function(thisObj){ - /** - * 删除条件时: 给对应策略添加删除线 - */ - var divId = thisObj.parentNode.getElementsByTagName("span")[0].id+"_exp"; - var stgys = $("span[name='"+divId+"']"); - $.each(stgys,function(index,obj){ - obj.className = "whereStgyEdit whereStgyEdit-delete"; - }); - - }, - /** - * 格式化条件,显示格式(除去id不显示) - * - * @param json - * @returns {String} - */ - formatShowWhere : function(json) { - - if(!json){ - return ""; - } - - var result; - - if(!json.type||json.type=="stream"){ - result = json.expr; - - if(json.range && json.range!=""){ - result += ","+json.range; - } - - if(json.func && json.func!=0 && json.func=="count"){ - result += ","+json.func+">"+json.cparam; - }else if(json.func && json.func!=0){ - result += ","+json.func; - } - }else{ - result = json.metric+","+json.time_from+"-"+json.time_to+","+json.downsample+","+json.aggr+","; - if(json.interval){ - result+=json.interval+" "; - - } - switch(json.unit){ - case "6": - result+="min"; - break; - case "5": - result+="hour"; - break; - case "1": - result+="day"; - break; - case "2": - result+="week"; - break; - case "3": - result+="month"; - break; - case "4": - result+="year"; - break; - } - if(json.time_start!=undefined&&json.time_end!=undefined){ - result+=","+json.time_start+"-"+json.time_end; - } - if(json.day_start!=undefined&&json.day_end!=undefined){ - result+=","+json.day_start+"-"+json.day_end; - } - } - - return result; - }, - randomId : function(x, y) { - if (!x) { - x = 9999; - } - if (!y) { - y = 1; - } - var d = [ "a", "b", "c", "d", "e", "f", "g", "h", "i" ]; - - var rand = parseInt(Math.random() * (x - y + 1) + y) - + d[parseInt(Math.random() * d.length + 0)] - + parseInt(Math.random() * 1000) - + d[parseInt(Math.random() * d.length + 0)] - + parseInt(Math.random() * 1000); - return rand; - } +/** + * 窗体初始化 + */ +window.winmgr.build({ + id : "notifyList", + height : "auto", + "overflow-y" : "auto", + order : 999, + theme : "ListBG" +}); +window.winmgr.build({ + id : "objectDiv", + height : "auto", + "overflow-y" : "auto", + order : 999, + theme : "ObjectBG" +}); +window.winmgr.build({ + id : "stgyDiv", + height : "auto", + "overflow-y" : "auto", + order : 999, + theme : "StgyDiv" +}); +window.winmgr.build({ + id : "condDiv", + height : "auto", + "overflow-y" : "auto", + order : 999, + theme : "condDiv" +}); +window.winmgr.show("notifyList"); + +/** + * 操作配置 + */ +var actionConf = { + actionObj:null //操作对象 +} +/** + * 下拉框UI + * */ +var selUiConf = { + keys:[ + + {"key":"server","value":"自定义指标"}, + {"key":"server","value":"服务端"}, + {"key":"client","value":"客户端"}, + {"key":"log","value":"日志"} + ], + "server":[ + ["procState","进程状态指标系"], + ["hostState","应用容器状态指标系"], + ["urlResp","服务状态指标系"], + ["appResp","应用状态指标系"], + ["serverResp","应用服务器状态指标系"], + ["procCrash","进程死亡指标系"] + ], + "client":[ + ["clientResp","调用状态指标系"] + ], + "log":[ + ["log","日志"] + ] + , + "userDef":[ + ["jvm","Java虚拟机状态指标系"] + ] + , + userInput:{ + "notifyNameF":"", + "notifyNameM":"", + "notifyNameI":"" + } + +} + +var supportJTA = ["服务状态指标系","应用状态指标系","应用服务器状态指标系","调用状态指标系"]; +/** + * 初始化头部 + */ +function initHeadDiv() { + var divContent = "" + + "
" + + + "" + + + "" + + + "" + + + "
" + + "" + + + "" + + "
" + "
" + ""; + HtmlHelper.id("notifyList").innerHTML += divContent; +} + +/** + * 显示添加策略 + */ +function showAddDiv() { + + var sb=new StringBuffer(); + sb.append( "
"); + sb.append( ""); + sb.append( ""); + sb.append( ""); + sb.append( "添加策略"); + sb.append( "
"); + sb.append( "
"); + sb.append( "
"); + sb.append( "
"); + + sb.append( '
'); + + + sb.append( '
'); + sb.append(''); + sb.append('
'); + sb.append(''); + sb.append(''); + sb.append(''); + sb.append('
'); + sb.append('
'); + + sb.append('
'); + sb.append('
'); + sb.append(''); + sb.append(''); + sb.append(''); + sb.append('
'); + sb.append( '
'); + sb.append('
'); + + sb.append( '
'); + sb.append( "
"); + + + sb.append( '
'); + sb.append( '
'); + + sb.append( '
'); + sb.append( '
条件定义
'); + sb.append( '
'); + + sb.append( '
'); + sb.append( '
触发策略
'); + sb.append( '
'); + + sb.append( '
'); + sb.append( '
触发动作
'); + sb.append( '
'); + + sb.append( '
'); + sb.append( '
'); + sb.append( '
 
'); + + sb.append( '
'); + + HtmlHelper.id("objectDiv").innerHTML = sb.toString(); + window.winmgr.hide("notifyList"); + window.winmgr.show("objectDiv"); + initActionDiv($("#isOwner").val()); + +} + + +/** + * 显示编辑策略 + */ +function showEditNotifyDiv(jsonObjParam) { + + var key,jsonObj,isOwner=false;enableThreadAnalysis=false; + //因为只有一对 key:value 获取key(值为id) + $.each(jsonObjParam,function(index,obj){ + key = index; + jsonObj = obj; + }); + + if(jsonObj.owner == window.parent.loginUser.userId + || window.parent.loginUser.groupId == "uav_admin" + || window.parent.loginUser.groupId == "vipgroup" + ){ + isOwner = true; + } + + var names = key.split("@"); + var cssType = "displayMsgInput",cssRedOnly = "displayMsgInput listIndex"; + var sb=new StringBuffer(); + sb.append( "
"); + sb.append( ""); + sb.append( "编辑策略"); + sb.append( "
"); + sb.append( "
"); + sb.append( "
"); + sb.append( "
"); + /** + * 所有渲染内容 div begin + */ + sb.append( '
'); + + sb.append( '
'); + if(window.parent.loginUser.groupId == "uav_admin" + || window.parent.loginUser.groupId == "vipgroup" + ){ + sb.append( '
'); + }else{ + + sb.append( '
'); + } + + + sb.append( '
'); + + //1 + var existsIns = jsonObj.instances.length>0?true:false; + var showNameF = getSelUiConfKeysValue(names[0],names[1]); + if(showNameF=="自定义指标"){ + cssType = "displayMsgInput listIndex_appmetrics"; + }else if(names[1] == "log"){ + showNameF = "日志"; + cssType = "displayMsgInput listIndex_log"; + }else if(names[0] == "server"){ + cssType = "displayMsgInput listIndex_server"; + }else if(names[0] == "client"){ + cssType = "displayMsgInput listIndex_client"; + } + sb.append( '
'); + selUiConf["userInput"]["notifyNameF"]=names[0];//编辑赋值,准备修改数据 + //2 + if(showNameF=="自定义指标"){ + selUiConf["userInput"]["notifyNameM"]=names[1];//编辑赋值,准备修改数据 + }else if(names[1] == "log"){ + sb.append( '
'); + selUiConf["userInput"]["notifyNameM"]=names[1];//编辑赋值,准备修改数据 + }else if(names[1]){ + sb.append( '
'); + selUiConf["userInput"]["notifyNameM"]=names[1];//编辑赋值,准备修改数据 + if($.inArray(getSelUiConfigValue(names[1]),supportJTA) >= 0){ + enableThreadAnalysis=true; + } + } + //3 + if(names[2] && names[1] == "log"){ + var nNameIShow = "指定日志:"+names[2]; + sb.append( '
'); + selUiConf["userInput"]["notifyNameI"]=names[2];//编辑赋值,准备修改数据 + }else if(names[1] == "log"){ + sb.append( '
'); + }else if(names[2]){ + var nNameIShow = (existsIns?"实例组:":"实例:")+names[2]; + sb.append( '
'); + selUiConf["userInput"]["notifyNameI"]=names[2];//编辑赋值,准备修改数据 + }else{ + sb.append( '
'); + } + + if(names[2] && isOwner){ + sb.append( "
'); + }else if(names[2] && !isOwner){ + sb.append( "
'); + }else if(isOwner){ + sb.append( "
'); + }else{ + sb.append( "
'); + } + + + sb.append( '
'); + if(isOwner){ + sb.append( '
'); + }else{ + sb.append( '
'); + } + + /** + * 初始化条件 begin + */ + sb.append( '
'); + sb.append( '
'); + sb.append( '条件定义'); + sb.append( '
'); + $.each(jsonObj.conditions,function(index,obj){ + if(obj.func && obj.func.indexOf("count>")>-1){ + obj.cparam = obj.func.substr(6); + obj.func = "count"; + } + + if(!obj.id){ + /** + * 兼容老数据 + */ + obj.id=StgyClass.randomId()+"_stgySpan"; + } + var html; + if(isOwner){ + html = '
'+StgyClass.formatShowWhere(obj)+'
'; + }else{ + html = '
'+StgyClass.formatShowWhere(obj)+'
'; + } + sb.append( html); + }); + sb.append( '
'); + sb.append( '
'); + /** + * 初始化条件 end + */ + + /** + * 初始化触发策略 begin + */ + sb.append( '
'); + + if(isOwner){ + sb.append( '
触发策略
'); + }else{ + sb.append( '
触发策略
'); + } + + if(jsonObj.relationsHtmls){ + $.each(jsonObj.relationsHtmls,function(index,html){ + var convergenceVal = ""; + if(jsonObj.hasOwnProperty("convergences")){ + convergenceVal = jsonObj.convergences[index]; + } + + var appendHtml = + '
'+ + '
'+ + '
'+html+'
'+ + '
'+convergenceVal+'
'+ + '
'; + + if(isOwner){ + appendHtml+=''; + }else{ + appendHtml+=''; + } + appendHtml+='
'+ + '
'+ + '
'; + sb.append(appendHtml); + }); + } + sb.append( '
'); + /** + * 初始化触发策略 begin + */ + + sb.append( '
'); + sb.append( '
触发动作
'); + var actionSum = 0; + initActionDiv(isOwner?"true":"false"); + if (jsonObj.action!=undefined) { + $.each(jsonObj.action,function(index,value){ + actionSum++; + var josnSpan ={ + "type":index, + "value":value + } + + var html ; + + if(isOwner){ + if("threadanalysis" == josnSpan.type){ + var html = '
'+josnSpan.type+''+JSON.stringify(josnSpan)+'
'; + }else{ + html = '
'+josnSpan.type+''+JSON.stringify(josnSpan)+'
'; + } + }else{ + html = '
'+josnSpan.type+''+JSON.stringify(josnSpan)+'
'; + } + sb.append( '
'); + sb.append( html); + sb.append( '
'); + + /** + * 计算下拉选项 + */ + $("#actionTypeSel option[value="+josnSpan.type+"]").remove(); + + }); + } + sb.append( '
'); + /** + * 初始化触发动作 end + */ + + if(isOwner){ + //按钮 + sb.append( '
'); + sb.append( '
'); + sb.append( '
 
'); + } + + sb.append( '
'); + /** + * 所有渲染内容 div end + */ + sb.append( ""); + HtmlHelper.id("objectDiv").innerHTML = sb.toString(); + + /** + * 判断出发条件:不是归属者不能添加 + */ + if(!isOwner){ + $("#whereAddButton").attr("class","well-add"); + $("#whereAddButton").click(function(){}); + } + /** + * 判断触发动作按钮 begin(类型都已经存在值,则不能再添加) + * 不是归属者也不能添加 + */ + var selTypeSize = $("#actionTypeSel option").size(); + if(selTypeSize == 0 || !isOwner){ + $("#actionAddButton").attr("class","well-add"); + $("#actionAddButton").click(function(){}); + } + /** + * 判断触发动作按钮 end + */ + window.winmgr.hide("notifyList"); + window.winmgr.show("objectDiv"); + + hideShowConStgy(names[1]); +} + + + +/** + * 触发动作添加窗口 + */ +function initActionDiv(isOwner) { + + var old = document.getElementById("actionDiv"); + if(old){ + var node = old.parentNode; + node.removeChild(old); + } + + var sb=new StringBuffer(); + + sb.append(''); + var div = document.createElement('div'); + div.innerHTML = sb.toString(); + document.body.appendChild(div); +} + +/** + * 显示添加条件窗口 + * @param thisObj + * @param type + */ +function showCon(thisObj,type){ + actionConf.actionObj=thisObj.parentNode; + if(selUiConf["userInput"]["notifyNameM"]=="log"){ + $("#condType").attr("disabled","disabled"); + } + $("#pageType").val(type); + if("EDIT" == type){ + var jsonValue = JSON.parse(thisObj.parentNode.getElementsByTagName("span")[0].textContent); + $("#condType").attr("disabled","disabled"); + var isOwner = $("#isOwner").val(); + if(!jsonValue.type||jsonValue.type=="stream"){ + $("#condType").val("stream"); + $("#contExpr").val(jsonValue.expr); + $("#conRange").val(jsonValue.range); + $("#conFunc").val((null == jsonValue.func?0:jsonValue.func)); + if("count" == jsonValue.func){ + $("#conFuncParam").val(jsonValue.cparam); + $("#conFuncParam").show(); + } + //不是归属用户,则只读 + if(isOwner!="true"){ + $("#whereSaveButton").hide(); + $("#contExpr").attr("readonly","readonly"); + $("#conRange").attr("readonly","readonly"); + $("#conFunc").attr("disabled","disabled"); + $("#conFuncParam").attr("readonly","readonly"); + + //只读CSS + $("#contExpr").attr("class","form-control"); + $("#conRange").attr("class","form-control"); + $("#conFuncParam").attr("class","form-control"); + $("#whereSaveButton").hide(); + } + + }else{ + var type; + if(jsonValue.interval){ + type="link-relative"; + }else{ + type="base-relative"; + } + $("#condType").val(type); + typeChangeShow(type); + + var hour=jsonValue.time_from.split(':')[0]; + var min=jsonValue.time_from.split(':')[1]; + $('#time_from_div').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); + hour=jsonValue.time_to.split(':')[0]; + min=jsonValue.time_to.split(':')[1]; + $('#time_to_div').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); + + if(jsonValue.time_start!=undefined&&jsonValue.time_end!=undefined){ + hour=jsonValue.time_start.split(':')[0]; + min=jsonValue.time_start.split(':')[1]; + $('#time_start_div').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); + hour=jsonValue.time_end.split(':')[0]; + min=jsonValue.time_end.split(':')[1]; + $('#time_end_div').data('datetimepicker').setLocalDate(new Date(2000, 1, 1, hour, min)); + } + + if(jsonValue.day_start!=undefined&&jsonValue.day_end!=undefined){ + var year=jsonValue.day_start.split('-')[0]; + var month=jsonValue.day_start.split('-')[1]; + var day=jsonValue.day_start.split('-')[2]; + $('#day_start_div').data('datetimepicker').setLocalDate(new Date(year, month-1, day, 0, 0)); + year=jsonValue.day_end.split('-')[0]; + month=jsonValue.day_end.split('-')[1]; + day=jsonValue.day_end.split('-')[2]; + $('#day_end_div').data('datetimepicker').setLocalDate(new Date(year, month-1, day, 0, 0)); + } + + showWeekDay(jsonValue.weekdayLimit); + + $("#conMetric").val(jsonValue.metric); + $("#conUpperLimit").val(jsonValue.upperLimit); + $("#conLowerLimit").val(jsonValue.lowerLimit); + $("#conAggr").val(jsonValue.aggr); + $("#conDownSample").val(jsonValue.downsample); + if(type=="link-relative"){ + $("#conInterval").val(jsonValue.interval); + } + showUnit(jsonValue.unit); + + if(isOwner!="true"){ + $("#time_from").attr("readonly","readonly"); + $("#time_to").attr("readonly","readonly"); + $("#time_start").attr("readonly","readonly"); + $("#time_end").attr("readonly","readonly"); + $("#day_start").attr("readonly","readonly"); + $("#day_end").attr("readonly","readonly"); + $("#conMetric").attr("readonly","readonly"); + $("#conUpperLimit").attr("readonly","readonly"); + $("#conLowerLimit").attr("readonly","readonly"); + $("#conMetric").attr("class","form-control"); + $("#conUpperLimit").attr("class","form-control"); + $("#conLowerLimit").attr("class","form-control"); + $("#conAggr").attr("disabled","disabled"); + $("#conDownSample").attr("disabled","disabled"); + if(type=="link-relative"){ + $("#conInterval").attr("readonly","readonly"); + $("#conInterval").attr("class","form-control"); + } + $("#whereSaveButton").hide(); + } + } + + } + +} + +function showUnit(unit){ + $("#unit").val(unit); + $("#opt"+unit).attr("class","btn btn-default active"); +} + +function showWeekDay(weekdayLimit){ + + for(var i=0;i"); + sb.append("条件定义"); + sb.append("
"); + sb.append("
"); + sb.append( "
'); + + sb.append( '
'); + /** + * 普通预警条件编辑 + */ + sb.append( '
'); + + sb.append( '
触发表达式

'); + sb.append( '
持续时间(秒)

'); + sb.append( "
聚集操作

'); + sb.append( ')\" style="display:none" onkeyup="this.value=this.value.replace(\/\\D/g,\'\')" onafterpaste="this.value=this.value.replace(\/\\D/g,\'\')">
'); + sb.append( '
'); + + /** + * 同环比预警条件编辑 + */ + sb.append( ''); + sb.append( ''); + + /** + * 保存按钮 + */ + sb.append( '
'); + sb.append( ''); + sb.append( ''); + sb.append( '
'); + + HtmlHelper.id("condDiv").innerHTML = sb.toString(); + initTimeControl(); + showCon(thisObj,type); + window.winmgr.hide("objectDiv"); + window.winmgr.show("condDiv"); + +} + +function funcChangeShow(thisObj,showId){ + if("count" == thisObj.value){ + $("#"+showId).show(); + }else{ + $("#"+showId).hide(); + } +} + +function typeChangeShow(type){ + var divs=["stream","timer","link-relative","base-relative"]; + divs.forEach(div=>{ + $("#"+div).hide(); + }) + if("stream"!=type){ + $("#timer").show(); + } + $("#"+type).show(); + +} +/** + * 初始化时间控件 + */ +function initTimeControl(){ + $('#time_from_div').datetimepicker({ + pickDate: false, + pickSeconds: false + }); + + + $('#time_to_div').datetimepicker({ + pickDate: false, + pickSeconds: false + }); + + $('#time_start_div').datetimepicker({ + pickDate: false, + pickSeconds: false + }); + + + $('#time_end_div').datetimepicker({ + pickDate: false, + pickSeconds: false + }); + + $('#day_start_div').datetimepicker({ + pickHour: false, + pickMin: false, + pickSeconds: false + }); + + + $('#day_end_div').datetimepicker({ + pickHour: false, + pickMin: false, + pickSeconds: false + }); + + +} + +function changeTimeUnit(value){ + $("#unit").val(value); +} + + + +function actionChangeShow(type){ + if("ADD" == type){ + if("threadanalysis" == $("#actionTypeSel").val()){ + $("textarea[name='actionValue']").val("10101").hide(); + $(".btn-addPriority").hide(); + }else{ + $("textarea[name='actionValue']").val("").show(); + $(".btn-addPriority").show(); + } + }else{ + $("textarea[name='actionValue']").show(); + $(".btn-addPriority").show(); + } +} + +function selServerChangeShow(type,value,text){ + var selId = type+"_notifyNameF"; + $("#"+selId).html(text); + $("#"+selId).css("padding-left","2px"); + $("#"+type+"_notifyNameF").css("color","black"); + + hideShowConStgy("show"); + + if(text == "自定义指标"){ + $("#"+type+"_appName_div").hide(); + $("#"+type+"_notifyNameM_div").attr("class","btn-group selectDiv defNone"); + selUiConf["userInput"]["notifyNameF"]=value; + selUiConf["userInput"]["notifyNameM"]="jvm"; + $("#notifyNameI").attr("placeholder","输入监控实例名或者实例组名"); + $("#enableThreadAnalysis").val(false); + removeChoosedJTA(); + }else if(value=="log"){ + $("#"+type+"_appName_div").show(); + $("#"+type+"_notifyNameM_div").attr("class","btn-group selectDiv defNone"); + $("#notifyNameI").attr("placeholder","输入指定日志"); + selUiConf["userInput"]["notifyNameF"]=""; + selUiConf["userInput"]["notifyNameM"]=value; + $("#enableThreadAnalysis").val(false); + removeChoosedJTA(); + }else{ + $("#"+type+"_appName_div").hide(); + $("#"+type+"_notifyNameM_div").attr("class","btn-group selectDiv"); + $("#notifyNameI").attr("placeholder","输入监控实例名或者实例组名"); + $("#"+type+"_notifyNameM").css("color","darkgrey"); + $("#"+type+"_notifyNameM").html("选择监控组指标"); + document.getElementById(type+"_notifyNameM_body").innerHTML =""; + $.each(selUiConf[value],function(index,obj){ + var li = document.createElement("li"); + var a = document.createElement("a"); + a.innerHTML=obj[1]; + a.onclick=function(){selIndexChangeShow(type,obj[0],obj[1]);}; + a.href="#"; + li.appendChild(a); + document.getElementById(type+"_notifyNameM_body").appendChild(li); + }); + selUiConf["userInput"]["notifyNameF"]=value; + } + +} + +function removeChoosedJTA(){ + if(HtmlHelper.id("ChoosedJTA") != null){ + HtmlHelper.id("ChoosedJTA").remove(); + } +} + +function changeJTAStat(text){ + if($.inArray(text,supportJTA) >= 0){ + $("#enableThreadAnalysis").val(true); + if(HtmlHelper.id("ChoosedJTA") == null){ + $("#actionAddButton").attr("class","glyphicon glyphicon-plus well-add"); + $("#actionAddButton").click(function(){showAction(this,'ADD')}); + } + }else{ + $("#enableThreadAnalysis").val(false); + removeChoosedJTA(); + } +} + +function hideShowConStgy(value){ + if(value == "procCrash"){ + $("#conFatDiv").hide(); + $("#stgyFatDiv").hide(); + } + else{ + $("#conFatDiv").show(); + $("#stgyFatDiv").show(); + } +} + +function selIndexChangeShow(type,value,text){ + changeJTAStat(text); + hideShowConStgy(value); + + $("#"+type+"_notifyNameM").html(text); + $("#"+type+"_notifyNameM").css("padding-left","2px"); + $("#"+type+"_notifyNameM").css("color","black"); + selUiConf["userInput"]["notifyNameM"]=value; +} + +function appNameChange(obj){ + selUiConf["userInput"]["notifyNameF"]=obj.value; +} +function getSelUiConfigValue(indexValue){ + var result =""; + $.each(selUiConf.keys,function(value,obj1){ + $.each(selUiConf[obj1.key],function(index,obj2){ + if(obj2[0]==indexValue){ + result=obj2[1]; + return false; + } + }); + if(result!==""){ + return false; + } + }); + + return result; +} +function getSelUiConfKeysValue(a, b) { + var result = ""; + if (b == "log") { + result="日志"; + } else if (a == "server" && b == "jvm") { + result="自定义指标"; + } else if (a == "server") { + result="服务端"; + } else if (a == "client") { + result="客户端"; + } + return result; +} +function conditionsAppend(){ + if(checkFunc()){ + var jsonObject; + if("stream"==$("#condType").val()){ + jsonObject = {"type":"stream","expr":HtmlHelper.inputXSSFilter($("#contExpr").val()),"range":HtmlHelper.inputXSSFilter($("#conRange").val()),"func":HtmlHelper.inputXSSFilter($("#conFunc").val()),"cparam":HtmlHelper.inputXSSFilter($("#conFuncParam").val())}; + }else{ + jsonObject = {"type":"timer","time_from":HtmlHelper.inputXSSFilter($("#time_from").val()),"time_to":HtmlHelper.inputXSSFilter($("#time_to").val()),"metric":HtmlHelper.inputXSSFilter($("#conMetric").val()),"upperLimit":HtmlHelper.inputXSSFilter($("#conUpperLimit").val()),"lowerLimit":HtmlHelper.inputXSSFilter($("#conLowerLimit").val())}; + + if(HtmlHelper.inputXSSFilter($("#conAggr").val())!="0"){ + jsonObject["aggr"]=HtmlHelper.inputXSSFilter($("#conAggr").val()); + }else{ + jsonObject["aggr"]="avg"; + } + + if(HtmlHelper.inputXSSFilter($("#conDownSample").val())!="0"){ + jsonObject["downsample"]=HtmlHelper.inputXSSFilter($("#conDownSample").val()); + }else{ + jsonObject["downsample"]="all-avg"; + } + + if("link-relative"==$("#condType").val()){ + jsonObject["interval"]=HtmlHelper.inputXSSFilter($("#conInterval").val()); + jsonObject["unit"]=HtmlHelper.inputXSSFilter($("#unit").val()); + }else{ + jsonObject["unit"]=HtmlHelper.inputXSSFilter($("#unit").val()); + } + + if($("#time_start").val()&&$("#time_end").val()){ + jsonObject["time_start"]=HtmlHelper.inputXSSFilter($("#time_start").val()); + jsonObject["time_end"]=HtmlHelper.inputXSSFilter($("#time_end").val()); + } + + if($("#day_start").val()&&$("#day_end").val()){ + jsonObject["day_start"]=HtmlHelper.inputXSSFilter($("#day_start").val()); + jsonObject["day_end"]=HtmlHelper.inputXSSFilter($("#day_end").val()); + } + + var weekdayLimit=[]; + for(var i=0;i<7;i++){ + weekdayLimit[i]=($("#weekday"+i).attr("class")=="btn btn-default active") + } + jsonObject["weekdayLimit"]=weekdayLimit; + + } + appendConditions(jsonObject); + window.winmgr.hide("condDiv"); + window.winmgr.show("objectDiv"); + } +} + +function checkFunc(){ + + var result = true; + if("stream"==$("#condType").val()){ + if(!$("#contExpr").val()){ + result = false; + }else if("count" == $("#conFunc").val() && !$("#conFuncParam").val()){ + result = false; + } + }else{ + if(!$("#time_from").val()||!$("#time_to").val()||!$("#conMetric").val()||!$("#conUpperLimit").val()||!$("#conLowerLimit").val()){ + result = false; + } + if("link-relative"==$("#condType").val()){ + if(!$("#conInterval").val()||!$("#unit").val()){ + result = false; + } + }else{ + if(!$("#unit").val()){ + result = false; + } + } + } + + + if(result){ + $("#conditionsErrMsg").hide(); + }else{ + $("#conditionsErrMsg").show(); + } + + return result; +} +function appendConditions(jsonObj) { + var type = $("#pageType").val(); + if("ADD"==type){ + var newNode = document.createElement("div"); + var stgyDivId = StgyClass.randomId()+"_stgySpan"; + html = '
'+getHtmlAndSetId(stgyDivId)+'
'; + newNode.innerHTML = html; + actionConf.actionObj.parentNode.appendChild(newNode); + }else if("EDIT"==type){ + var oldId = actionConf.actionObj.getElementsByTagName("span")[0].id; + actionConf.actionObj.innerHTML= getHtmlAndSetId(oldId); + StgyClass.updateWhereToStgyAppend(jsonObj); + } + + function getHtmlAndSetId(stgyDivId){ + jsonObj.id = stgyDivId;//赋值id + var html = StgyClass.formatShowWhere(jsonObj)+''; + return html; + } +} +/** + * 条件窗口操作 end + */ + + +/** + * 触发动作操作 begin + */ +function showAction(thisObj,type){ + actionConf.actionObj=thisObj.parentNode; + checkJTAAction(); + $("#actiontype").val(type); + $.each($("textarea[name='actionValue']"),function(index,obj){ + if(index>0){ + removeActonTextarea(obj); + }else{ + obj.value=""; + } + }); + $("#actionDiv").modal({backdrop: 'static', keyboard: false}); + $("#actionDiv").modal(); + //还原只读 + $("#actionSaveButton").show(); + $("#actionValue").removeAttr("readonly"); + + + if("EDIT"==type){ + //不是归属用户,则只读 + var isOwner = $("#isOwner").val(); + $("#actionTypeSel").hide(); + var spanJson = JSON.parse(thisObj.parentNode.getElementsByTagName('span')[0].textContent); + + $.each(spanJson.value,function(index,value){ + /** + * 第一次循环:追加渲染 + */ + if(index>0){ + appendActionTextarea(); + } + }); + var actionTextValues = $("textarea[name='actionValue']"); + $.each(spanJson.value,function(index,value){ + /** + * 第二次循环:赋值 + */ + actionTextValues[index].value=value; + }); + + $("#actionEditType").val(spanJson.type); + + actionChangeShow("EDIT"); + if(isOwner!="true"){ + $("#actionSaveButton").hide(); + } + }else{ + $("#actionTypeSel").show(); + actionChangeShow("ADD"); + } +} + +function checkJTAAction(){ + if($("#enableThreadAnalysis").val() =="true"&& $("#actionTypeSel").find("option[value='threadanalysis']").size() == 0 && $("#ChoosedJTA").size() == 0){ + $("#actionTypeSel").append(""); + } + else if($("#enableThreadAnalysis").val() == "false" && $("#actionTypeSel").find("option[value='threadanalysis']").size() == 1){ + $("#actionTypeSel option[value=threadanalysis]").remove(); + } +} + +function actionAppend(){ + + $("#ActionErrMsg").hide(); + + if(checkAction()){ + appendActions(); + $("#actionDiv").modal('hide'); + }else{ + $("#ActionErrMsg").show(); + } +} + +function appendActionTextarea(thisObj){ + var isOwner = $("#isOwner").val(); + + var html = ''; + if(isOwner == "true"){ + html = ''; + html+= '
'; + }else{ + html = ''; + } + + var newNode = document.createElement("div"); + newNode.innerHTML = html; + document.getElementById("actionBodyDiv").appendChild(newNode); +} +function removeActonTextarea(thisObj){ + var node = thisObj.parentNode.parentNode; + node.removeChild(thisObj.parentNode); +} + +function checkAction(){ + var actionTextValues = $("textarea[name='actionValue']"); + + var checkValue = $.trim(actionTextValues[0].value); //只校验第一个必须输入 + var type = $("#actiontype").val(); + if("ADD"==type && !checkValue){ + return false; + }else if(!checkValue){ + return false; + } + + var result = false; + var actionValues = new Array(); + $.each(actionTextValues,function(index,obj){ + var values = format(obj.value); + obj.value = values; + if(values!=""){ + actionValues.push(values); + result = true; + } + }); + + if(!result){ + $("#ActionErrMsg").show(); + } + + return result; + + function format(_values){ + var result = new Array(); + var values = _values.split(","); + $.each(values,function(index,value){ + value = $.trim(value); + if(value!=""){ + result.push(value); + } + }); + + if(!result || result.length==0){ + return ""; + }else{ + return result.join(","); + } + } +} + +function appendActions() { + var type = $("#actiontype").val(); + var html = getAppendHtml(type); + + if("threadanalysis" == $("#actionTypeSel").val()){ + $("#enableThreadAnalysis").val(false); + } + if("ADD"==type){ + var newNode = document.createElement("div"); + newNode.innerHTML = html; + actionConf.actionObj.parentNode.appendChild(newNode); + + /** + * 计算下拉菜单:删除当前选项 + */ + $("#actionTypeSel option[value="+$("#actionTypeSel").val()+"]").remove(); + + /** + * 计算是否还有添加类型:添加按钮控制 + */ + var actionTypeSelect = document.getElementById("actionTypeSel"); + if(actionTypeSelect.length == 0){ + $("#actionAddButton").attr("class","well-add"); + $("#actionAddButton").click(function(){}); + } + + + }else if("EDIT"==type){ + actionConf.actionObj.parentNode.innerHTML = html; + } + + function getAppendHtml(){ + var result = new Array(); + var actionTextValues = $("textarea[name='actionValue']"); + $.each(actionTextValues,function(index,obj){ + result.push(obj.value); + }); + + var actionType =""; + if(type=="ADD"){ + actionType = $("#actionTypeSel").val(); + }else if(type=="EDIT"){ + actionType = $("#actionEditType").val(); + } + + var jsonObj = {type:HtmlHelper.inputXSSFilter(actionType),value:HtmlHelper.inputXSSFilter(result)}; + if("threadanalysis" == jsonObj.type){ + var html = '
'+jsonObj.type+''+JSON.stringify(jsonObj)+'
'; + }else{ + var html = '
'+jsonObj.type+''+JSON.stringify(jsonObj)+'
'; + } + return html; + } +} +/** + * 触发动作操作 end + */ + + +function delThisObj(thisObj) { + var node = thisObj.parentNode.parentNode; + node.removeChild(thisObj.parentNode); + StgyClass.deleteWhereToStgyAppend(thisObj); +} + +function delThisActionObj(thisObj) { + + /** + * 还原当前选项 + */ + var spanJson = JSON.parse(thisObj.parentNode.getElementsByTagName('span')[0].innerHTML); + if(spanJson.type == "threadanalysis"){ + $("#enableThreadAnalysis").val(true); + } + $('#actionTypeSel').append(""); + $("#actionAddButton").attr("class","glyphicon glyphicon-plus well-add"); + $("#actionAddButton").click(function(){showAction(this,'ADD')}); + /** + * 删除显示 + */ + var node = thisObj.parentNode.parentNode; + node.removeChild(thisObj.parentNode); +} + +function checkNameIShow(){ + if($("#notifyNameI").val()){ + $("#notifyInstances").show(); + }else{ + $("#notifyInstances").val(""); + $("#notifyInstances").hide(); + } + selUiConf["userInput"]["notifyNameI"] = $("#notifyNameI").val(); +} + +function closeObjectDiv() { + window.winmgr.hide("objectDiv"); + window.winmgr.show("notifyList"); +} + +function openHelpDiv() { + window.open("https://uavorg.github.io/documents/uavdoc_useroperation/28.html#%E5%88%9B%E5%BB%BA","apphub.help"); +} + + +/** + * 策略表达式处理类 + */ +var StgyClass = { + datas:{//数据原型 + where:new Array() + }, + initDatas:function(){//初始化数据原型 + StgyClass.datas.where = new Array(); + }, + checkWhereExists : function() { + /** + * 判断条件是否存在 + */ + StgyClass.initDatas(); + var conditions = new Array(), exists = false; + var div = document.getElementById("objectDiv"); + var spans = div.getElementsByTagName("span"); + $.each(spans, function(index, obj) { + if(obj.id && obj.id.indexOf("_stgySpan")>=0){ + exists=true + /** + * 同时将条件数据打包 + */ + StgyClass.datas.where.push(JSON.parse(obj.textContent)); + } + }); + + return exists; + }, + showStgyDiv : function(thisObj,type) { + + var isOwner = $("#isOwner").val(); + /** + * 显示策略编辑(弹出新元素) + */ + actionConf.actionObj=thisObj.parentNode; + + var sb = new StringBuffer(); + sb.append("
"); + sb.append("触发策略"); + sb.append("
"); + sb.append("
"); + + if(StgyClass.checkWhereExists()){ //渲染触发策略页面 + sb.append( '
'); + $.each(StgyClass.datas.where,function(index,data){ + + if(isOwner=="true"){ + sb.append( ''); + }else{ + sb.append( ''); + } + }); + sb.append( '
'); + + + if(isOwner=="true"){ + sb.append( '
'); + }else{ + sb.append( '
'); + } + + if(type=="edit"){ + sb.append(thisObj.parentNode.parentNode.getElementsByTagName("div")[0].innerHTML); + } + sb.append( '
'); + + if(isOwner=="true"){ + sb.append( '
'); + }else{ + sb.append( '
'); + } + + if(type=="edit"){ + sb.append(thisObj.parentNode.parentNode.getElementsByTagName("div")[1].innerHTML); + } + sb.append( '
'); + + if(isOwner=="true"){ + sb.append( '
'); + } + + }else{ + sb.append("
没有可用条件
"); + } + + HtmlHelper.id("stgyDiv").innerHTML = sb.toString(); + window.winmgr.hide("objectDiv"); + window.winmgr.show("stgyDiv"); + + }, + closeStgyDiv : function() { + /** + * 关闭策略编辑(关闭元素) + */ + window.winmgr.hide("stgyDiv"); + window.winmgr.show("objectDiv"); + }, + appendWhereToStgy:function(thisObj) { + /** + * 在策略编辑:将选中条件追加到策略表达式 + */ + var whereId = thisObj.id + "_exp"; + + var html = '  ' + + thisObj.innerText + '  '; + /** + * 必须要focus一下目标元素,不然会跟随光标而追加html内容。 + */ + document.getElementById("stgy_exp").focus(); + var sel = window.getSelection(); + if (sel.getRangeAt && sel.rangeCount) { + var range = sel.getRangeAt(0); + range.deleteContents(); + + var el = document.createElement("div"); + el.innerHTML = html; + var frag = document.createDocumentFragment(), node, lastNode; + while ((node = el.firstChild)) { + lastNode = frag.appendChild(node); + } + range.insertNode(frag); + + // Preserve the selection + if (lastNode) { + range = range.cloneRange(); + range.setStartAfter(lastNode); + range.collapse(true); + sel.removeAllRanges(); + sel.addRange(range); + } + } + }, + saveStgyToAppend : function(type){ + /** + * 策略编辑,保存按钮:关闭编辑,并且将策略结果追加到页面 + */ + var html = document.getElementById("stgy_exp").innerHTML; + var htmlConvergence = document.getElementById("convergence_exp").innerHTML.replace(/<\/?[^>]*>/g,''); + + if(html.length>0 && type=="add"){ + html = '
'+ + '
'+html+'
'+ + '
'+htmlConvergence+'
'+ + '
'+ + ''; + '
'+ + '
'; + + var newNode = document.createElement("div"); + newNode.innerHTML = html; + actionConf.actionObj.parentNode.appendChild(newNode); + + }else if(html.length>0 && type=="edit"){ + actionConf.actionObj.parentNode.getElementsByTagName("div")[0].innerHTML = html; + actionConf.actionObj.parentNode.getElementsByTagName("div")[1].innerHTML = htmlConvergence; + } + + StgyClass.closeStgyDiv(); + + }, + deleteStgyToAppend : function(thisObj){ + /** + * 删除策略结果 + */ + var node = thisObj.parentNode.parentNode.parentNode; + node.removeChild(thisObj.parentNode.parentNode); + }, + updateWhereToStgyAppend : function(json){ + /** + *修改策略结果 + */ + var updateId = json.id+"_exp"; + var stgys = $("span[name='"+updateId+"']"); + $.each(stgys,function(index,obj){ + obj.innerHTML = " "+StgyClass.formatShowWhere(json)+" "; + }); + }, + deleteWhereToStgyAppend : function(thisObj){ + /** + * 删除条件时: 给对应策略添加删除线 + */ + var divId = thisObj.parentNode.getElementsByTagName("span")[0].id+"_exp"; + var stgys = $("span[name='"+divId+"']"); + $.each(stgys,function(index,obj){ + obj.className = "whereStgyEdit whereStgyEdit-delete"; + }); + + }, + /** + * 格式化条件,显示格式(除去id不显示) + * + * @param json + * @returns {String} + */ + formatShowWhere : function(json) { + + if(!json){ + return ""; + } + + var result; + + if(!json.type||json.type=="stream"){ + result = json.expr; + + if(json.range && json.range!=""){ + result += ","+json.range; + } + + if(json.func && json.func!=0 && json.func=="count"){ + result += ","+json.func+">"+json.cparam; + }else if(json.func && json.func!=0){ + result += ","+json.func; + } + }else{ + result = json.metric+","+json.time_from+"-"+json.time_to+","+json.downsample+","+json.aggr+","; + if(json.interval){ + result+=json.interval+" "; + + } + switch(json.unit){ + case "6": + result+="min"; + break; + case "5": + result+="hour"; + break; + case "1": + result+="day"; + break; + case "2": + result+="week"; + break; + case "3": + result+="month"; + break; + case "4": + result+="year"; + break; + } + if(json.time_start!=undefined&&json.time_end!=undefined){ + result+=","+json.time_start+"-"+json.time_end; + } + if(json.day_start!=undefined&&json.day_end!=undefined){ + result+=","+json.day_start+"-"+json.day_end; + } + } + + return result; + }, + randomId : function(x, y) { + if (!x) { + x = 9999; + } + if (!y) { + y = 1; + } + var d = [ "a", "b", "c", "d", "e", "f", "g", "h", "i" ]; + + var rand = parseInt(Math.random() * (x - y + 1) + y) + + d[parseInt(Math.random() * d.length + 0)] + + parseInt(Math.random() * 1000) + + d[parseInt(Math.random() * d.length + 0)] + + parseInt(Math.random() * 1000); + return rand; + } } \ No newline at end of file diff --git a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/NotifyStrategy.java b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/NotifyStrategy.java index f5b420c1..b8d163ef 100644 --- a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/NotifyStrategy.java +++ b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/NotifyStrategy.java @@ -1,562 +1,562 @@ -/*- - * << - * UAVStack - * == - * Copyright (C) 2016 - 2017 UAVStack - * == - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * >> - */ - -package com.creditease.uav.feature.runtimenotify; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.alibaba.fastjson.JSONArray; -import com.creditease.agent.helpers.DateTimeHelper; -import com.creditease.agent.helpers.EncodeHelper; -import com.creditease.agent.helpers.JSONHelper; - -/** - * notify strategy ds - */ -public class NotifyStrategy { - - public enum Type { - STREAM("stream"), TIMER("timer"); - - private String name; - - Type(String name) { - this.name = name; - } - - @Override - public String toString() { - - return name; - } - } - - private static final String[] OPERATORS = { ":=", "!=", ">", "<", "=" }; - - private static final Pattern INDEX_PATTERN = Pattern.compile("\\[\\d+\\]"); - - private Type type; - - private String scope; - - private List condtions; - - private List convergences; - - private String msgTemplate; - - private Map action = Collections.emptyMap(); - - private List context = Collections.emptyList(); - - private List instances = Collections.emptyList(); - - private long maxRange = 0; - - private String name; - - public NotifyStrategy() { - } - - public NotifyStrategy(String name, String scope, List context, Map action, - List instances, String msgTemplate, List convergences) { - this.name = name; - this.scope = scope; - if (context != null && context.size() != 0) { - this.context = context; - } - if (action != null && action.size() != 0) { - this.action = action; - } - if (instances != null && instances.size() != 0) { - this.instances = instances; - } - this.convergences = convergences; - this.msgTemplate = msgTemplate; - } - - public void setConditions(List conditions, List relations) { - - int idx = 0; // expression count - List exprs = new ArrayList<>(); - for (Object o : conditions) { - - // condition is simple string: "arg>123" - if (String.class.isAssignableFrom(o.getClass())) { - Expression expression = new Expression((String) o); - expression.setIdx(idx++); - exprs.add(expression); - } - else { - @SuppressWarnings("unchecked") - Map cond = (Map) o; - Expression expression; - if (cond.get("type") == null || cond.get("type").equals(Type.STREAM.name)) { - String expr = (String) cond.get("expr"); - String func = (String) cond.get("func"); - Long range = cond.get("range") == null ? null : Long.valueOf(cond.get("range").toString()); - Float sampling = cond.get("sampling") == null ? null - : Float.valueOf(cond.get("sampling").toString()); - expression = new Expression(expr, func, range, sampling); - } - else { - String metricPrefix = name.substring(name.indexOf('@') + 1, name.lastIndexOf('@')); - cond.put("metric", metricPrefix + "." + cond.get("metric")); - expression = new Expression(cond); - this.type = Type.TIMER; - } - expression.setIdx(idx++); - exprs.add(expression); - } - } - - idx = 1; // reuse for condition count, start from 1 - List conds = null; - if (relations == null || relations.isEmpty()) { - conds = new ArrayList<>(conditions.size()); - - for (Expression expr : exprs) { - conds.add(new Condition(idx++, expr)); - } - } - else { - conds = new ArrayList<>(relations.size()); - for (String relation : relations) { - - Matcher m = INDEX_PATTERN.matcher(relation); - Set set = new HashSet<>(); - while (m.find()) { - String idxHolder = m.group(); - int i = Integer.parseInt(idxHolder.substring(1, idxHolder.length() - 1)); - if (i >= exprs.size()) { // IndexOutOfBoundsException - continue; - } - set.add(exprs.get(i)); - relation = relation.replace(idxHolder, "{" + i + "}"); // temp i - } - - List list = new ArrayList<>(set); - for (int i = 0; i < list.size(); i++) { - relation = relation.replace("{" + list.get(i).getIdx() + "}", "[" + i + "]"); - } - conds.add(new Condition(idx++, list, relation)); - } - } - - this.condtions = conds; - - /** init max range */ - for (Condition cond : this.condtions) { - for (Expression expr : cond.expressions) { - maxRange = Math.max(maxRange, expr.range); - } - } - - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public static NotifyStrategy parse(String name, String json) { - - Map m = JSONHelper.toObject(json, Map.class); - String scope = (String) m.get("scope"); - List context = (List) m.get("context"); - List conditions = (List) m.get("conditions"); - List relations = (List) m.get("relations"); - List convergences = (List) m.get("convergences"); - Map action = (Map) m.get("action"); - String msgTemplate = (String) m.get("msgTemplate"); - List instances = (List) m.get("instances"); - - NotifyStrategy stra = new NotifyStrategy(name, scope, context, action, instances, msgTemplate, convergences); - - stra.setConditions(conditions, relations); - - return stra; - } - - public long getMaxRange() { - - return maxRange; - } - - public String getMsgTemplate() { - - return msgTemplate; - } - - public void setMsgTemplate(String msgTemplate) { - - this.msgTemplate = msgTemplate; - } - - public Map getAction() { - - return action; - } - - public void setAction(Map action) { - - this.action = action; - } - - public List getContext() { - - return context; - } - - public void setContext(List context) { - - this.context = context; - } - - public String getScope() { - - return scope; - } - - public void setScope(String scope) { - - this.scope = scope; - } - - public List getInstances() { - - return instances; - } - - public void setInstances(List instances) { - - this.instances = instances; - } - - public String getName() { - - return name; - } - - public Type getType() { - - return type; - } - - public List getCondtions() { - - return condtions; - } - - public List getConvergences() { - - return convergences; - } - - protected static class Expression { - - private int idx; - private Type type; - private String arg; - private String operator; - private String expectedValue; - private long range = 0; - private String func; - private float sampling = 1; - private String downsample; - private Boolean[] weekdayLimit=new Boolean[] {true,true,true,true,true,true,true}; - - private Set matchArgExpr = new HashSet(); - - private long time_from; - private long time_to; - private long interval; - private int unit; - private String upperLimit; - private String lowerLimit; - private String time_end; - private String time_start; - private String day_start; - private String day_end; - - public Expression(String exprStr) { - for (String op : OPERATORS) { - if (exprStr.contains(op)) { - String[] exprs = exprStr.split(op); - this.arg = exprs[0].trim(); - - // suport * as a match - initMatchArgExpr(); - - this.operator = op; - this.expectedValue = exprs[1]; - break; - } - } - this.type = Type.STREAM; - } - - public Expression(String exprStr, String func, Long range, Float sampling) { - this(exprStr); - if (range != null && range > 0) { - this.range = range * 1000; // second to ms - } - this.func = func; - if (sampling != null) { - this.sampling = sampling; - } - - } - - public Expression(Map cond) { - - this.arg = (String) cond.get("metric"); - this.unit = Integer.parseInt((String) cond.get("unit")); - this.time_from = DateTimeHelper - .dateFormat(DateTimeHelper.getToday("yyyy-MM-dd") + " " + cond.get("time_from"), "yyyy-MM-dd HH:mm") - .getTime(); - this.time_to = DateTimeHelper - .dateFormat(DateTimeHelper.getToday("yyyy-MM-dd") + " " + cond.get("time_to"), "yyyy-MM-dd HH:mm") - .getTime(); - - this.time_start=(String) cond.get("time_start"); - - this.time_end= (String) cond.get("time_end"); - - this.day_start=(String) cond.get("day_start"); - - this.day_end= (String) cond.get("day_end"); - - if(cond.containsKey("weekdayLimit")) { - ((JSONArray)cond.get("weekdayLimit")).toArray(this.weekdayLimit); - } - - if (cond.get("interval") != null) { - long interval = Long.parseLong((String) cond.get("interval")); - switch (unit) { - case DateTimeHelper.INTERVAL_DAY: - interval = interval * 24 * 3600 * 1000; - break; - case DateTimeHelper.INTERVAL_HOUR: - interval = interval * 3600 * 1000; - break; - case DateTimeHelper.INTERVAL_MINUTE: - interval = interval * 60000; - break; - } - this.interval = interval; - } - - this.upperLimit = (String) cond.get("upperLimit"); - this.lowerLimit = (String) cond.get("lowerLimit"); - this.func = (String) cond.get("aggr"); - this.downsample=(String) cond.get("downsample"); - this.type = Type.TIMER; - } - - private void initMatchArgExpr() { - - if (this.arg.indexOf("*") > -1) { - String[] tmps = this.arg.split("\\*"); - for (String tmp : tmps) { - matchArgExpr.add(tmp); - } - } - } - - public boolean isMatchExpr() { - - return matchArgExpr.size() > 0; - } - - public Set matchTargetArgs(Set srcArgs) { - - Set targetArgs = new HashSet(); - - for (String arg : srcArgs) { - - int matchCount = 0; - for (String matchField : this.matchArgExpr) { - - if (arg.indexOf(matchField) > -1) { - matchCount++; - } - } - - if (matchCount == this.matchArgExpr.size()) { - targetArgs.add(arg); - } - } - - return targetArgs; - } - - public String getHashCode() { - - return EncodeHelper.encodeMD5(arg + func + lowerLimit + upperLimit + time_from + time_to + interval + unit); - } - - public String getArg() { - - return arg; - } - - public String getOperator() { - - return operator; - } - - public String getExpectedValue() { - - return expectedValue; - } - - public long getRange() { - - return range; - } - - public String getFunc() { - - return func; - } - - public float getSampling() { - - return sampling; - } - - public int getIdx() { - - return idx; - } - - public Type getType() { - - return type; - } - - public long getTime_from() { - - return time_from; - } - - public long getTime_to() { - - return time_to; - } - - public long getInterval() { - - return interval; - } - - public String getUpperLimit() { - - return upperLimit; - } - - public String getLowerLimit() { - - return lowerLimit; - } - - public int getUnit() { - - return unit; - } - - public void setIdx(int idx) { - - this.idx = idx; - } - - public String getTime_end() { - - return time_end; - } - - public String getTime_start() { - - return time_start; - } - - public String getDownsample() { - - return downsample; - } - - public String getDay_start() { - - return day_start; - } - - public String getDay_end() { - - return day_end; - } - - public Boolean[] getWeekdayLimit() { - - return weekdayLimit; - } - - } - - protected class Condition { - - private int index; - private List expressions; - private String relation; - - public Condition(int index, Expression expr) { - this.index = index; - List exprs = new ArrayList<>(1); - exprs.add(expr); - this.expressions = exprs; - } - - public Condition(int index, List exprs, String relation) { - this.index = index; - this.expressions = exprs; - this.relation = relation; - } - - public int getIndex() { - - return index; - } - - public List getExpressions() { - - return expressions; - } - - public String getRelation() { - - return relation; - } - - } - -} +/*- + * << + * UAVStack + * == + * Copyright (C) 2016 - 2017 UAVStack + * == + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * >> + */ + +package com.creditease.uav.feature.runtimenotify; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.alibaba.fastjson.JSONArray; +import com.creditease.agent.helpers.DateTimeHelper; +import com.creditease.agent.helpers.EncodeHelper; +import com.creditease.agent.helpers.JSONHelper; + +/** + * notify strategy ds + */ +public class NotifyStrategy { + + public enum Type { + STREAM("stream"), TIMER("timer"); + + private String name; + + Type(String name) { + this.name = name; + } + + @Override + public String toString() { + + return name; + } + } + + private static final String[] OPERATORS = { ":=", "!=", ">", "<", "=" }; + + private static final Pattern INDEX_PATTERN = Pattern.compile("\\[\\d+\\]"); + + private Type type; + + private String scope; + + private List condtions; + + private List convergences; + + private String msgTemplate; + + private Map action = Collections.emptyMap(); + + private List context = Collections.emptyList(); + + private List instances = Collections.emptyList(); + + private long maxRange = 0; + + private String name; + + public NotifyStrategy() { + } + + public NotifyStrategy(String name, String scope, List context, Map action, + List instances, String msgTemplate, List convergences) { + this.name = name; + this.scope = scope; + if (context != null && context.size() != 0) { + this.context = context; + } + if (action != null && action.size() != 0) { + this.action = action; + } + if (instances != null && instances.size() != 0) { + this.instances = instances; + } + this.convergences = convergences; + this.msgTemplate = msgTemplate; + } + + public void setConditions(List conditions, List relations) { + + int idx = 0; // expression count + List exprs = new ArrayList<>(); + for (Object o : conditions) { + + // condition is simple string: "arg>123" + if (String.class.isAssignableFrom(o.getClass())) { + Expression expression = new Expression((String) o); + expression.setIdx(idx++); + exprs.add(expression); + } + else { + @SuppressWarnings("unchecked") + Map cond = (Map) o; + Expression expression; + if (cond.get("type") == null || cond.get("type").equals(Type.STREAM.name)) { + String expr = (String) cond.get("expr"); + String func = (String) cond.get("func"); + Long range = cond.get("range") == null ? null : Long.valueOf(cond.get("range").toString()); + Float sampling = cond.get("sampling") == null ? null + : Float.valueOf(cond.get("sampling").toString()); + expression = new Expression(expr, func, range, sampling); + } + else { + String metricPrefix = name.substring(name.indexOf('@') + 1, name.lastIndexOf('@')); + cond.put("metric", metricPrefix + "." + cond.get("metric")); + expression = new Expression(cond); + this.type = Type.TIMER; + } + expression.setIdx(idx++); + exprs.add(expression); + } + } + + idx = 1; // reuse for condition count, start from 1 + List conds = null; + if (relations == null || relations.isEmpty()) { + conds = new ArrayList<>(conditions.size()); + + for (Expression expr : exprs) { + conds.add(new Condition(idx++, expr)); + } + } + else { + conds = new ArrayList<>(relations.size()); + for (String relation : relations) { + + Matcher m = INDEX_PATTERN.matcher(relation); + Set set = new HashSet<>(); + while (m.find()) { + String idxHolder = m.group(); + int i = Integer.parseInt(idxHolder.substring(1, idxHolder.length() - 1)); + if (i >= exprs.size()) { // IndexOutOfBoundsException + continue; + } + set.add(exprs.get(i)); + relation = relation.replace(idxHolder, "{" + i + "}"); // temp i + } + + List list = new ArrayList<>(set); + for (int i = 0; i < list.size(); i++) { + relation = relation.replace("{" + list.get(i).getIdx() + "}", "[" + i + "]"); + } + conds.add(new Condition(idx++, list, relation)); + } + } + + this.condtions = conds; + + /** init max range */ + for (Condition cond : this.condtions) { + for (Expression expr : cond.expressions) { + maxRange = Math.max(maxRange, expr.range); + } + } + + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static NotifyStrategy parse(String name, String json) { + + Map m = JSONHelper.toObject(json, Map.class); + String scope = (String) m.get("scope"); + List context = (List) m.get("context"); + List conditions = (List) m.get("conditions"); + List relations = (List) m.get("relations"); + List convergences = (List) m.get("convergences"); + Map action = (Map) m.get("action"); + String msgTemplate = (String) m.get("msgTemplate"); + List instances = (List) m.get("instances"); + + NotifyStrategy stra = new NotifyStrategy(name, scope, context, action, instances, msgTemplate, convergences); + + stra.setConditions(conditions, relations); + + return stra; + } + + public long getMaxRange() { + + return maxRange; + } + + public String getMsgTemplate() { + + return msgTemplate; + } + + public void setMsgTemplate(String msgTemplate) { + + this.msgTemplate = msgTemplate; + } + + public Map getAction() { + + return action; + } + + public void setAction(Map action) { + + this.action = action; + } + + public List getContext() { + + return context; + } + + public void setContext(List context) { + + this.context = context; + } + + public String getScope() { + + return scope; + } + + public void setScope(String scope) { + + this.scope = scope; + } + + public List getInstances() { + + return instances; + } + + public void setInstances(List instances) { + + this.instances = instances; + } + + public String getName() { + + return name; + } + + public Type getType() { + + return type; + } + + public List getCondtions() { + + return condtions; + } + + public List getConvergences() { + + return convergences; + } + + protected static class Expression { + + private int idx; + private Type type; + private String arg; + private String operator; + private String expectedValue; + private long range = 0; + private String func; + private float sampling = 1; + private String downsample; + private Boolean[] weekdayLimit=new Boolean[] {true,true,true,true,true,true,true}; + + private Set matchArgExpr = new HashSet(); + + private long time_from; + private long time_to; + private long interval; + private int unit; + private String upperLimit; + private String lowerLimit; + private String time_end; + private String time_start; + private String day_start; + private String day_end; + + public Expression(String exprStr) { + for (String op : OPERATORS) { + if (exprStr.contains(op)) { + String[] exprs = exprStr.split(op); + this.arg = exprs[0].trim(); + + // suport * as a match + initMatchArgExpr(); + + this.operator = op; + this.expectedValue = exprs[1]; + break; + } + } + this.type = Type.STREAM; + } + + public Expression(String exprStr, String func, Long range, Float sampling) { + this(exprStr); + if (range != null && range > 0) { + this.range = range * 1000; // second to ms + } + this.func = func; + if (sampling != null) { + this.sampling = sampling; + } + + } + + public Expression(Map cond) { + + this.arg = (String) cond.get("metric"); + this.unit = Integer.parseInt((String) cond.get("unit")); + this.time_from = DateTimeHelper + .dateFormat(DateTimeHelper.getToday("yyyy-MM-dd") + " " + cond.get("time_from"), "yyyy-MM-dd HH:mm") + .getTime(); + this.time_to = DateTimeHelper + .dateFormat(DateTimeHelper.getToday("yyyy-MM-dd") + " " + cond.get("time_to"), "yyyy-MM-dd HH:mm") + .getTime(); + + this.time_start=(String) cond.get("time_start"); + + this.time_end= (String) cond.get("time_end"); + + this.day_start=(String) cond.get("day_start"); + + this.day_end= (String) cond.get("day_end"); + + if(cond.containsKey("weekdayLimit")) { + ((JSONArray)cond.get("weekdayLimit")).toArray(this.weekdayLimit); + } + + if (cond.get("interval") != null) { + long interval = Long.parseLong((String) cond.get("interval")); + switch (unit) { + case DateTimeHelper.INTERVAL_DAY: + interval = interval * 24 * 3600 * 1000; + break; + case DateTimeHelper.INTERVAL_HOUR: + interval = interval * 3600 * 1000; + break; + case DateTimeHelper.INTERVAL_MINUTE: + interval = interval * 60000; + break; + } + this.interval = interval; + } + + this.upperLimit = (String) cond.get("upperLimit"); + this.lowerLimit = (String) cond.get("lowerLimit"); + this.func = (String) cond.get("aggr"); + this.downsample=(String) cond.get("downsample"); + this.type = Type.TIMER; + } + + private void initMatchArgExpr() { + + if (this.arg.indexOf("*") > -1) { + String[] tmps = this.arg.split("\\*"); + for (String tmp : tmps) { + matchArgExpr.add(tmp); + } + } + } + + public boolean isMatchExpr() { + + return matchArgExpr.size() > 0; + } + + public Set matchTargetArgs(Set srcArgs) { + + Set targetArgs = new HashSet(); + + for (String arg : srcArgs) { + + int matchCount = 0; + for (String matchField : this.matchArgExpr) { + + if (arg.indexOf(matchField) > -1) { + matchCount++; + } + } + + if (matchCount == this.matchArgExpr.size()) { + targetArgs.add(arg); + } + } + + return targetArgs; + } + + public String getHashCode() { + + return EncodeHelper.encodeMD5(arg + func + lowerLimit + upperLimit + time_from + time_to + interval + unit); + } + + public String getArg() { + + return arg; + } + + public String getOperator() { + + return operator; + } + + public String getExpectedValue() { + + return expectedValue; + } + + public long getRange() { + + return range; + } + + public String getFunc() { + + return func; + } + + public float getSampling() { + + return sampling; + } + + public int getIdx() { + + return idx; + } + + public Type getType() { + + return type; + } + + public long getTime_from() { + + return time_from; + } + + public long getTime_to() { + + return time_to; + } + + public long getInterval() { + + return interval; + } + + public String getUpperLimit() { + + return upperLimit; + } + + public String getLowerLimit() { + + return lowerLimit; + } + + public int getUnit() { + + return unit; + } + + public void setIdx(int idx) { + + this.idx = idx; + } + + public String getTime_end() { + + return time_end; + } + + public String getTime_start() { + + return time_start; + } + + public String getDownsample() { + + return downsample; + } + + public String getDay_start() { + + return day_start; + } + + public String getDay_end() { + + return day_end; + } + + public Boolean[] getWeekdayLimit() { + + return weekdayLimit; + } + + } + + protected class Condition { + + private int index; + private List expressions; + private String relation; + + public Condition(int index, Expression expr) { + this.index = index; + List exprs = new ArrayList<>(1); + exprs.add(expr); + this.expressions = exprs; + } + + public Condition(int index, List exprs, String relation) { + this.index = index; + this.expressions = exprs; + this.relation = relation; + } + + public int getIndex() { + + return index; + } + + public List getExpressions() { + + return expressions; + } + + public String getRelation() { + + return relation; + } + + } + +} diff --git a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/task/JudgeNotifyTimerTask.java b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/task/JudgeNotifyTimerTask.java index 08c91657..3497b89e 100644 --- a/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/task/JudgeNotifyTimerTask.java +++ b/com.creditease.uav.healthmanager/src/main/java/com/creditease/uav/feature/runtimenotify/task/JudgeNotifyTimerTask.java @@ -1,259 +1,259 @@ -/*- - * << - * UAVStack - * == - * Copyright (C) 2016 - 2017 UAVStack - * == - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * >> - */ - -package com.creditease.uav.feature.runtimenotify.task; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import com.creditease.agent.helpers.JSONHelper; -import com.creditease.agent.helpers.NetworkHelper; -import com.creditease.agent.helpers.StringHelper; -import com.creditease.agent.monitor.api.NotificationEvent; -import com.creditease.uav.cache.api.CacheManager; -import com.creditease.uav.cache.api.CacheManager.CacheLock; -import com.creditease.uav.feature.RuntimeNotifyCatcher; -import com.creditease.uav.feature.runtimenotify.NotifyStrategy; -import com.creditease.uav.feature.runtimenotify.Slice; -import com.creditease.uav.feature.runtimenotify.StrategyJudgement; -import com.creditease.uav.feature.runtimenotify.scheduler.RuntimeNotifyStrategyMgr; - -public class JudgeNotifyTimerTask extends JudgeNotifyCommonTask { - - private NotifyStrategy stra; - private long taskStart = System.currentTimeMillis(); - private long judge_time; - private static final String LOCK_REGION = "lock.region.uav"; - private static final long LOCK_TIMEOUT = 60 * 1000; - private CacheManager cm; - - public JudgeNotifyTimerTask(String name, String feature, long judge_time, NotifyStrategy stra) { - super(name, feature); - this.stra = stra; - this.judge_time = judge_time - judge_time % 60000; - cm = (CacheManager) this.getConfigManager().getComponent(feature, RuntimeNotifyCatcher.CACHE_MANAGER_NAME); - } - - @Override - public void run() { - - CacheLock lock = null; - try { - lock = cm.newCacheLock(LOCK_REGION, stra.getName(), LOCK_TIMEOUT); - - if (!lock.getLock()) { - return; - } - /** - * Step 1:find out instance - */ - for (String instance : stra.getInstances()) { - /** - * Step 2: judge the strategy - */ - - StrategyJudgement judgement = (StrategyJudgement) getConfigManager().getComponent(feature, - "StrategyJudgement"); - - Slice slice = new Slice(instance, judge_time); - Map args = new HashMap(); - // 标识该slice由TimerTask创建,为同环比创建,非流式计算创建 - args.put("creater", "timer"); - slice.setArgs(args); - - Map result = judgement.judge(slice, stra, null); - - /** - * Step 3: if fire the event, build notification event - */ - if (result != null && !result.isEmpty()) { - NotificationEvent event = this.newNotificationEvent(instance, result, stra.getConvergences()); - - // get context - putContext(slice,event); - - // get action - putNotifyAction(event, stra); - - // get msg tempalte - putNotifyMsg(event, stra); - - if (this.log.isTraceEnable()) { - this.log.info(this, "RuntimeNotify Notification Event Happen: event=" + event.toJSONString()); - } - - this.putNotificationEvent(event); - } - } - - } - catch (Exception e) { - log.err(this, "JudgeNotifyTimerTask" + stra.getName() + " RUN FAIL.", e); - } - finally { - if (lock != null && lock.isLockInHand()) { - lock.releaseLock(); - } - } - - if (log.isDebugEnable()) { - long cost = System.currentTimeMillis() - taskStart; - String detail = cost < 10 ? "" : " detail:strategy=" + JSONHelper.toString(stra); - log.debug(this, "whole task lifecycle COST: (" + cost + ")ms" + detail); - } - } - - /** - * get context - * - * TODO: we need support context param in strategy - */ - private void putContext(Slice slice, NotificationEvent event) { - - Map args = slice.getArgs(); - - for (String key : args.keySet()) { - - Object argVal = args.get(key); - - String jsonstr = JSONHelper.toString(argVal); - - event.addArg(key, jsonstr); - } - } - - /** - * newNotificationEvent - * - * - * @return - */ - private NotificationEvent newNotificationEvent(String instance, Map result, List convergences) { - - String ip = instance; - String host = instance; - String appgroup = "UNKNOWN"; - - instance = formatInstance(instance); - - Map infos = getInfoFromSliceCache(instance); - if (infos != null) { - ip = String.valueOf(infos.get("ip")); - host = String.valueOf(infos.get("host")); - appgroup = String.valueOf(infos.get("appgroup")); - } - - StringBuilder desc = new StringBuilder(); - List conditionIndex = new ArrayList(); - - for (Map.Entry cause : result.entrySet()) { - // description - desc.append(instance + "触发条件[" + cause.getKey() + "]:").append(cause.getValue()).append("\r\n"); - // condition index - conditionIndex.add(cause.getKey()); - } - - String title = ip + "[" + instance + "]触发" + result.size() + "个报警(条件序号: " + conditionIndex.toString().replaceAll("\\[|]|,", "") + ")"; - - // fix  (\u00A0) can be shown in email - String description = desc.toString().replace('\u00A0', ' '); - - NotificationEvent ne = new NotificationEvent(NotificationEvent.EVENT_RT_ALERT_THRESHOLD, title, description, - judge_time, ip, host); - - // add appgroup - ne.addArg("appgroup", appgroup); - - // 兼容不存在convergences属性的旧预警策略 - if(convergences == null || convergences.size() == 0 ) { - return ne; - } - - // 同一个Event由多个策略触发时,梯度收敛以最长的为准 - String conv = obtainConvergenceForEvent(convergences, conditionIndex); - if(!StringHelper.isEmpty(conv)) { - ne.addArg("convergences", conv); - ne.addArg(NotificationEvent.EVENT_Tag_NoBlock, "true"); - } - - return ne; - } - - private String formatInstance(String instance) { - - if (NetworkHelper.isIPV4(instance)) { - instance += "_"; - } - instance = stra.getName().substring(0, stra.getName().lastIndexOf('@') + 1) + instance; - - return instance; - } - - private Map getInfoFromSliceCache(String instance) { - - String cacheKey = "SLICE_" + instance + "_"; - for (int index = 0; index < 60; index++) { - String result = cm.lpop(RuntimeNotifyStrategyMgr.UAV_CACHE_REGION, cacheKey + index); - if (result != null) { - Slice s = new Slice(result); - return s.getArgs(); - } - } - - return null; - } - - private void putNotifyAction(NotificationEvent event, NotifyStrategy stra) { - - Map actions = stra.getAction(); - if (actions == null || actions.isEmpty()) { - return; - } - - for (Entry act : actions.entrySet()) { - event.addArg("action_" + act.getKey(), act.getValue()); - } - } - - private void putNotifyMsg(NotificationEvent event, NotifyStrategy stra) { - - String msgTemplate = stra.getMsgTemplate(); - String msg = makeMsgByTemplate(msgTemplate, stra); - - if (msg != null) { - event.addArg("msg", msg); - } - } - - /** - * - * @param template - * @param slice - * @return - */ - private String makeMsgByTemplate(String template, NotifyStrategy stra) { - - return ""; - } - -} +/*- + * << + * UAVStack + * == + * Copyright (C) 2016 - 2017 UAVStack + * == + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * >> + */ + +package com.creditease.uav.feature.runtimenotify.task; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.creditease.agent.helpers.JSONHelper; +import com.creditease.agent.helpers.NetworkHelper; +import com.creditease.agent.helpers.StringHelper; +import com.creditease.agent.monitor.api.NotificationEvent; +import com.creditease.uav.cache.api.CacheManager; +import com.creditease.uav.cache.api.CacheManager.CacheLock; +import com.creditease.uav.feature.RuntimeNotifyCatcher; +import com.creditease.uav.feature.runtimenotify.NotifyStrategy; +import com.creditease.uav.feature.runtimenotify.Slice; +import com.creditease.uav.feature.runtimenotify.StrategyJudgement; +import com.creditease.uav.feature.runtimenotify.scheduler.RuntimeNotifyStrategyMgr; + +public class JudgeNotifyTimerTask extends JudgeNotifyCommonTask { + + private NotifyStrategy stra; + private long taskStart = System.currentTimeMillis(); + private long judge_time; + private static final String LOCK_REGION = "lock.region.uav"; + private static final long LOCK_TIMEOUT = 60 * 1000; + private CacheManager cm; + + public JudgeNotifyTimerTask(String name, String feature, long judge_time, NotifyStrategy stra) { + super(name, feature); + this.stra = stra; + this.judge_time = judge_time - judge_time % 60000; + cm = (CacheManager) this.getConfigManager().getComponent(feature, RuntimeNotifyCatcher.CACHE_MANAGER_NAME); + } + + @Override + public void run() { + + CacheLock lock = null; + try { + lock = cm.newCacheLock(LOCK_REGION, stra.getName(), LOCK_TIMEOUT); + + if (!lock.getLock()) { + return; + } + /** + * Step 1:find out instance + */ + for (String instance : stra.getInstances()) { + /** + * Step 2: judge the strategy + */ + + StrategyJudgement judgement = (StrategyJudgement) getConfigManager().getComponent(feature, + "StrategyJudgement"); + + Slice slice = new Slice(instance, judge_time); + Map args = new HashMap(); + // 标识该slice由TimerTask创建,为同环比创建,非流式计算创建 + args.put("creater", "timer"); + slice.setArgs(args); + + Map result = judgement.judge(slice, stra, null); + + /** + * Step 3: if fire the event, build notification event + */ + if (result != null && !result.isEmpty()) { + NotificationEvent event = this.newNotificationEvent(instance, result, stra.getConvergences()); + + // get context + putContext(slice,event); + + // get action + putNotifyAction(event, stra); + + // get msg tempalte + putNotifyMsg(event, stra); + + if (this.log.isTraceEnable()) { + this.log.info(this, "RuntimeNotify Notification Event Happen: event=" + event.toJSONString()); + } + + this.putNotificationEvent(event); + } + } + + } + catch (Exception e) { + log.err(this, "JudgeNotifyTimerTask" + stra.getName() + " RUN FAIL.", e); + } + finally { + if (lock != null && lock.isLockInHand()) { + lock.releaseLock(); + } + } + + if (log.isDebugEnable()) { + long cost = System.currentTimeMillis() - taskStart; + String detail = cost < 10 ? "" : " detail:strategy=" + JSONHelper.toString(stra); + log.debug(this, "whole task lifecycle COST: (" + cost + ")ms" + detail); + } + } + + /** + * get context + * + * TODO: we need support context param in strategy + */ + private void putContext(Slice slice, NotificationEvent event) { + + Map args = slice.getArgs(); + + for (String key : args.keySet()) { + + Object argVal = args.get(key); + + String jsonstr = JSONHelper.toString(argVal); + + event.addArg(key, jsonstr); + } + } + + /** + * newNotificationEvent + * + * + * @return + */ + private NotificationEvent newNotificationEvent(String instance, Map result, List convergences) { + + String ip = instance; + String host = instance; + String appgroup = "UNKNOWN"; + + instance = formatInstance(instance); + + Map infos = getInfoFromSliceCache(instance); + if (infos != null) { + ip = String.valueOf(infos.get("ip")); + host = String.valueOf(infos.get("host")); + appgroup = String.valueOf(infos.get("appgroup")); + } + + StringBuilder desc = new StringBuilder(); + List conditionIndex = new ArrayList(); + + for (Map.Entry cause : result.entrySet()) { + // description + desc.append(instance + "触发条件[" + cause.getKey() + "]:").append(cause.getValue()).append("\r\n"); + // condition index + conditionIndex.add(cause.getKey()); + } + + String title = ip + "[" + instance + "]触发" + result.size() + "个报警(条件序号: " + conditionIndex.toString().replaceAll("\\[|]|,", "") + ")"; + + // fix  (\u00A0) can be shown in email + String description = desc.toString().replace('\u00A0', ' '); + + NotificationEvent ne = new NotificationEvent(NotificationEvent.EVENT_RT_ALERT_THRESHOLD, title, description, + judge_time, ip, host); + + // add appgroup + ne.addArg("appgroup", appgroup); + + // 兼容不存在convergences属性的旧预警策略 + if(convergences == null || convergences.size() == 0 ) { + return ne; + } + + // 同一个Event由多个策略触发时,梯度收敛以最长的为准 + String conv = obtainConvergenceForEvent(convergences, conditionIndex); + if(!StringHelper.isEmpty(conv)) { + ne.addArg("convergences", conv); + ne.addArg(NotificationEvent.EVENT_Tag_NoBlock, "true"); + } + + return ne; + } + + private String formatInstance(String instance) { + + if (NetworkHelper.isIPV4(instance)) { + instance += "_"; + } + instance = stra.getName().substring(0, stra.getName().lastIndexOf('@') + 1) + instance; + + return instance; + } + + private Map getInfoFromSliceCache(String instance) { + + String cacheKey = "SLICE_" + instance + "_"; + for (int index = 0; index < 60; index++) { + String result = cm.lpop(RuntimeNotifyStrategyMgr.UAV_CACHE_REGION, cacheKey + index); + if (result != null) { + Slice s = new Slice(result); + return s.getArgs(); + } + } + + return null; + } + + private void putNotifyAction(NotificationEvent event, NotifyStrategy stra) { + + Map actions = stra.getAction(); + if (actions == null || actions.isEmpty()) { + return; + } + + for (Entry act : actions.entrySet()) { + event.addArg("action_" + act.getKey(), act.getValue()); + } + } + + private void putNotifyMsg(NotificationEvent event, NotifyStrategy stra) { + + String msgTemplate = stra.getMsgTemplate(); + String msg = makeMsgByTemplate(msgTemplate, stra); + + if (msg != null) { + event.addArg("msg", msg); + } + } + + /** + * + * @param template + * @param slice + * @return + */ + private String makeMsgByTemplate(String template, NotifyStrategy stra) { + + return ""; + } + +} diff --git a/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/DateTimeHelper.java b/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/DateTimeHelper.java index 705a8bfe..fea71ac8 100644 --- a/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/DateTimeHelper.java +++ b/com.creditease.uav.helper/src/main/java/com/creditease/agent/helpers/DateTimeHelper.java @@ -1,1008 +1,1008 @@ -/*- - * << - * UAVStack - * == - * Copyright (C) 2016 - 2017 UAVStack - * == - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * >> - */ - -package com.creditease.agent.helpers; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; - -public class DateTimeHelper { - - /** - * 日 - */ - public final static int INTERVAL_DAY = 1; - - /** - * 周 - */ - public final static int INTERVAL_WEEK = 2; - - /** - * 月 - */ - public final static int INTERVAL_MONTH = 3; - - /** - * 年 - */ - public final static int INTERVAL_YEAR = 4; - - /** - * 小时 - */ - public final static int INTERVAL_HOUR = 5; - - /** - * 分钟 - */ - public final static int INTERVAL_MINUTE = 6; - - /** - * 秒 - */ - public final static int INTERVAL_SECOND = 7; - - /** - * date = 1901-01-01 - */ - public final static Date tempDate = new Date(new Long("-2177481952000"));; - - private DateTimeHelper() { - } - - /** - * toStandardDateFormat yyyy-MM-dd HH:mm:ss.SSS - * - * @param timestamp - * @return - */ - public static String toStandardDateFormat(long timestamp) { - - return toFormat("yyyy-MM-dd HH:mm:ss.SSS", timestamp); - } - - /** - * toFormat - * - * @param format - * @param timestamp - * @return - */ - public static String toFormat(String format, long timestamp) { - - SimpleDateFormat sdf = new SimpleDateFormat(format); - - return sdf.format(new Date(timestamp)); - } - - /** - * get the time range index in a time span (ms) for 24 hours - * - * @param timeFlag - * @param span - * @return - */ - public static long getTimeRangeIndex(long timeFlag, long span) { - - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - Calendar cl = Calendar.getInstance(); - - int year = cl.get(Calendar.YEAR); - int month = cl.get(Calendar.MONTH) + 1; - int day = cl.get(Calendar.DATE); - - long cTime = 0; - try { - Date d = sdf.parse(year + "-" + month + "-" + day + " 00:00:00"); - cTime = d.getTime(); - } - catch (ParseException e) { - // ignore - } - - long seconds = timeFlag - cTime; - - long timeRangeIndex = seconds / span; - - return timeRangeIndex; - } - - /** - * get the time range index in 1 min for 24 hours - * - * @param timeFlag - * @return - */ - public static long getTimeRangeIndexIn1Min(long timeFlag) { - - return getTimeRangeIndex(timeFlag, 60000); - } - - /** - * 测试是否是当天 - * - * @param date - * 某一日期 - * @return true 今天, false-不是 - */ - @SuppressWarnings("deprecation") - public static boolean isToday(Date date) { - - Date now = new Date(); - boolean result = true; - result &= date.getYear() == now.getYear(); - result &= date.getMonth() == now.getMonth(); - result &= date.getDate() == now.getDate(); - return result; - } - - /** - * 两个日期相减,取天数 - * - * @param date1 - * @param date2 - * @return - */ - public static long DaysBetween(Date date1, Date date2) { - - if (date2 == null) - date2 = new Date(); - long day = (date2.getTime() - date1.getTime()) / (24 * 60 * 60 * 1000); - return day; - } - - /** - * 比较两个日期 if date1<=date2 return true - * - * @param date1 - * @param date2 - * @return - */ - public static boolean compareDate(String date1, String date2) { - - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - Date d1 = format.parse(date1); - Date d2 = format.parse(date2); - return !d1.after(d2); - } - catch (ParseException e) { - e.printStackTrace(); - return false; - } - } - - /** - * 字符型转换成日期型 - * - * @param date - * @param dateFormat - * @return - */ - public static Date dateFormat(String date, String dateFormat) { - - if (date == null) - return null; - SimpleDateFormat format = new SimpleDateFormat(dateFormat); - if (date != null) { - try { - return format.parse(date); - } - catch (Exception ex) { - } - } - return null; - } - - /** - * 使用默认格式 yyyy-MM-dd HH:mm:ss - * - * @param date - * @return - */ - public static Date dateFormat(String date) { - - return dateFormat(date, "yyyy-MM-dd HH:mm:ss"); - } - - /** - * 日期型转换成字符串 - * - * @param date - * @param dateFormat - * @return - */ - public static String dateFormat(Date date, String dateFormat) { - - if (date != null) { - SimpleDateFormat format = new SimpleDateFormat(dateFormat); - if (date != null) { - return format.format(date); - } - } - return ""; - } - - /** - * 由于生日增加保密属性,现决定1900为保密对应值,如果遇到1900的年份,则隐掉年份 - * - * @param date - * @param dateFormat - * @return 不保密显示1981-12-01保密则显示`12-01 - */ - public static String birthdayFormat(Date date) { - - if (date != null) { - SimpleDateFormat format = null; - if (date.before(tempDate)) { - format = new SimpleDateFormat("MM-dd"); - } - else { - format = new SimpleDateFormat("yyyy-MM-dd"); - } - if (date != null) { - return format.format(date); - } - } - return ""; - } - - /** - * 使用默认格式 yyyy-MM-dd HH:mm:ss - * - * @param date - * @return - */ - public static String dateFormat(Date date) { - - return dateFormat(date, "yyyy-MM-dd HH:mm:ss"); - } - - public static boolean isExpiredDay(Date date1) { - - long day = (new Date().getTime() - date1.getTime()) / (24 * 60 * 60 * 1000); - if (day >= 1) - return true; - else - return false; - } - - public static Date getYesterday() { - - Date date = new Date(); - long time = (date.getTime() / 1000) - 60 * 60 * 24; - date.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - date = format.parse(format.format(date)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return date; - } - - public static Date getWeekAgo() { - - Date date = new Date(); - long time = (date.getTime() / 1000) - 7 * 60 * 60 * 24; - date.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - date = format.parse(format.format(date)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return date; - } - - public static String getDaysAgo(int interval) { - - Date date = new Date(); - long time = (date.getTime() / 1000) - interval * 60 * 60 * 24; - date.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - return format.format(date); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return ""; - } - - public static Date getTomorrow() { - - Date date = new Date(); - long time = (date.getTime() / 1000) + 60 * 60 * 24; - date.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - date = format.parse(format.format(date)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return date; - } - - public static Date getBeforeDate(String range) { - - Calendar today = Calendar.getInstance(); - if ("week".equalsIgnoreCase(range)) - today.add(Calendar.WEEK_OF_MONTH, -1); - else if ("month".equalsIgnoreCase(range)) - today.add(Calendar.MONTH, -1); - else - today.clear(); - return today.getTime(); - } - - public static Date getThisWeekStartTime() { - - Calendar today = Calendar.getInstance(); - today.set(Calendar.DAY_OF_WEEK, today.getFirstDayOfWeek()); - Calendar weekFirstDay = Calendar.getInstance(); - weekFirstDay.clear(); - weekFirstDay.set(Calendar.YEAR, today.get(Calendar.YEAR)); - weekFirstDay.set(Calendar.MONTH, today.get(Calendar.MONTH)); - weekFirstDay.set(Calendar.DATE, today.get(Calendar.DATE)); - return weekFirstDay.getTime(); - } - - public static String getToday(String format) { - - String result = ""; - try { - Date today = new Date(); - SimpleDateFormat simpleFormat = new SimpleDateFormat(format); - result = simpleFormat.format(today); - } - catch (Exception e) { - } - return result; - } - - public static Date getStartDay(int year, int month) { - - Calendar today = Calendar.getInstance(); - today.clear(); - today.set(Calendar.YEAR, year); - today.set(Calendar.MONTH, month - 1); - today.set(Calendar.DAY_OF_MONTH, 1); - return today.getTime(); - } - - public static List getBeforeYearList(int before) { - - Calendar today = Calendar.getInstance(); - int theYear = today.get(Calendar.YEAR); - List list = new ArrayList(); - for (int i = before; i >= 0; i--) - list.add(theYear - i); - - return list; - } - - /** - * 增加时间 - * - * @param interval - * [INTERVAL_DAY,INTERVAL_WEEK,INTERVAL_MONTH,INTERVAL_YEAR, INTERVAL_HOUR,INTERVAL_MINUTE] - * @param date - * @param n - * 可以为负数 - * @return - */ - public static Date dateAdd(int interval, Date date, int n) { - - long time = (date.getTime() / 1000); // 单位秒 - switch (interval) { - case INTERVAL_DAY: - time = time + n * 86400;// 60 * 60 * 24; - break; - case INTERVAL_WEEK: - time = time + n * 604800;// 60 * 60 * 24 * 7; - break; - case INTERVAL_MONTH: - time = time + n * 2678400;// 60 * 60 * 24 * 31; - break; - case INTERVAL_YEAR: - time = time + n * 31536000;// 60 * 60 * 24 * 365; - break; - case INTERVAL_HOUR: - time = time + n * 3600;// 60 * 60 ; - break; - case INTERVAL_MINUTE: - time = time + n * 60; - break; - case INTERVAL_SECOND: - time = time + n; - break; - default: - } - - Date result = new Date(); - result.setTime(time * 1000); - return result; - } - - /** - * 计算两个时间间隔 - * - * @param interval - * [INTERVAL_DAY,INTERVAL_WEEK,INTERVAL_MONTH,INTERVAL_YEAR, INTERVAL_HOUR,INTERVAL_MINUTE] - * @param begin - * @param end - * @return - */ - public static int dateDiff(int interval, Date begin, Date end) { - - long beginTime = (begin.getTime() / 1000); // 单位:秒 - long endTime = (end.getTime() / 1000); // 单位: 秒 - long tmp = 0; - if (endTime == beginTime) { - return 0; - } - - // 确定endTime 大于 beginTime 结束时间秒数 大于 开始时间秒数 - if (endTime < beginTime) { - tmp = beginTime; - beginTime = endTime; - endTime = tmp; - } - - long intervalTime = endTime - beginTime; - long result = 0; - switch (interval) { - case INTERVAL_DAY: - result = intervalTime / 86400;// 60 * 60 * 24; - break; - case INTERVAL_WEEK: - result = intervalTime / 604800;// 60 * 60 * 24 * 7; - break; - case INTERVAL_MONTH: - result = intervalTime / 2678400;// 60 * 60 * 24 * 31; - break; - case INTERVAL_YEAR: - result = intervalTime / 31536000;// 60 * 60 * 24 * 365; - break; - case INTERVAL_HOUR: - result = intervalTime / 3600;// 60 * 60 ; - break; - case INTERVAL_MINUTE: - result = intervalTime / 60; - break; - case INTERVAL_SECOND: - result = intervalTime / 1; - break; - default: - } - - // 做过交换 - if (tmp > 0) { - result = 0 - result; - } - return (int) result; - } - - /** - * 当前年份 - * - * @return - */ - public static int getTodayYear() { - - int yyyy = Integer.parseInt(dateFormat(new Date(), "yyyy")); - return yyyy; - } - - public static Date getNow() { - - return new Date(); - } - - /** - * 把日期格式为rss格式兼容的字符串 - * - * @param date - * @return - */ - public static String dateFormatRss(Date date) { - - if (date != null) { - return dateFormat(date, "E, d MMM yyyy H:mm:ss") + " GMT"; - } - return ""; - } - - /** - * 判断当前日期是否在两个日期之间 - * - * @param startDate - * 开始时间 - * @param endDate - * 结束时间 - * @return - */ - public static boolean betweenStartDateAndEndDate(Date startDate, Date endDate) { - - boolean bool = false; - Date curDate = new Date(); - if (curDate.after(startDate) && curDate.before(dateAdd(INTERVAL_DAY, endDate, 1))) { - bool = true; - } - return bool; - - } - - /** - * 判断当前时间是否在在两个时间之间 - * - * @param startDate - * 开始时间 - * @param endDate - * 结束时间 - * @return - */ - public static boolean nowDateBetweenStartDateAndEndDate(Date startDate, Date endDate) { - - boolean bool = false; - Date curDate = new Date(); - if (curDate.after(startDate) && curDate.before(endDate)) { - bool = true; - } - return bool; - } - - /** - * 判断当前时间是否在date之后 - * - * @param date - * @return - */ - public static boolean nowDateAfterDate(Date date) { - - boolean bool = false; - Date curDate = new Date(); - if (curDate.after(date)) { - bool = true; - } - return bool; - } - - /** - * 判断二个日期相隔的天数,结束时间为null时,,取当前时间 - * - * @param startDate - * 开始时间 - * @param endDate - * 结束时间 - * @return - */ - public static int getBetweenTodaysStartDateAndEndDate(Date startDate, Date endDate) { - - int betweentoday = 0; - if (startDate == null) { - return betweentoday; - } - if (endDate == null) { - Calendar calendar = Calendar.getInstance(); - String year = new Integer(calendar.get(Calendar.YEAR)).toString(); - String month = new Integer((calendar.get(Calendar.MONTH) + 1)).toString(); - String day = new Integer(calendar.get(Calendar.DAY_OF_MONTH)).toString(); - String strtodaytime = year + "-" + month + "-" + day; - DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); - try { - endDate = formatter.parse(strtodaytime); - } - catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - if (endDate.after(startDate)) { - betweentoday = (int) ((endDate.getTime() - startDate.getTime()) / 86400000); - } - else { - betweentoday = (int) ((startDate.getTime() - endDate.getTime()) / 86400000); - } - return betweentoday; - } - - /** - * 取得指定长度日期时间字符串{不含格式} - * - * @param format - * 时间格式由常量决定 8: YYMMDDHH 8位 10: YYMMDDHHmm 10位 12: YYMMDDHHmmss 12位 14: YYYYMMDDHHmmss 14位 15: - * YYMMDDHHmmssxxx 15位 (最后的xxx 是毫秒) - */ - public static String getTime(int format) { - - StringBuffer cTime = new StringBuffer(10); - Calendar time = Calendar.getInstance(); - int miltime = time.get(Calendar.MILLISECOND); - int second = time.get(Calendar.SECOND); - int minute = time.get(Calendar.MINUTE); - int hour = time.get(Calendar.HOUR_OF_DAY); - int day = time.get(Calendar.DAY_OF_MONTH); - int month = time.get(Calendar.MONTH) + 1; - int year = time.get(Calendar.YEAR); - if (format != 14) { - if (year >= 2000) - year = year - 2000; - else - year = year - 1900; - } - if (format >= 2) { - if (format == 14) - cTime.append(year); - else - cTime.append(getFormatTime(year, 2)); - } - if (format >= 4) - cTime.append(getFormatTime(month, 2)); - if (format >= 6) - cTime.append(getFormatTime(day, 2)); - if (format >= 8) - cTime.append(getFormatTime(hour, 2)); - if (format >= 10) - cTime.append(getFormatTime(minute, 2)); - if (format >= 12) - cTime.append(getFormatTime(second, 2)); - if (format >= 15) - cTime.append(getFormatTime(miltime, 3)); - return cTime.toString(); - } - - /** - * 产生任意位的字符串 - * - * @param time - * 要转换格式的时间 - * @param format - * 转换的格式 - * @return String 转换的时间 - */ - private static String getFormatTime(int time, int format) { - - StringBuffer numm = new StringBuffer(); - int length = String.valueOf(time).length(); - if (format < length) - return null; - for (int i = 0; i < format - length; i++) { - numm.append("0"); - } - numm.append(time); - return numm.toString().trim(); - } - - /** - * 根据生日去用户年龄 - * - * @param birthday - * @return int - * @exception @Date - * Apr 24, 2008 - */ - public static int getUserAge(Date birthday) { - - if (birthday == null) - return 0; - Calendar cal = Calendar.getInstance(); - if (cal.before(birthday)) { - return 0; - } - int yearNow = cal.get(Calendar.YEAR); - cal.setTime(birthday);// 给时间赋值 - int yearBirth = cal.get(Calendar.YEAR); - return yearNow - yearBirth; - } - - /** - * 将int型时间(1970年至今的秒数)转换成Date型时间 - * - * @param unixTime - * 1970年至今的秒数 - * @return - */ - public static Date getDateByUnixTime(int unixTime) { - - return new Date(unixTime * 1000L); - } - - public static long getUnixTimeLong() { - - return getUnixTimeByDate(new Date()); - } - - public static int getCurrentUnixTime() { - - return getUnixTimeByDate(new Date()); - } - - /** - * 将Date型时间转换成int型时间(1970年至今的秒数) - * - * @param unixTime - * 1970年至今的秒数 - * @return - */ - public static int getUnixTimeByDate(Date date) { - - return (int) (date.getTime() / 1000); - } - - public static long getUnixTimeLong(Date date) { - - return (date.getTime() / 1000); - } - - public static Date getNextDay(Date date) { - - long time = (date.getTime() / 1000) + 60 * 60 * 24; - date.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - date = format.parse(format.format(date)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return date; - - } - - /** - * @param date - * @return 复制新Date,不改变参数 - */ - public static Date nextDay(Date date) { - - Date newDate = (Date) date.clone(); - long time = (newDate.getTime() / 1000) + 60 * 60 * 24; - newDate.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - newDate = format.parse(format.format(newDate)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return newDate; - - } - - public static Date getNowTime() { - - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - Date date = new Date(); - String dateStr = dateFormat(date); - try { - date = format.parse(dateStr); - } - catch (ParseException e) { - e.printStackTrace(); - } - return date; - } - - public static Date getTomorrow(Date date1) { - - // 创建当前时间对象 - Calendar now = Calendar.getInstance(); - now.setTime(date1); - // 日期[+1]day - now.add(Calendar.DATE, 1); - return now.getTime(); - } - - public static Date getWeekAgo(Date date) { - - Date newDate = (Date) date.clone(); - long time = (newDate.getTime() / 1000) - 60 * 60 * 24 * 7; - newDate.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - newDate = format.parse(format.format(newDate)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return newDate; - } - - /** - * @param date - * @return 复制新Date,不改变参数 - */ - public static Date yesterday(Date date) { - - Date newDate = (Date) date.clone(); - long time = (newDate.getTime() / 1000) - 60 * 60 * 24; - newDate.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - newDate = format.parse(format.format(newDate)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return newDate; - } - - public static Date getYesterday(Date date) { - - long time = (date.getTime() / 1000) - 60 * 60 * 24; - date.setTime(time * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - date = format.parse(format.format(date)); - } - catch (Exception ex) { - System.out.println(ex.getMessage()); - } - return date; - } - - public static String getStringNowTime() { - - Date date = new Date(); - String dateStr = dateFormat(date); - return dateStr; - } - - /** - * 指定时间的秒数 指定时间零点的秒数加指定天数的秒数 - * - * @param time - * 时间 - * @param range - * 天 - * @return - */ - public static long getSpecifyTimeSec(long time, int range) { - - Date date = new Date((time * 1000 + (23 - Calendar.ZONE_OFFSET) * 3600000) / 86400000 * 86400000 - - (23 - Calendar.ZONE_OFFSET) * 3600000); - long zeroTime = date.getTime() / 1000; - long specifyTime = range * 24 * 3600; - return (zeroTime + specifyTime); - } - - /** - * 将int型时间(1970年至今的秒数)转换成指定格式的时间 - * - * @param unixTime - * 1970年至今的秒数 - * @param dateFormat - * 时间格式 - * @return - */ - public static String formatDateByUnixTime(long unixTime, String dateFormat) { - - return dateFormat(new Date(unixTime * 1000), dateFormat); - } - - private static List dateFormats = new ArrayList(12) { - - private static final long serialVersionUID = 2249396579858199535L; - { - add(new SimpleDateFormat("yyyy-MM-dd")); - add(new SimpleDateFormat("yyyy/MM/dd")); - add(new SimpleDateFormat("yyyy.MM.dd")); - add(new SimpleDateFormat("yyyy-MM-dd HH:24:mm:ss")); - add(new SimpleDateFormat("yyyy/MM/dd HH:24:mm:ss")); - add(new SimpleDateFormat("yyyy.MM.dd HH:24:mm:ss")); - add(new SimpleDateFormat("M/dd/yyyy")); - add(new SimpleDateFormat("dd.M.yyyy")); - add(new SimpleDateFormat("M/dd/yyyy hh:mm:ss a")); - add(new SimpleDateFormat("dd.M.yyyy hh:mm:ss a")); - add(new SimpleDateFormat("dd.MMM.yyyy")); - add(new SimpleDateFormat("dd-MMM-yyyy")); - } - }; - - public static Date convertToDate(String input) { - - Date date = null; - if (null == input) { - return null; - } - for (SimpleDateFormat format : dateFormats) { - try { - format.setLenient(false); - date = format.parse(input); - } - catch (ParseException e) { - // Shhh.. try other formats - } - if (date != null) { - break; - } - } - return date; - } - - public static Long getTodayTime() { - - Calendar today = Calendar.getInstance(); - today.set(Calendar.HOUR_OF_DAY, 0); - today.set(Calendar.MINUTE, 0); - today.set(Calendar.SECOND, 0); - return Long.valueOf(String.valueOf(today.getTimeInMillis()).substring(0, 10)); - } - - public static Long getYesterdayTime() { - - Calendar today = Calendar.getInstance(); - today.set(Calendar.HOUR_OF_DAY, -24); - today.set(Calendar.MINUTE, 0); - today.set(Calendar.SECOND, 0); - return Long.valueOf(String.valueOf(today.getTimeInMillis()).substring(0, 10)); - } - - public static Long getTomorrowTime() { - - Calendar tomorrow = Calendar.getInstance(); - tomorrow.set(Calendar.HOUR_OF_DAY, 24); - tomorrow.set(Calendar.MINUTE, 0); - tomorrow.set(Calendar.SECOND, 0); - return Long.valueOf(String.valueOf(tomorrow.getTimeInMillis()).substring(0, 10)); - } - - public static Date getMonthAgo(Date date) { - - Calendar now = Calendar.getInstance(); - now.setTime(date); - - now.add(Calendar.MONTH, -1); - - return now.getTime(); - } - - public static Date getYearAgo(Date date) { - - Calendar now = Calendar.getInstance(); - now.setTime(date); - - now.add(Calendar.YEAR, -1); - - return now.getTime(); - } - - public static int getWeekday(Date date) { - - Calendar cal = Calendar.getInstance(); - - cal.setTime(date); - - return cal.get(Calendar.DAY_OF_WEEK) - 1; - } -} +/*- + * << + * UAVStack + * == + * Copyright (C) 2016 - 2017 UAVStack + * == + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * >> + */ + +package com.creditease.agent.helpers; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +public class DateTimeHelper { + + /** + * 日 + */ + public final static int INTERVAL_DAY = 1; + + /** + * 周 + */ + public final static int INTERVAL_WEEK = 2; + + /** + * 月 + */ + public final static int INTERVAL_MONTH = 3; + + /** + * 年 + */ + public final static int INTERVAL_YEAR = 4; + + /** + * 小时 + */ + public final static int INTERVAL_HOUR = 5; + + /** + * 分钟 + */ + public final static int INTERVAL_MINUTE = 6; + + /** + * 秒 + */ + public final static int INTERVAL_SECOND = 7; + + /** + * date = 1901-01-01 + */ + public final static Date tempDate = new Date(new Long("-2177481952000"));; + + private DateTimeHelper() { + } + + /** + * toStandardDateFormat yyyy-MM-dd HH:mm:ss.SSS + * + * @param timestamp + * @return + */ + public static String toStandardDateFormat(long timestamp) { + + return toFormat("yyyy-MM-dd HH:mm:ss.SSS", timestamp); + } + + /** + * toFormat + * + * @param format + * @param timestamp + * @return + */ + public static String toFormat(String format, long timestamp) { + + SimpleDateFormat sdf = new SimpleDateFormat(format); + + return sdf.format(new Date(timestamp)); + } + + /** + * get the time range index in a time span (ms) for 24 hours + * + * @param timeFlag + * @param span + * @return + */ + public static long getTimeRangeIndex(long timeFlag, long span) { + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + Calendar cl = Calendar.getInstance(); + + int year = cl.get(Calendar.YEAR); + int month = cl.get(Calendar.MONTH) + 1; + int day = cl.get(Calendar.DATE); + + long cTime = 0; + try { + Date d = sdf.parse(year + "-" + month + "-" + day + " 00:00:00"); + cTime = d.getTime(); + } + catch (ParseException e) { + // ignore + } + + long seconds = timeFlag - cTime; + + long timeRangeIndex = seconds / span; + + return timeRangeIndex; + } + + /** + * get the time range index in 1 min for 24 hours + * + * @param timeFlag + * @return + */ + public static long getTimeRangeIndexIn1Min(long timeFlag) { + + return getTimeRangeIndex(timeFlag, 60000); + } + + /** + * 测试是否是当天 + * + * @param date + * 某一日期 + * @return true 今天, false-不是 + */ + @SuppressWarnings("deprecation") + public static boolean isToday(Date date) { + + Date now = new Date(); + boolean result = true; + result &= date.getYear() == now.getYear(); + result &= date.getMonth() == now.getMonth(); + result &= date.getDate() == now.getDate(); + return result; + } + + /** + * 两个日期相减,取天数 + * + * @param date1 + * @param date2 + * @return + */ + public static long DaysBetween(Date date1, Date date2) { + + if (date2 == null) + date2 = new Date(); + long day = (date2.getTime() - date1.getTime()) / (24 * 60 * 60 * 1000); + return day; + } + + /** + * 比较两个日期 if date1<=date2 return true + * + * @param date1 + * @param date2 + * @return + */ + public static boolean compareDate(String date1, String date2) { + + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + Date d1 = format.parse(date1); + Date d2 = format.parse(date2); + return !d1.after(d2); + } + catch (ParseException e) { + e.printStackTrace(); + return false; + } + } + + /** + * 字符型转换成日期型 + * + * @param date + * @param dateFormat + * @return + */ + public static Date dateFormat(String date, String dateFormat) { + + if (date == null) + return null; + SimpleDateFormat format = new SimpleDateFormat(dateFormat); + if (date != null) { + try { + return format.parse(date); + } + catch (Exception ex) { + } + } + return null; + } + + /** + * 使用默认格式 yyyy-MM-dd HH:mm:ss + * + * @param date + * @return + */ + public static Date dateFormat(String date) { + + return dateFormat(date, "yyyy-MM-dd HH:mm:ss"); + } + + /** + * 日期型转换成字符串 + * + * @param date + * @param dateFormat + * @return + */ + public static String dateFormat(Date date, String dateFormat) { + + if (date != null) { + SimpleDateFormat format = new SimpleDateFormat(dateFormat); + if (date != null) { + return format.format(date); + } + } + return ""; + } + + /** + * 由于生日增加保密属性,现决定1900为保密对应值,如果遇到1900的年份,则隐掉年份 + * + * @param date + * @param dateFormat + * @return 不保密显示1981-12-01保密则显示`12-01 + */ + public static String birthdayFormat(Date date) { + + if (date != null) { + SimpleDateFormat format = null; + if (date.before(tempDate)) { + format = new SimpleDateFormat("MM-dd"); + } + else { + format = new SimpleDateFormat("yyyy-MM-dd"); + } + if (date != null) { + return format.format(date); + } + } + return ""; + } + + /** + * 使用默认格式 yyyy-MM-dd HH:mm:ss + * + * @param date + * @return + */ + public static String dateFormat(Date date) { + + return dateFormat(date, "yyyy-MM-dd HH:mm:ss"); + } + + public static boolean isExpiredDay(Date date1) { + + long day = (new Date().getTime() - date1.getTime()) / (24 * 60 * 60 * 1000); + if (day >= 1) + return true; + else + return false; + } + + public static Date getYesterday() { + + Date date = new Date(); + long time = (date.getTime() / 1000) - 60 * 60 * 24; + date.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + date = format.parse(format.format(date)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return date; + } + + public static Date getWeekAgo() { + + Date date = new Date(); + long time = (date.getTime() / 1000) - 7 * 60 * 60 * 24; + date.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + date = format.parse(format.format(date)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return date; + } + + public static String getDaysAgo(int interval) { + + Date date = new Date(); + long time = (date.getTime() / 1000) - interval * 60 * 60 * 24; + date.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + return format.format(date); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return ""; + } + + public static Date getTomorrow() { + + Date date = new Date(); + long time = (date.getTime() / 1000) + 60 * 60 * 24; + date.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + date = format.parse(format.format(date)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return date; + } + + public static Date getBeforeDate(String range) { + + Calendar today = Calendar.getInstance(); + if ("week".equalsIgnoreCase(range)) + today.add(Calendar.WEEK_OF_MONTH, -1); + else if ("month".equalsIgnoreCase(range)) + today.add(Calendar.MONTH, -1); + else + today.clear(); + return today.getTime(); + } + + public static Date getThisWeekStartTime() { + + Calendar today = Calendar.getInstance(); + today.set(Calendar.DAY_OF_WEEK, today.getFirstDayOfWeek()); + Calendar weekFirstDay = Calendar.getInstance(); + weekFirstDay.clear(); + weekFirstDay.set(Calendar.YEAR, today.get(Calendar.YEAR)); + weekFirstDay.set(Calendar.MONTH, today.get(Calendar.MONTH)); + weekFirstDay.set(Calendar.DATE, today.get(Calendar.DATE)); + return weekFirstDay.getTime(); + } + + public static String getToday(String format) { + + String result = ""; + try { + Date today = new Date(); + SimpleDateFormat simpleFormat = new SimpleDateFormat(format); + result = simpleFormat.format(today); + } + catch (Exception e) { + } + return result; + } + + public static Date getStartDay(int year, int month) { + + Calendar today = Calendar.getInstance(); + today.clear(); + today.set(Calendar.YEAR, year); + today.set(Calendar.MONTH, month - 1); + today.set(Calendar.DAY_OF_MONTH, 1); + return today.getTime(); + } + + public static List getBeforeYearList(int before) { + + Calendar today = Calendar.getInstance(); + int theYear = today.get(Calendar.YEAR); + List list = new ArrayList(); + for (int i = before; i >= 0; i--) + list.add(theYear - i); + + return list; + } + + /** + * 增加时间 + * + * @param interval + * [INTERVAL_DAY,INTERVAL_WEEK,INTERVAL_MONTH,INTERVAL_YEAR, INTERVAL_HOUR,INTERVAL_MINUTE] + * @param date + * @param n + * 可以为负数 + * @return + */ + public static Date dateAdd(int interval, Date date, int n) { + + long time = (date.getTime() / 1000); // 单位秒 + switch (interval) { + case INTERVAL_DAY: + time = time + n * 86400;// 60 * 60 * 24; + break; + case INTERVAL_WEEK: + time = time + n * 604800;// 60 * 60 * 24 * 7; + break; + case INTERVAL_MONTH: + time = time + n * 2678400;// 60 * 60 * 24 * 31; + break; + case INTERVAL_YEAR: + time = time + n * 31536000;// 60 * 60 * 24 * 365; + break; + case INTERVAL_HOUR: + time = time + n * 3600;// 60 * 60 ; + break; + case INTERVAL_MINUTE: + time = time + n * 60; + break; + case INTERVAL_SECOND: + time = time + n; + break; + default: + } + + Date result = new Date(); + result.setTime(time * 1000); + return result; + } + + /** + * 计算两个时间间隔 + * + * @param interval + * [INTERVAL_DAY,INTERVAL_WEEK,INTERVAL_MONTH,INTERVAL_YEAR, INTERVAL_HOUR,INTERVAL_MINUTE] + * @param begin + * @param end + * @return + */ + public static int dateDiff(int interval, Date begin, Date end) { + + long beginTime = (begin.getTime() / 1000); // 单位:秒 + long endTime = (end.getTime() / 1000); // 单位: 秒 + long tmp = 0; + if (endTime == beginTime) { + return 0; + } + + // 确定endTime 大于 beginTime 结束时间秒数 大于 开始时间秒数 + if (endTime < beginTime) { + tmp = beginTime; + beginTime = endTime; + endTime = tmp; + } + + long intervalTime = endTime - beginTime; + long result = 0; + switch (interval) { + case INTERVAL_DAY: + result = intervalTime / 86400;// 60 * 60 * 24; + break; + case INTERVAL_WEEK: + result = intervalTime / 604800;// 60 * 60 * 24 * 7; + break; + case INTERVAL_MONTH: + result = intervalTime / 2678400;// 60 * 60 * 24 * 31; + break; + case INTERVAL_YEAR: + result = intervalTime / 31536000;// 60 * 60 * 24 * 365; + break; + case INTERVAL_HOUR: + result = intervalTime / 3600;// 60 * 60 ; + break; + case INTERVAL_MINUTE: + result = intervalTime / 60; + break; + case INTERVAL_SECOND: + result = intervalTime / 1; + break; + default: + } + + // 做过交换 + if (tmp > 0) { + result = 0 - result; + } + return (int) result; + } + + /** + * 当前年份 + * + * @return + */ + public static int getTodayYear() { + + int yyyy = Integer.parseInt(dateFormat(new Date(), "yyyy")); + return yyyy; + } + + public static Date getNow() { + + return new Date(); + } + + /** + * 把日期格式为rss格式兼容的字符串 + * + * @param date + * @return + */ + public static String dateFormatRss(Date date) { + + if (date != null) { + return dateFormat(date, "E, d MMM yyyy H:mm:ss") + " GMT"; + } + return ""; + } + + /** + * 判断当前日期是否在两个日期之间 + * + * @param startDate + * 开始时间 + * @param endDate + * 结束时间 + * @return + */ + public static boolean betweenStartDateAndEndDate(Date startDate, Date endDate) { + + boolean bool = false; + Date curDate = new Date(); + if (curDate.after(startDate) && curDate.before(dateAdd(INTERVAL_DAY, endDate, 1))) { + bool = true; + } + return bool; + + } + + /** + * 判断当前时间是否在在两个时间之间 + * + * @param startDate + * 开始时间 + * @param endDate + * 结束时间 + * @return + */ + public static boolean nowDateBetweenStartDateAndEndDate(Date startDate, Date endDate) { + + boolean bool = false; + Date curDate = new Date(); + if (curDate.after(startDate) && curDate.before(endDate)) { + bool = true; + } + return bool; + } + + /** + * 判断当前时间是否在date之后 + * + * @param date + * @return + */ + public static boolean nowDateAfterDate(Date date) { + + boolean bool = false; + Date curDate = new Date(); + if (curDate.after(date)) { + bool = true; + } + return bool; + } + + /** + * 判断二个日期相隔的天数,结束时间为null时,,取当前时间 + * + * @param startDate + * 开始时间 + * @param endDate + * 结束时间 + * @return + */ + public static int getBetweenTodaysStartDateAndEndDate(Date startDate, Date endDate) { + + int betweentoday = 0; + if (startDate == null) { + return betweentoday; + } + if (endDate == null) { + Calendar calendar = Calendar.getInstance(); + String year = new Integer(calendar.get(Calendar.YEAR)).toString(); + String month = new Integer((calendar.get(Calendar.MONTH) + 1)).toString(); + String day = new Integer(calendar.get(Calendar.DAY_OF_MONTH)).toString(); + String strtodaytime = year + "-" + month + "-" + day; + DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + try { + endDate = formatter.parse(strtodaytime); + } + catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + if (endDate.after(startDate)) { + betweentoday = (int) ((endDate.getTime() - startDate.getTime()) / 86400000); + } + else { + betweentoday = (int) ((startDate.getTime() - endDate.getTime()) / 86400000); + } + return betweentoday; + } + + /** + * 取得指定长度日期时间字符串{不含格式} + * + * @param format + * 时间格式由常量决定 8: YYMMDDHH 8位 10: YYMMDDHHmm 10位 12: YYMMDDHHmmss 12位 14: YYYYMMDDHHmmss 14位 15: + * YYMMDDHHmmssxxx 15位 (最后的xxx 是毫秒) + */ + public static String getTime(int format) { + + StringBuffer cTime = new StringBuffer(10); + Calendar time = Calendar.getInstance(); + int miltime = time.get(Calendar.MILLISECOND); + int second = time.get(Calendar.SECOND); + int minute = time.get(Calendar.MINUTE); + int hour = time.get(Calendar.HOUR_OF_DAY); + int day = time.get(Calendar.DAY_OF_MONTH); + int month = time.get(Calendar.MONTH) + 1; + int year = time.get(Calendar.YEAR); + if (format != 14) { + if (year >= 2000) + year = year - 2000; + else + year = year - 1900; + } + if (format >= 2) { + if (format == 14) + cTime.append(year); + else + cTime.append(getFormatTime(year, 2)); + } + if (format >= 4) + cTime.append(getFormatTime(month, 2)); + if (format >= 6) + cTime.append(getFormatTime(day, 2)); + if (format >= 8) + cTime.append(getFormatTime(hour, 2)); + if (format >= 10) + cTime.append(getFormatTime(minute, 2)); + if (format >= 12) + cTime.append(getFormatTime(second, 2)); + if (format >= 15) + cTime.append(getFormatTime(miltime, 3)); + return cTime.toString(); + } + + /** + * 产生任意位的字符串 + * + * @param time + * 要转换格式的时间 + * @param format + * 转换的格式 + * @return String 转换的时间 + */ + private static String getFormatTime(int time, int format) { + + StringBuffer numm = new StringBuffer(); + int length = String.valueOf(time).length(); + if (format < length) + return null; + for (int i = 0; i < format - length; i++) { + numm.append("0"); + } + numm.append(time); + return numm.toString().trim(); + } + + /** + * 根据生日去用户年龄 + * + * @param birthday + * @return int + * @exception @Date + * Apr 24, 2008 + */ + public static int getUserAge(Date birthday) { + + if (birthday == null) + return 0; + Calendar cal = Calendar.getInstance(); + if (cal.before(birthday)) { + return 0; + } + int yearNow = cal.get(Calendar.YEAR); + cal.setTime(birthday);// 给时间赋值 + int yearBirth = cal.get(Calendar.YEAR); + return yearNow - yearBirth; + } + + /** + * 将int型时间(1970年至今的秒数)转换成Date型时间 + * + * @param unixTime + * 1970年至今的秒数 + * @return + */ + public static Date getDateByUnixTime(int unixTime) { + + return new Date(unixTime * 1000L); + } + + public static long getUnixTimeLong() { + + return getUnixTimeByDate(new Date()); + } + + public static int getCurrentUnixTime() { + + return getUnixTimeByDate(new Date()); + } + + /** + * 将Date型时间转换成int型时间(1970年至今的秒数) + * + * @param unixTime + * 1970年至今的秒数 + * @return + */ + public static int getUnixTimeByDate(Date date) { + + return (int) (date.getTime() / 1000); + } + + public static long getUnixTimeLong(Date date) { + + return (date.getTime() / 1000); + } + + public static Date getNextDay(Date date) { + + long time = (date.getTime() / 1000) + 60 * 60 * 24; + date.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + date = format.parse(format.format(date)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return date; + + } + + /** + * @param date + * @return 复制新Date,不改变参数 + */ + public static Date nextDay(Date date) { + + Date newDate = (Date) date.clone(); + long time = (newDate.getTime() / 1000) + 60 * 60 * 24; + newDate.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + newDate = format.parse(format.format(newDate)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return newDate; + + } + + public static Date getNowTime() { + + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(); + String dateStr = dateFormat(date); + try { + date = format.parse(dateStr); + } + catch (ParseException e) { + e.printStackTrace(); + } + return date; + } + + public static Date getTomorrow(Date date1) { + + // 创建当前时间对象 + Calendar now = Calendar.getInstance(); + now.setTime(date1); + // 日期[+1]day + now.add(Calendar.DATE, 1); + return now.getTime(); + } + + public static Date getWeekAgo(Date date) { + + Date newDate = (Date) date.clone(); + long time = (newDate.getTime() / 1000) - 60 * 60 * 24 * 7; + newDate.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + newDate = format.parse(format.format(newDate)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return newDate; + } + + /** + * @param date + * @return 复制新Date,不改变参数 + */ + public static Date yesterday(Date date) { + + Date newDate = (Date) date.clone(); + long time = (newDate.getTime() / 1000) - 60 * 60 * 24; + newDate.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + newDate = format.parse(format.format(newDate)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return newDate; + } + + public static Date getYesterday(Date date) { + + long time = (date.getTime() / 1000) - 60 * 60 * 24; + date.setTime(time * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + date = format.parse(format.format(date)); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + return date; + } + + public static String getStringNowTime() { + + Date date = new Date(); + String dateStr = dateFormat(date); + return dateStr; + } + + /** + * 指定时间的秒数 指定时间零点的秒数加指定天数的秒数 + * + * @param time + * 时间 + * @param range + * 天 + * @return + */ + public static long getSpecifyTimeSec(long time, int range) { + + Date date = new Date((time * 1000 + (23 - Calendar.ZONE_OFFSET) * 3600000) / 86400000 * 86400000 + - (23 - Calendar.ZONE_OFFSET) * 3600000); + long zeroTime = date.getTime() / 1000; + long specifyTime = range * 24 * 3600; + return (zeroTime + specifyTime); + } + + /** + * 将int型时间(1970年至今的秒数)转换成指定格式的时间 + * + * @param unixTime + * 1970年至今的秒数 + * @param dateFormat + * 时间格式 + * @return + */ + public static String formatDateByUnixTime(long unixTime, String dateFormat) { + + return dateFormat(new Date(unixTime * 1000), dateFormat); + } + + private static List dateFormats = new ArrayList(12) { + + private static final long serialVersionUID = 2249396579858199535L; + { + add(new SimpleDateFormat("yyyy-MM-dd")); + add(new SimpleDateFormat("yyyy/MM/dd")); + add(new SimpleDateFormat("yyyy.MM.dd")); + add(new SimpleDateFormat("yyyy-MM-dd HH:24:mm:ss")); + add(new SimpleDateFormat("yyyy/MM/dd HH:24:mm:ss")); + add(new SimpleDateFormat("yyyy.MM.dd HH:24:mm:ss")); + add(new SimpleDateFormat("M/dd/yyyy")); + add(new SimpleDateFormat("dd.M.yyyy")); + add(new SimpleDateFormat("M/dd/yyyy hh:mm:ss a")); + add(new SimpleDateFormat("dd.M.yyyy hh:mm:ss a")); + add(new SimpleDateFormat("dd.MMM.yyyy")); + add(new SimpleDateFormat("dd-MMM-yyyy")); + } + }; + + public static Date convertToDate(String input) { + + Date date = null; + if (null == input) { + return null; + } + for (SimpleDateFormat format : dateFormats) { + try { + format.setLenient(false); + date = format.parse(input); + } + catch (ParseException e) { + // Shhh.. try other formats + } + if (date != null) { + break; + } + } + return date; + } + + public static Long getTodayTime() { + + Calendar today = Calendar.getInstance(); + today.set(Calendar.HOUR_OF_DAY, 0); + today.set(Calendar.MINUTE, 0); + today.set(Calendar.SECOND, 0); + return Long.valueOf(String.valueOf(today.getTimeInMillis()).substring(0, 10)); + } + + public static Long getYesterdayTime() { + + Calendar today = Calendar.getInstance(); + today.set(Calendar.HOUR_OF_DAY, -24); + today.set(Calendar.MINUTE, 0); + today.set(Calendar.SECOND, 0); + return Long.valueOf(String.valueOf(today.getTimeInMillis()).substring(0, 10)); + } + + public static Long getTomorrowTime() { + + Calendar tomorrow = Calendar.getInstance(); + tomorrow.set(Calendar.HOUR_OF_DAY, 24); + tomorrow.set(Calendar.MINUTE, 0); + tomorrow.set(Calendar.SECOND, 0); + return Long.valueOf(String.valueOf(tomorrow.getTimeInMillis()).substring(0, 10)); + } + + public static Date getMonthAgo(Date date) { + + Calendar now = Calendar.getInstance(); + now.setTime(date); + + now.add(Calendar.MONTH, -1); + + return now.getTime(); + } + + public static Date getYearAgo(Date date) { + + Calendar now = Calendar.getInstance(); + now.setTime(date); + + now.add(Calendar.YEAR, -1); + + return now.getTime(); + } + + public static int getWeekday(Date date) { + + Calendar cal = Calendar.getInstance(); + + cal.setTime(date); + + return cal.get(Calendar.DAY_OF_WEEK) - 1; + } +} diff --git a/com.creditease.uav.hook.mq/src/main/java/com/creditease/uav/hook/rabbitmq/interceptors/RabbitmqIT.java b/com.creditease.uav.hook.mq/src/main/java/com/creditease/uav/hook/rabbitmq/interceptors/RabbitmqIT.java index b14e429f..662ea72e 100644 --- a/com.creditease.uav.hook.mq/src/main/java/com/creditease/uav/hook/rabbitmq/interceptors/RabbitmqIT.java +++ b/com.creditease.uav.hook.mq/src/main/java/com/creditease/uav/hook/rabbitmq/interceptors/RabbitmqIT.java @@ -1,365 +1,365 @@ -/*- - * << - * UAVStack - * == - * Copyright (C) 2016 - 2017 UAVStack - * == - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * >> - */ - -package com.creditease.uav.hook.rabbitmq.interceptors; - -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.creditease.monitor.UAVServer; -import com.creditease.monitor.captureframework.spi.CaptureConstants; -import com.creditease.monitor.captureframework.spi.Monitor; -import com.creditease.monitor.proxy.spi.JDKProxyInvokeHandler; -import com.creditease.monitor.proxy.spi.JDKProxyInvokeProcessor; -import com.creditease.uav.apm.invokechain.spi.InvokeChainConstants; -import com.creditease.uav.common.BaseComponent; -import com.creditease.uav.hook.rabbitmq.adapter.RabbitmqConsumerAdapter; -import com.creditease.uav.hook.rabbitmq.adapter.RabbitmqProducerAdapter; -import com.creditease.uav.util.JDKProxyInvokeUtil; -import com.rabbitmq.client.AMQP; -import com.rabbitmq.client.AMQP.BasicProperties; -import com.rabbitmq.client.Channel; -import com.rabbitmq.client.Connection; -import com.rabbitmq.client.Consumer; - -public class RabbitmqIT extends BaseComponent { - - private String applicationId; - static final Map queueNameIndex = new HashMap(); - static { - queueNameIndex.put("basicPublish", 1); - queueNameIndex.put("queueDeclare", 0); - queueNameIndex.put("queueDeclareNoWait", 0); - queueNameIndex.put("queueDeclarePassive", 0); - queueNameIndex.put("queueDelete", 0); - queueNameIndex.put("queueDeleteNoWait", 0); - queueNameIndex.put("queueBind", 0); - queueNameIndex.put("queueBindNoWait", 0); - queueNameIndex.put("queueUnbind", 0); - queueNameIndex.put("queuePurge", 0); - queueNameIndex.put("basicGet", 0); - queueNameIndex.put("basicConsume", 0); - } - - public RabbitmqIT(String appid) { - this.applicationId = appid; - } - - public Connection doInstall(Connection arg) { - - arg = JDKProxyInvokeUtil.newProxyInstance(Connection.class.getClassLoader(), - new Class[] { Connection.class }, - new JDKProxyInvokeHandler(arg, new ConnectionProxyProcessor())); - - return arg; - } - - /** - * - * ConnectionProxyProcessor description: ConnectionProxyProcessor - * - */ - public class ConnectionProxyProcessor extends JDKProxyInvokeProcessor { - - @Override - public void preProcess(Connection t, Object proxy, Method method, Object[] args) { - - } - - @Override - public Object postProcess(Object res, Connection t, Object proxy, Method method, Object[] args) { - - if (method.getName().equals("createChannel")) { - return JDKProxyInvokeUtil.newProxyInstance(Channel.class.getClassLoader(), - new Class[] { Channel.class }, - new JDKProxyInvokeHandler((Channel) res, new ChannelProxyProcessor())); - } - return null; - } - - } - - /** - * - * ChannelProxyProcessor description: ChannelProxyProcessor - * - */ - public class ChannelProxyProcessor extends JDKProxyInvokeProcessor { - - String address; - String targetServer; - private Map ivcContextParams = new HashMap(); - - @SuppressWarnings("unchecked") - @Override - public void preProcess(Channel t, Object proxy, Method method, Object[] args) { - - if (method.getExceptionTypes().length > 0 - && method.getExceptionTypes()[0].getName().equals(IOException.class.getName())) { - String methodName = method.getName(); - String queueName = null; - if (queueNameIndex.containsKey(methodName) && args.length != 0) { - - queueName = (String) args[queueNameIndex.get(methodName)]; - if (isTempQueue(queueName)) { - return; - } - - } - - if (null == address) { - address = t.getConnection().getAddress().getHostAddress() + ":" + t.getConnection().getPort(); - address = "mq:rabbit://" + address; - } - String url = address + ((null == queueName) ? "" : "/" + queueName); - - if ("basicConsume".equals(method.getName())) { - // delegate the consumer - args[args.length - 1] = JDKProxyInvokeUtil.newProxyInstance(Consumer.class.getClassLoader(), - new Class[] { Consumer.class }, new JDKProxyInvokeHandler( - (Consumer) args[args.length - 1], new ConsumerProxyProcessor(t, url))); - - } - - Map params = new HashMap(); - params.put(CaptureConstants.INFO_CLIENT_REQUEST_URL, url); - params.put(CaptureConstants.INFO_CLIENT_REQUEST_ACTION, method.getName()); - params.put(CaptureConstants.INFO_CLIENT_APPID, applicationId); - params.put(CaptureConstants.INFO_CLIENT_TYPE, "rabbitmq.client"); - - if (logger.isDebugable()) { - logger.debug("Invoke START:" + url + ",op=" + method.getName(), null); - } - - UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, - Monitor.CapturePhase.PRECAP, params); - - // 调用链只关心真正的消息通讯 - if (method.getName().equals("basicPublish")) { - - // register adapter - UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", - "registerAdapter", RabbitmqProducerAdapter.class); - - ivcContextParams = (Map) UAVServer.instance().runSupporter( - "com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", - InvokeChainConstants.CHAIN_APP_CLIENT, InvokeChainConstants.CapturePhase.PRECAP, params, - RabbitmqProducerAdapter.class, - new Object[] { (BasicProperties) args[args.length - 2], args[args.length - 1] }); - if (ivcContextParams != null - && ivcContextParams.containsKey(InvokeChainConstants.PARAM_MQHEAD_INFO)) { - args[args.length - 2] = ivcContextParams.get(InvokeChainConstants.PARAM_MQHEAD_INFO); - } - } - } - } - - @Override - public Object postProcess(Object res, Channel t, Object proxy, Method method, Object[] args) { - - if (needDoCap(method, args)) { - doCap(1, t, method, null); - } - - return null; - } - - @Override - public void catchInvokeException(Channel t, Object proxy, Method method, Object[] args, Throwable e) { - - if (needDoCap(method, args)) { - doCap(-1, t, method, e); - } - - } - - private boolean needDoCap(Method method, Object[] args) { - - if (method.getExceptionTypes().length == 0 - || !method.getExceptionTypes()[0].getName().equals(IOException.class.getName())) { - return false; - } - String methodName = method.getName(); - if (queueNameIndex.containsKey(methodName) && args.length != 0) { - - if (isTempQueue((String) args[queueNameIndex.get(methodName)])) { - return false; - } - } - return true; - } - - private void doCap(int rc, Channel t, Method method, Throwable e) { - - if (null == targetServer) { - Map conn = t.getConnection().getServerProperties(); - String cluster_name = (null == conn.get("cluster_name")) ? "unknown" - : conn.get("cluster_name").toString(); - String version = (null == conn.get("version")) ? "unknown" : conn.get("version").toString(); - targetServer = cluster_name + "@" + version; - } - - Map params = new HashMap(); - - params.put(CaptureConstants.INFO_CLIENT_TARGETSERVER, targetServer); - params.put(CaptureConstants.INFO_CLIENT_RESPONSECODE, rc); - - if (logger.isDebugable()) { - logger.debug("Invoke END: rc=" + rc + "," + targetServer, null); - } - - UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, - Monitor.CapturePhase.DOCAP, params); - - // 调用链只关心真正的消息通讯 - if (method.getName().equals("basicPublish")) { - - if (rc == -1) { - ivcContextParams.put(CaptureConstants.INFO_CLIENT_RESPONSESTATE, e.toString()); - } - if (ivcContextParams != null) { - ivcContextParams.putAll(params); - } - - UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", - InvokeChainConstants.CHAIN_APP_CLIENT, InvokeChainConstants.CapturePhase.DOCAP, - ivcContextParams, RabbitmqProducerAdapter.class, null); - } - - } - - public boolean isTempQueue(String queueName) { - - String regEx = "^([0-9]|[a-f]){8}(-([0-9]|[a-f]){4}){3}-([0-9]|[a-f]){12}$"; - Matcher matcher = Pattern.compile(regEx).matcher(queueName); - return matcher.matches(); - - } - } - - public class ConsumerProxyProcessor extends JDKProxyInvokeProcessor { - - private Channel channel; - private String url; - private String targetServer; - - public ConsumerProxyProcessor(Channel channel, String url) { - this.channel = channel; - this.url = url; - } - - @Override - public void preProcess(Consumer t, Object proxy, Method method, Object[] args) { - - Map params = new HashMap(); - params.put(CaptureConstants.INFO_CLIENT_REQUEST_URL, url); - params.put(CaptureConstants.INFO_CLIENT_REQUEST_ACTION, "Consumer." + method.getName()); - params.put(CaptureConstants.INFO_CLIENT_APPID, applicationId); - params.put(CaptureConstants.INFO_CLIENT_TYPE, "rabbitmq.client"); - - if (logger.isDebugable()) { - logger.debug("Invoke START:" + url + ",op=Consumer." + method.getName(), null); - } - - UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, - Monitor.CapturePhase.PRECAP, params); - // 调用链只关心真正消费消息 - if (method.getName().equals("handleDelivery")) { - - AMQP.BasicProperties props = (BasicProperties) args[2]; - if (props.getHeaders() != null - && props.getHeaders().containsKey(InvokeChainConstants.PARAM_MQHEAD_SPANINFO)) { - params.put(InvokeChainConstants.PARAM_MQHEAD_SPANINFO, - props.getHeaders().get(InvokeChainConstants.PARAM_MQHEAD_SPANINFO) + ""); - params.put(CaptureConstants.INFO_APPSERVER_CONNECTOR_REQUEST_URL, url); - } - - // register adapter - UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", - "registerAdapter", RabbitmqConsumerAdapter.class); - - UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", - InvokeChainConstants.CHAIN_APP_SERVICE, InvokeChainConstants.CapturePhase.PRECAP, params, - RabbitmqConsumerAdapter.class, args); - } - - } - - @Override - public void catchInvokeException(Consumer t, Object proxy, Method method, Object[] args, Throwable e) { - - doCap(-1, channel, t, method, e); - - } - - @Override - public Object postProcess(Object res, Consumer operation, Object proxy, Method method, Object[] args) { - - doCap(1, channel, operation, method, null); - return null; - } - - private void doCap(int rc, Channel channel, Consumer consumer, Method method, Throwable e) { - - if (null == targetServer) { - Map conn = channel.getConnection().getServerProperties(); - String cluster_name = (null == conn.get("cluster_name")) ? "unknown" - : conn.get("cluster_name").toString(); - String version = (null == conn.get("version")) ? "unknown" : conn.get("version").toString(); - targetServer = cluster_name + "@" + version; - } - - Map params = new HashMap(); - - params.put(CaptureConstants.INFO_CLIENT_TARGETSERVER, targetServer); - params.put(CaptureConstants.INFO_CLIENT_RESPONSECODE, rc); - - if (logger.isDebugable()) { - logger.debug("Invoke END: rc=" + rc + "," + targetServer, null); - } - - UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, - Monitor.CapturePhase.DOCAP, params); - - if (method.getName().equals("handleDelivery")) { - params.put(CaptureConstants.INFO_APPSERVER_CONNECTOR_REQUEST_URL, url); - params.put(CaptureConstants.INFO_CLIENT_APPID, applicationId); - params.put(InvokeChainConstants.CLIENT_IT_CLASS, consumer.getClass().getName()); - // 调用链只关心一个方法 - params.put(InvokeChainConstants.CLIENT_IT_METHOD, "handleDelivery"); - params.put(CaptureConstants.INFO_CLIENT_RESPONSECODE, rc); - if (rc == -1) { - params.put(CaptureConstants.INFO_CLIENT_RESPONSESTATE, e.toString()); - } - - // invoke chain - UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", - InvokeChainConstants.CHAIN_APP_SERVICE, InvokeChainConstants.CapturePhase.DOCAP, params, - RabbitmqConsumerAdapter.class, null); - } - } - - } - -} +/*- + * << + * UAVStack + * == + * Copyright (C) 2016 - 2017 UAVStack + * == + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * >> + */ + +package com.creditease.uav.hook.rabbitmq.interceptors; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.creditease.monitor.UAVServer; +import com.creditease.monitor.captureframework.spi.CaptureConstants; +import com.creditease.monitor.captureframework.spi.Monitor; +import com.creditease.monitor.proxy.spi.JDKProxyInvokeHandler; +import com.creditease.monitor.proxy.spi.JDKProxyInvokeProcessor; +import com.creditease.uav.apm.invokechain.spi.InvokeChainConstants; +import com.creditease.uav.common.BaseComponent; +import com.creditease.uav.hook.rabbitmq.adapter.RabbitmqConsumerAdapter; +import com.creditease.uav.hook.rabbitmq.adapter.RabbitmqProducerAdapter; +import com.creditease.uav.util.JDKProxyInvokeUtil; +import com.rabbitmq.client.AMQP; +import com.rabbitmq.client.AMQP.BasicProperties; +import com.rabbitmq.client.Channel; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.Consumer; + +public class RabbitmqIT extends BaseComponent { + + private String applicationId; + static final Map queueNameIndex = new HashMap(); + static { + queueNameIndex.put("basicPublish", 1); + queueNameIndex.put("queueDeclare", 0); + queueNameIndex.put("queueDeclareNoWait", 0); + queueNameIndex.put("queueDeclarePassive", 0); + queueNameIndex.put("queueDelete", 0); + queueNameIndex.put("queueDeleteNoWait", 0); + queueNameIndex.put("queueBind", 0); + queueNameIndex.put("queueBindNoWait", 0); + queueNameIndex.put("queueUnbind", 0); + queueNameIndex.put("queuePurge", 0); + queueNameIndex.put("basicGet", 0); + queueNameIndex.put("basicConsume", 0); + } + + public RabbitmqIT(String appid) { + this.applicationId = appid; + } + + public Connection doInstall(Connection arg) { + + arg = JDKProxyInvokeUtil.newProxyInstance(Connection.class.getClassLoader(), + new Class[] { Connection.class }, + new JDKProxyInvokeHandler(arg, new ConnectionProxyProcessor())); + + return arg; + } + + /** + * + * ConnectionProxyProcessor description: ConnectionProxyProcessor + * + */ + public class ConnectionProxyProcessor extends JDKProxyInvokeProcessor { + + @Override + public void preProcess(Connection t, Object proxy, Method method, Object[] args) { + + } + + @Override + public Object postProcess(Object res, Connection t, Object proxy, Method method, Object[] args) { + + if (method.getName().equals("createChannel")) { + return JDKProxyInvokeUtil.newProxyInstance(Channel.class.getClassLoader(), + new Class[] { Channel.class }, + new JDKProxyInvokeHandler((Channel) res, new ChannelProxyProcessor())); + } + return null; + } + + } + + /** + * + * ChannelProxyProcessor description: ChannelProxyProcessor + * + */ + public class ChannelProxyProcessor extends JDKProxyInvokeProcessor { + + String address; + String targetServer; + private Map ivcContextParams = new HashMap(); + + @SuppressWarnings("unchecked") + @Override + public void preProcess(Channel t, Object proxy, Method method, Object[] args) { + + if (method.getExceptionTypes().length > 0 + && method.getExceptionTypes()[0].getName().equals(IOException.class.getName())) { + String methodName = method.getName(); + String queueName = null; + if (queueNameIndex.containsKey(methodName) && args.length != 0) { + + queueName = (String) args[queueNameIndex.get(methodName)]; + if (isTempQueue(queueName)) { + return; + } + + } + + if (null == address) { + address = t.getConnection().getAddress().getHostAddress() + ":" + t.getConnection().getPort(); + address = "mq:rabbit://" + address; + } + String url = address + ((null == queueName) ? "" : "/" + queueName); + + if ("basicConsume".equals(method.getName())) { + // delegate the consumer + args[args.length - 1] = JDKProxyInvokeUtil.newProxyInstance(Consumer.class.getClassLoader(), + new Class[] { Consumer.class }, new JDKProxyInvokeHandler( + (Consumer) args[args.length - 1], new ConsumerProxyProcessor(t, url))); + + } + + Map params = new HashMap(); + params.put(CaptureConstants.INFO_CLIENT_REQUEST_URL, url); + params.put(CaptureConstants.INFO_CLIENT_REQUEST_ACTION, method.getName()); + params.put(CaptureConstants.INFO_CLIENT_APPID, applicationId); + params.put(CaptureConstants.INFO_CLIENT_TYPE, "rabbitmq.client"); + + if (logger.isDebugable()) { + logger.debug("Invoke START:" + url + ",op=" + method.getName(), null); + } + + UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, + Monitor.CapturePhase.PRECAP, params); + + // 调用链只关心真正的消息通讯 + if (method.getName().equals("basicPublish")) { + + // register adapter + UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", + "registerAdapter", RabbitmqProducerAdapter.class); + + ivcContextParams = (Map) UAVServer.instance().runSupporter( + "com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", + InvokeChainConstants.CHAIN_APP_CLIENT, InvokeChainConstants.CapturePhase.PRECAP, params, + RabbitmqProducerAdapter.class, + new Object[] { (BasicProperties) args[args.length - 2], args[args.length - 1] }); + if (ivcContextParams != null + && ivcContextParams.containsKey(InvokeChainConstants.PARAM_MQHEAD_INFO)) { + args[args.length - 2] = ivcContextParams.get(InvokeChainConstants.PARAM_MQHEAD_INFO); + } + } + } + } + + @Override + public Object postProcess(Object res, Channel t, Object proxy, Method method, Object[] args) { + + if (needDoCap(method, args)) { + doCap(1, t, method, null); + } + + return null; + } + + @Override + public void catchInvokeException(Channel t, Object proxy, Method method, Object[] args, Throwable e) { + + if (needDoCap(method, args)) { + doCap(-1, t, method, e); + } + + } + + private boolean needDoCap(Method method, Object[] args) { + + if (method.getExceptionTypes().length == 0 + || !method.getExceptionTypes()[0].getName().equals(IOException.class.getName())) { + return false; + } + String methodName = method.getName(); + if (queueNameIndex.containsKey(methodName) && args.length != 0) { + + if (isTempQueue((String) args[queueNameIndex.get(methodName)])) { + return false; + } + } + return true; + } + + private void doCap(int rc, Channel t, Method method, Throwable e) { + + if (null == targetServer) { + Map conn = t.getConnection().getServerProperties(); + String cluster_name = (null == conn.get("cluster_name")) ? "unknown" + : conn.get("cluster_name").toString(); + String version = (null == conn.get("version")) ? "unknown" : conn.get("version").toString(); + targetServer = cluster_name + "@" + version; + } + + Map params = new HashMap(); + + params.put(CaptureConstants.INFO_CLIENT_TARGETSERVER, targetServer); + params.put(CaptureConstants.INFO_CLIENT_RESPONSECODE, rc); + + if (logger.isDebugable()) { + logger.debug("Invoke END: rc=" + rc + "," + targetServer, null); + } + + UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, + Monitor.CapturePhase.DOCAP, params); + + // 调用链只关心真正的消息通讯 + if (method.getName().equals("basicPublish")) { + + if (rc == -1) { + ivcContextParams.put(CaptureConstants.INFO_CLIENT_RESPONSESTATE, e.toString()); + } + if (ivcContextParams != null) { + ivcContextParams.putAll(params); + } + + UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", + InvokeChainConstants.CHAIN_APP_CLIENT, InvokeChainConstants.CapturePhase.DOCAP, + ivcContextParams, RabbitmqProducerAdapter.class, null); + } + + } + + public boolean isTempQueue(String queueName) { + + String regEx = "^([0-9]|[a-f]){8}(-([0-9]|[a-f]){4}){3}-([0-9]|[a-f]){12}$"; + Matcher matcher = Pattern.compile(regEx).matcher(queueName); + return matcher.matches(); + + } + } + + public class ConsumerProxyProcessor extends JDKProxyInvokeProcessor { + + private Channel channel; + private String url; + private String targetServer; + + public ConsumerProxyProcessor(Channel channel, String url) { + this.channel = channel; + this.url = url; + } + + @Override + public void preProcess(Consumer t, Object proxy, Method method, Object[] args) { + + Map params = new HashMap(); + params.put(CaptureConstants.INFO_CLIENT_REQUEST_URL, url); + params.put(CaptureConstants.INFO_CLIENT_REQUEST_ACTION, "Consumer." + method.getName()); + params.put(CaptureConstants.INFO_CLIENT_APPID, applicationId); + params.put(CaptureConstants.INFO_CLIENT_TYPE, "rabbitmq.client"); + + if (logger.isDebugable()) { + logger.debug("Invoke START:" + url + ",op=Consumer." + method.getName(), null); + } + + UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, + Monitor.CapturePhase.PRECAP, params); + // 调用链只关心真正消费消息 + if (method.getName().equals("handleDelivery")) { + + AMQP.BasicProperties props = (BasicProperties) args[2]; + if (props.getHeaders() != null + && props.getHeaders().containsKey(InvokeChainConstants.PARAM_MQHEAD_SPANINFO)) { + params.put(InvokeChainConstants.PARAM_MQHEAD_SPANINFO, + props.getHeaders().get(InvokeChainConstants.PARAM_MQHEAD_SPANINFO) + ""); + params.put(CaptureConstants.INFO_APPSERVER_CONNECTOR_REQUEST_URL, url); + } + + // register adapter + UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", + "registerAdapter", RabbitmqConsumerAdapter.class); + + UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", + InvokeChainConstants.CHAIN_APP_SERVICE, InvokeChainConstants.CapturePhase.PRECAP, params, + RabbitmqConsumerAdapter.class, args); + } + + } + + @Override + public void catchInvokeException(Consumer t, Object proxy, Method method, Object[] args, Throwable e) { + + doCap(-1, channel, t, method, e); + + } + + @Override + public Object postProcess(Object res, Consumer operation, Object proxy, Method method, Object[] args) { + + doCap(1, channel, operation, method, null); + return null; + } + + private void doCap(int rc, Channel channel, Consumer consumer, Method method, Throwable e) { + + if (null == targetServer) { + Map conn = channel.getConnection().getServerProperties(); + String cluster_name = (null == conn.get("cluster_name")) ? "unknown" + : conn.get("cluster_name").toString(); + String version = (null == conn.get("version")) ? "unknown" : conn.get("version").toString(); + targetServer = cluster_name + "@" + version; + } + + Map params = new HashMap(); + + params.put(CaptureConstants.INFO_CLIENT_TARGETSERVER, targetServer); + params.put(CaptureConstants.INFO_CLIENT_RESPONSECODE, rc); + + if (logger.isDebugable()) { + logger.debug("Invoke END: rc=" + rc + "," + targetServer, null); + } + + UAVServer.instance().runMonitorCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, + Monitor.CapturePhase.DOCAP, params); + + if (method.getName().equals("handleDelivery")) { + params.put(CaptureConstants.INFO_APPSERVER_CONNECTOR_REQUEST_URL, url); + params.put(CaptureConstants.INFO_CLIENT_APPID, applicationId); + params.put(InvokeChainConstants.CLIENT_IT_CLASS, consumer.getClass().getName()); + // 调用链只关心一个方法 + params.put(InvokeChainConstants.CLIENT_IT_METHOD, "handleDelivery"); + params.put(CaptureConstants.INFO_CLIENT_RESPONSECODE, rc); + if (rc == -1) { + params.put(CaptureConstants.INFO_CLIENT_RESPONSESTATE, e.toString()); + } + + // invoke chain + UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", + InvokeChainConstants.CHAIN_APP_SERVICE, InvokeChainConstants.CapturePhase.DOCAP, params, + RabbitmqConsumerAdapter.class, null); + } + } + + } + +} From bc2aa14a8985566adf9d9b30656a2b1e9177ddad Mon Sep 17 00:00:00 2001 From: xiaolong Date: Fri, 20 Apr 2018 15:27:03 +0800 Subject: [PATCH 6/6] =?UTF-8?q?https://github.com/uavorg/uavstack/issues/2?= =?UTF-8?q?53=201.=E4=BF=AE=E6=94=B9ma=E7=9A=84=E9=BB=98=E8=AE=A4=E5=88=86?= =?UTF-8?q?=E7=BB=84=E4=B8=BAUAV=E4=B8=8Ehm=E4=BF=9D=E6=8C=81=E4=B8=80?= =?UTF-8?q?=E7=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- com.creditease.uav.agent.buildComponent/bin/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.creditease.uav.agent.buildComponent/bin/run.sh b/com.creditease.uav.agent.buildComponent/bin/run.sh index 2c5d3281..4f820367 100644 --- a/com.creditease.uav.agent.buildComponent/bin/run.sh +++ b/com.creditease.uav.agent.buildComponent/bin/run.sh @@ -47,7 +47,7 @@ export CLASSPATH=bin/com.creditease.uav.base-1.0-boot.jar echo $CLASSPATH javaAgent="-javaagent:../uavmof/com.creditease.uav.agent/com.creditease.uav.monitorframework.agent-1.0-agent.jar" javaOpts="-server -Xms64m -Xmx256m -Xss256k -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing -XX:CMSIncrementalDutyCycleMin=0 -XX:CMSIncrementalDutyCycle=10 -XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection -XX:-CMSParallelRemarkEnabled -XX:CMSFullGCsBeforeCompaction=0 -XX:CMSInitiatingOccupancyFraction=70 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=." -$executeJava $javaAgent $javaOpts -XX:OnOutOfMemoryError='kill -9 %p' -DNetCardIndex=$netcardIndex -DNetCardName=$netcardName -DJAppID=$2 -DJAppGroup=UNKNOWN -classpath $CLASSPATH com.creditease.mscp.boot.MSCPBoot -p $1 & +$executeJava $javaAgent $javaOpts -XX:OnOutOfMemoryError='kill -9 %p' -DNetCardIndex=$netcardIndex -DNetCardName=$netcardName -DJAppID=$2 -DJAppGroup=UAV -classpath $CLASSPATH com.creditease.mscp.boot.MSCPBoot -p $1 & # add crontab process watcher if [ "$proc_watcher" == "yes" ]; then