完善统计
This commit is contained in:
parent
8799ea2078
commit
5aacf09cb2
4
pom.xml
4
pom.xml
@ -35,6 +35,10 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
|
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
@ -14,6 +14,7 @@ public interface ISystemConst {
|
|||||||
|
|
||||||
String UUID = "uuid";
|
String UUID = "uuid";
|
||||||
String COUNT = "count";
|
String COUNT = "count";
|
||||||
|
|
||||||
String SESSION_USER = "SESSION_USER";
|
String SESSION_USER = "SESSION_USER";
|
||||||
String USER_ADMIN_USERNAME = "admin";
|
String USER_ADMIN_USERNAME = "admin";
|
||||||
String USER_ADMIN_PASSWORD = "aaa111!!!";
|
String USER_ADMIN_PASSWORD = "aaa111!!!";
|
||||||
@ -22,4 +23,7 @@ public interface ISystemConst {
|
|||||||
String ROUTE_PREFIX = "/gw";
|
String ROUTE_PREFIX = "/gw";
|
||||||
String ROOT_PATH_PREFIX = "/*";
|
String ROOT_PATH_PREFIX = "/*";
|
||||||
|
|
||||||
|
String DATE_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
String DATE_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,24 @@
|
|||||||
package ink.wgink.gateway.handler.count;
|
package ink.wgink.gateway.handler.count;
|
||||||
|
|
||||||
|
import ink.wgink.gateway.consts.ISystemConst;
|
||||||
import ink.wgink.gateway.dao.log.IRequestLogDao;
|
import ink.wgink.gateway.dao.log.IRequestLogDao;
|
||||||
import ink.wgink.gateway.dao.route.IRouteDao;
|
import ink.wgink.gateway.dao.route.IRouteDao;
|
||||||
import ink.wgink.gateway.dao.routetype.IRouteTypeDao;
|
import ink.wgink.gateway.dao.routetype.IRouteTypeDao;
|
||||||
import ink.wgink.gateway.handler.BaseHandler;
|
import ink.wgink.gateway.handler.BaseHandler;
|
||||||
import ink.wgink.gateway.pojo.count.HomeCount;
|
import ink.wgink.gateway.pojo.count.HomeCount;
|
||||||
import ink.wgink.gateway.pojo.count.RequestLogCount;
|
import ink.wgink.gateway.pojo.count.RequestLogLineChat;
|
||||||
import ink.wgink.gateway.pojo.log.RequestLog;
|
import ink.wgink.gateway.pojo.log.RequestLog;
|
||||||
import ink.wgink.gateway.pojo.result.SuccessResult;
|
|
||||||
import ink.wgink.gateway.pojo.result.SuccessResultData;
|
import ink.wgink.gateway.pojo.result.SuccessResultData;
|
||||||
import ink.wgink.gateway.util.DateUtil;
|
import ink.wgink.gateway.util.DateUtil;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.joda.time.format.DateTimeFormat;
|
||||||
import org.springframework.data.domain.Example;
|
import org.springframework.data.domain.Example;
|
||||||
import org.springframework.data.domain.ExampleMatcher;
|
import org.springframework.data.domain.ExampleMatcher;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
|
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||||
|
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
|
||||||
|
import org.springframework.data.mongodb.core.query.Criteria;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||||
@ -37,11 +44,13 @@ public class CountHandler extends BaseHandler {
|
|||||||
private IRouteTypeDao routeTypeDao;
|
private IRouteTypeDao routeTypeDao;
|
||||||
private IRouteDao routeDao;
|
private IRouteDao routeDao;
|
||||||
private IRequestLogDao requestLogDao;
|
private IRequestLogDao requestLogDao;
|
||||||
|
private MongoTemplate mongoTemplate;
|
||||||
|
|
||||||
public CountHandler(IRouteTypeDao routeTypeDao, IRouteDao routeDao, IRequestLogDao requestLogDao) {
|
public CountHandler(IRouteTypeDao routeTypeDao, IRouteDao routeDao, IRequestLogDao requestLogDao, MongoTemplate mongoTemplate) {
|
||||||
this.routeTypeDao = routeTypeDao;
|
this.routeTypeDao = routeTypeDao;
|
||||||
this.routeDao = routeDao;
|
this.routeDao = routeDao;
|
||||||
this.requestLogDao = requestLogDao;
|
this.requestLogDao = requestLogDao;
|
||||||
|
this.mongoTemplate = mongoTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,16 +92,30 @@ public class CountHandler extends BaseHandler {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 最新请求数量列表
|
* 最新请求数量列表
|
||||||
|
* 按分钟统计访问次数
|
||||||
*
|
*
|
||||||
* @param serverRequest
|
* @param serverRequest
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
// 每分钟跟新依次统计数据
|
|
||||||
public Mono<ServerResponse> listLastCount(ServerRequest serverRequest) {
|
public Mono<ServerResponse> listLastCount(ServerRequest serverRequest) {
|
||||||
return ServerResponse.ok().contentType(MediaType.TEXT_EVENT_STREAM).body(requestLogDao.count().flatMap(count -> {
|
return ServerResponse.ok().contentType(MediaType.TEXT_EVENT_STREAM).body(
|
||||||
RequestLogCount requestLogCount = new RequestLogCount();
|
Flux.interval(Duration.ofMinutes(0), Duration.ofSeconds(15)).flatMap(second ->
|
||||||
return Mono.just(requestLogCount);
|
requestLogDao.count().flatMap(count -> {
|
||||||
}), RequestLogCount.class);
|
DateTime nowDateTime = DateTime.now();
|
||||||
|
DateTime startDateTime = nowDateTime.minusMinutes(60);
|
||||||
|
String now = nowDateTime.toString(DateTimeFormat.forPattern(ISystemConst.DATE_YYYY_MM_DD_HH_MM));
|
||||||
|
String start = startDateTime.toString(DateTimeFormat.forPattern(ISystemConst.DATE_YYYY_MM_DD_HH_MM));
|
||||||
|
// 这个条件类似
|
||||||
|
// SELECT gmtCreate, count(gmtCreate) FROM log_request WHERE LEFT('gmtCreate', 16) >= '' and LEFT('gmtCreate', 16) <= '' GROUP BY gmtCreate
|
||||||
|
Aggregation aggregation = Aggregation.newAggregation(
|
||||||
|
Aggregation.project().andExpression("{substr(gmtCreate,0,16)}").as("gmtMinute"),
|
||||||
|
Aggregation.match(Criteria.where("gmtMinute").gte(start).lte(now)),
|
||||||
|
Aggregation.group("gmtMinute").count().as("count"),
|
||||||
|
Aggregation.sort(Sort.by("_id").ascending())
|
||||||
|
);
|
||||||
|
AggregationResults<RequestLogLineChat> aggregate = mongoTemplate.aggregate(aggregation, IRequestLogDao.COLLECTION_NAME, RequestLogLineChat.class);
|
||||||
|
return Mono.just(new SuccessResultData(aggregate.getMappedResults()));
|
||||||
|
})), SuccessResultData.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package ink.wgink.gateway.pojo.count;
|
package ink.wgink.gateway.pojo.count;
|
||||||
|
|
||||||
import ink.wgink.gateway.dao.log.IRequestLogDao;
|
import ink.wgink.gateway.dao.log.IRequestLogDao;
|
||||||
import ink.wgink.gateway.pojo.BasePOJO;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
import org.springframework.data.mongodb.core.mapping.Document;
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@ -21,10 +21,11 @@ import java.io.Serializable;
|
|||||||
@Data
|
@Data
|
||||||
@ToString
|
@ToString
|
||||||
@Document(collection = IRequestLogDao.COLLECTION_NAME)
|
@Document(collection = IRequestLogDao.COLLECTION_NAME)
|
||||||
public class RequestLogCount implements Serializable {
|
public class RequestLogLineChat implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 289254213770448241L;
|
private static final long serialVersionUID = 289254213770448241L;
|
||||||
private String gmtCreate;
|
@Id
|
||||||
|
private String gmtMinute;
|
||||||
private Long count;
|
private Long count;
|
||||||
|
|
||||||
}
|
}
|
@ -10,7 +10,7 @@
|
|||||||
<link rel="stylesheet" href="assets/layui/css/admin.css"/>
|
<link rel="stylesheet" href="assets/layui/css/admin.css"/>
|
||||||
<link rel="stylesheet" href="assets/layui/css/admin.css"/>
|
<link rel="stylesheet" href="assets/layui/css/admin.css"/>
|
||||||
<style>
|
<style>
|
||||||
#app {padding: 15px 0;}
|
#app {padding-top: 15px; overflow-x: hidden;}
|
||||||
.layuiadmin-badge {float: right; height: 42px; line-height: 42px;}
|
.layuiadmin-badge {float: right; height: 42px; line-height: 42px;}
|
||||||
.layuiadmin-card-list {padding: 15px;line-height: 38px !important; text-align: right;}
|
.layuiadmin-card-list {padding: 15px;line-height: 38px !important; text-align: right;}
|
||||||
.layuiadmin-card-list .layuiadmin-big-font {font-size: 38px;}
|
.layuiadmin-card-list .layuiadmin-big-font {font-size: 38px;}
|
||||||
@ -65,11 +65,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-row layui-col-space15">
|
<div class="layui-row layui-col-space15">
|
||||||
<div class="layui-col-sm12 layui-col-md6">
|
<div class="layui-col-sm12 layui-col-md12">
|
||||||
<div class="layui-col-sm12">
|
<div class="layui-col-sm12">
|
||||||
<div class="layui-card">
|
<div class="layui-card">
|
||||||
<div class="layui-card-body">
|
<div class="layui-card-body">
|
||||||
<div id="loginEChart" style="width: 100%; height: 267px;"></div>
|
<div id="lastRequestLogLineChat" style="width: 100%;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -84,13 +84,19 @@
|
|||||||
base: 'assets/layui/modules/'
|
base: 'assets/layui/modules/'
|
||||||
}).extend({}).use(['layer', 'animate-numbers'], function () {
|
}).extend({}).use(['layer', 'animate-numbers'], function () {
|
||||||
var $ = layui.$;
|
var $ = layui.$;
|
||||||
|
var $win = $(window);
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
data: {
|
data: {
|
||||||
requestCount: 0,
|
requestCount: 0,
|
||||||
requestTodayCount: 0,
|
requestTodayCount: 0,
|
||||||
routeTypeCount: 0,
|
routeTypeCount: 0,
|
||||||
routeCount: 0
|
routeCount: 0,
|
||||||
|
lastRequestLog: {
|
||||||
|
list: [],
|
||||||
|
lastRequestLogLineChat: null
|
||||||
|
},
|
||||||
|
resizeTimeout: null
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'requestCount': function(value, old) {
|
'requestCount': function(value, old) {
|
||||||
@ -105,6 +111,12 @@
|
|||||||
'routeCount': function(value, old) {
|
'routeCount': function(value, old) {
|
||||||
$('#routeCount').animateNumbers(value);
|
$('#routeCount').animateNumbers(value);
|
||||||
},
|
},
|
||||||
|
'lastRequestLogArray': function(value, old) {
|
||||||
|
|
||||||
|
},
|
||||||
|
'lastRequestLogLineChat': function() {
|
||||||
|
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
sseCountHome: function() {
|
sseCountHome: function() {
|
||||||
@ -131,18 +143,108 @@
|
|||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
},
|
},
|
||||||
|
initRequestLogLineChat: function(data) {
|
||||||
|
var self = this;
|
||||||
|
if(self.lastRequestLogLineChat) {
|
||||||
|
self.lastRequestLogLineChat.resize();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var legendData = [];
|
||||||
|
var xAxisData = [];
|
||||||
|
var seriesData = [];
|
||||||
|
for(var i = 0, item; item = data.data[i++];) {
|
||||||
|
legendData.push(item.gmtMinute);
|
||||||
|
xAxisData.push(item.gmtMinute.split(' ')[1]);
|
||||||
|
seriesData.push(item.count);
|
||||||
|
}
|
||||||
|
var option = {
|
||||||
|
title: {
|
||||||
|
text: '最近一小时内接口网关调用次数'
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: legendData
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '3%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
|
data: xAxisData
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value'
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '访问次数',
|
||||||
|
type: 'line',
|
||||||
|
stack: '总量',
|
||||||
|
data: seriesData
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
if(!self.lastRequestLogLineChat) {
|
||||||
|
self.lastRequestLogLineChat = echarts.init(document.getElementById('lastRequestLogLineChat'));
|
||||||
|
self.lastRequestLogLineChat.setOption(option);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.lastRequestLogLineChat.setOption(option);
|
||||||
|
},
|
||||||
|
sseRequestLogLineChat: function() {
|
||||||
|
var self = this;
|
||||||
|
var source = new EventSource(top.restAjax.path('api/count/list-last-count', []));
|
||||||
|
source.addEventListener('message', function(e) {
|
||||||
|
var data = JSON.parse(e.data);
|
||||||
|
self.initRequestLogLineChat(data);
|
||||||
|
});
|
||||||
|
source.addEventListener('open', function(e) {}, false);
|
||||||
|
// 响应finish事件,主动关闭EventSource
|
||||||
|
source.addEventListener('finish', function(e) {
|
||||||
|
source.close();
|
||||||
|
}, false);
|
||||||
|
// 异常
|
||||||
|
source.addEventListener('error', function(e) {
|
||||||
|
if (e.readyState == EventSource.CLOSED) {
|
||||||
|
console.log("连接关闭");
|
||||||
|
} else {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
},
|
||||||
countHome: function() {
|
countHome: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (window.EventSource) {
|
if (window.EventSource) {
|
||||||
self.sseCountHome();
|
self.sseCountHome();
|
||||||
|
self.sseRequestLogLineChat();
|
||||||
} else {
|
} else {
|
||||||
console.log('浏览器不支持sse');
|
console.log('浏览器不支持sse');
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
resize: function() {
|
||||||
|
$('#lastRequestLogLineChat').height($win.height() - 170 +'px');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted: function() {
|
mounted: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
self.resize();
|
||||||
self.countHome();
|
self.countHome();
|
||||||
|
$win.on('resize', function() {
|
||||||
|
if(self.resizeTimeout) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.resizeTimeout = setTimeout(function() {
|
||||||
|
self.resize();
|
||||||
|
self.initRequestLogLineChat();
|
||||||
|
self.resizeTimeout = null;
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user