diff --git a/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/dao/IInstanceDAO.java b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/dao/IInstanceDAO.java new file mode 100644 index 000000000..d8bbee131 --- /dev/null +++ b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/dao/IInstanceDAO.java @@ -0,0 +1,10 @@ +package org.skywalking.apm.collector.ui.dao; + +/** + * @author pengys5 + */ +public interface IInstanceDAO { + Long lastHeartBeatTime(); + + Long instanceLastHeartBeatTime(long applicationInstanceId); +} diff --git a/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/dao/InstanceEsDAO.java b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/dao/InstanceEsDAO.java new file mode 100644 index 000000000..85e542eba --- /dev/null +++ b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/dao/InstanceEsDAO.java @@ -0,0 +1,63 @@ +package org.skywalking.apm.collector.ui.dao; + +import org.elasticsearch.action.search.SearchRequestBuilder; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchType; +import org.elasticsearch.index.query.AbstractQueryBuilder; +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.index.query.MatchQueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.index.query.RangeQueryBuilder; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.sort.SortBuilders; +import org.elasticsearch.search.sort.SortMode; +import org.skywalking.apm.collector.storage.elasticsearch.dao.EsDAO; +import org.skywalking.apm.collector.storage.table.node.NodeComponentTable; +import org.skywalking.apm.collector.storage.table.register.InstanceTable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author pengys5 + */ +public class InstanceEsDAO extends EsDAO implements IInstanceDAO { + + private final Logger logger = LoggerFactory.getLogger(InstanceEsDAO.class); + + @Override public Long lastHeartBeatTime() { + long fiveMinuteBefore = System.currentTimeMillis() - 5 * 60 * 1000; + RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(InstanceTable.COLUMN_HEARTBEAT_TIME).gt(fiveMinuteBefore); + return heartBeatTime(rangeQueryBuilder); + } + + @Override public Long instanceLastHeartBeatTime(long applicationInstanceId) { + long fiveMinuteBefore = System.currentTimeMillis() - 5 * 60 * 1000; + BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); + RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(InstanceTable.COLUMN_HEARTBEAT_TIME).gt(fiveMinuteBefore); + MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(InstanceTable.COLUMN_INSTANCE_ID, applicationInstanceId); + boolQueryBuilder.must(rangeQueryBuilder); + boolQueryBuilder.must(matchQueryBuilder); + return heartBeatTime(boolQueryBuilder); + } + + private Long heartBeatTime(AbstractQueryBuilder queryBuilder) { + SearchRequestBuilder searchRequestBuilder = getClient().prepareSearch(InstanceTable.TABLE); + searchRequestBuilder.setTypes(NodeComponentTable.TABLE_TYPE); + searchRequestBuilder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH); + searchRequestBuilder.setQuery(queryBuilder); + searchRequestBuilder.setSize(1); + searchRequestBuilder.setFetchSource(InstanceTable.COLUMN_HEARTBEAT_TIME, null); + searchRequestBuilder.addSort(SortBuilders.fieldSort(InstanceTable.COLUMN_HEARTBEAT_TIME).sortMode(SortMode.MAX)); + + SearchResponse searchResponse = searchRequestBuilder.execute().actionGet(); + SearchHit[] searchHits = searchResponse.getHits().getHits(); + + Long heartBeatTime = 0L; + for (SearchHit searchHit : searchHits) { + heartBeatTime = (Long)searchHit.getSource().get(InstanceTable.COLUMN_HEARTBEAT_TIME); + logger.debug("heartBeatTime: {}", heartBeatTime); + heartBeatTime = heartBeatTime - 5; + } + return heartBeatTime; + } +} diff --git a/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/dao/InstanceH2DAO.java b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/dao/InstanceH2DAO.java new file mode 100644 index 000000000..b5568f662 --- /dev/null +++ b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/dao/InstanceH2DAO.java @@ -0,0 +1,16 @@ +package org.skywalking.apm.collector.ui.dao; + +import org.skywalking.apm.collector.storage.h2.dao.H2DAO; + +/** + * @author pengys5 + */ +public class InstanceH2DAO extends H2DAO implements IInstanceDAO { + @Override public Long lastHeartBeatTime() { + return null; + } + + @Override public Long instanceLastHeartBeatTime(long applicationInstanceId) { + return null; + } +} diff --git a/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/jetty/handler/time/AllInstanceLastTimeGetHandler.java b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/jetty/handler/time/AllInstanceLastTimeGetHandler.java new file mode 100644 index 000000000..df09f1327 --- /dev/null +++ b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/jetty/handler/time/AllInstanceLastTimeGetHandler.java @@ -0,0 +1,36 @@ +package org.skywalking.apm.collector.ui.jetty.handler.time; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import javax.servlet.http.HttpServletRequest; +import org.skywalking.apm.collector.server.jetty.ArgumentsParseException; +import org.skywalking.apm.collector.server.jetty.JettyHandler; +import org.skywalking.apm.collector.ui.service.TimeSynchronousService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author pengys5 + */ +public class AllInstanceLastTimeGetHandler extends JettyHandler { + + private final Logger logger = LoggerFactory.getLogger(AllInstanceLastTimeGetHandler.class); + + @Override public String pathSpec() { + return "/time/allInstance"; + } + + private TimeSynchronousService service = new TimeSynchronousService(); + + @Override protected JsonElement doGet(HttpServletRequest req) throws ArgumentsParseException { + Long time = service.allInstanceLastTime(); + logger.debug("all instance last time: {}", time); + JsonObject timeJson = new JsonObject(); + timeJson.addProperty("time", time); + return timeJson; + } + + @Override protected JsonElement doPost(HttpServletRequest req) throws ArgumentsParseException { + throw new UnsupportedOperationException(); + } +} diff --git a/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/jetty/handler/time/InstanceLastTimeGetHandler.java b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/jetty/handler/time/InstanceLastTimeGetHandler.java new file mode 100644 index 000000000..8e6dcc3db --- /dev/null +++ b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/jetty/handler/time/InstanceLastTimeGetHandler.java @@ -0,0 +1,46 @@ +package org.skywalking.apm.collector.ui.jetty.handler.time; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import javax.servlet.http.HttpServletRequest; +import org.skywalking.apm.collector.server.jetty.ArgumentsParseException; +import org.skywalking.apm.collector.server.jetty.JettyHandler; +import org.skywalking.apm.collector.ui.service.TimeSynchronousService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author pengys5 + */ +public class InstanceLastTimeGetHandler extends JettyHandler { + + private final Logger logger = LoggerFactory.getLogger(InstanceLastTimeGetHandler.class); + + @Override public String pathSpec() { + return "/time/instanceId"; + } + + private TimeSynchronousService service = new TimeSynchronousService(); + + @Override protected JsonElement doGet(HttpServletRequest req) throws ArgumentsParseException { + String applicationInstanceIdStr = req.getParameter("applicationInstanceId"); + logger.debug("applicationInstanceId: {}", applicationInstanceIdStr); + + int applicationInstanceId; + try { + applicationInstanceId = Integer.parseInt(applicationInstanceIdStr); + } catch (NumberFormatException e) { + throw new ArgumentsParseException("application instance id must be integer"); + } + + Long time = service.instanceLastTime(applicationInstanceId); + logger.debug("application instance id: {}, instance last time: {}", applicationInstanceId, time); + JsonObject timeJson = new JsonObject(); + timeJson.addProperty("time", time); + return timeJson; + } + + @Override protected JsonElement doPost(HttpServletRequest req) throws ArgumentsParseException { + throw new UnsupportedOperationException(); + } +} diff --git a/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/service/InstanceHealthService.java b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/service/InstanceHealthService.java new file mode 100644 index 000000000..0367c4366 --- /dev/null +++ b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/service/InstanceHealthService.java @@ -0,0 +1,8 @@ +package org.skywalking.apm.collector.ui.service; + +/** + * @author pengys5 + */ +public class InstanceHealthService { + +} diff --git a/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/service/TimeSynchronousService.java b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/service/TimeSynchronousService.java new file mode 100644 index 000000000..756970eab --- /dev/null +++ b/apm-collector/apm-collector-ui/src/main/java/org/skywalking/apm/collector/ui/service/TimeSynchronousService.java @@ -0,0 +1,24 @@ +package org.skywalking.apm.collector.ui.service; + +import org.skywalking.apm.collector.storage.dao.DAOContainer; +import org.skywalking.apm.collector.ui.dao.IInstanceDAO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author pengys5 + */ +public class TimeSynchronousService { + + private final Logger logger = LoggerFactory.getLogger(SegmentTopService.class); + + public Long allInstanceLastTime() { + IInstanceDAO instanceDAO = (IInstanceDAO)DAOContainer.INSTANCE.get(IInstanceDAO.class.getName()); + return instanceDAO.lastHeartBeatTime(); + } + + public Long instanceLastTime(int applicationInstanceId) { + IInstanceDAO instanceDAO = (IInstanceDAO)DAOContainer.INSTANCE.get(IInstanceDAO.class.getName()); + return instanceDAO.instanceLastHeartBeatTime(applicationInstanceId); + } +} diff --git a/apm-collector/apm-collector-ui/src/main/resources/META-INF/defines/es_dao.define b/apm-collector/apm-collector-ui/src/main/resources/META-INF/defines/es_dao.define index 4e71da25d..1ea705134 100644 --- a/apm-collector/apm-collector-ui/src/main/resources/META-INF/defines/es_dao.define +++ b/apm-collector/apm-collector-ui/src/main/resources/META-INF/defines/es_dao.define @@ -6,4 +6,5 @@ org.skywalking.apm.collector.ui.dao.SegmentCostEsDAO org.skywalking.apm.collector.ui.dao.GlobalTraceEsDAO org.skywalking.apm.collector.ui.dao.SegmentEsDAO org.skywalking.apm.collector.ui.dao.ApplicationEsDAO -org.skywalking.apm.collector.ui.dao.ServiceNameEsDAO \ No newline at end of file +org.skywalking.apm.collector.ui.dao.ServiceNameEsDAO +org.skywalking.apm.collector.ui.dao.InstanceEsDAO \ No newline at end of file diff --git a/apm-collector/apm-collector-ui/src/main/resources/META-INF/defines/h2_dao.define b/apm-collector/apm-collector-ui/src/main/resources/META-INF/defines/h2_dao.define index a90a49369..a501a251e 100644 --- a/apm-collector/apm-collector-ui/src/main/resources/META-INF/defines/h2_dao.define +++ b/apm-collector/apm-collector-ui/src/main/resources/META-INF/defines/h2_dao.define @@ -6,4 +6,5 @@ org.skywalking.apm.collector.ui.dao.SegmentCostH2DAO org.skywalking.apm.collector.ui.dao.GlobalTraceH2DAO org.skywalking.apm.collector.ui.dao.SegmentH2DAO org.skywalking.apm.collector.ui.dao.ApplicationH2DAO -org.skywalking.apm.collector.ui.dao.ServiceNameH2DAO \ No newline at end of file +org.skywalking.apm.collector.ui.dao.ServiceNameH2DAO +org.skywalking.apm.collector.ui.dao.InstanceH2DAO \ No newline at end of file