1.修改对接过程中发现的系统管理相关功能接口问题
2.添加系统监控功能
This commit is contained in:
parent
fcec555a44
commit
67cad8b525
|
|
@ -333,17 +333,6 @@
|
|||
<groupId>edu.ucar</groupId>
|
||||
<artifactId>netcdfAll</artifactId>
|
||||
<version>${netcdfAll.version}</version>
|
||||
<!-- <exclusions>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>edu.ucar</groupId>-->
|
||||
<!-- <artifactId>jj2000</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- </exclusions>-->
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>edu.ucar</groupId>-->
|
||||
<!-- <artifactId>jj2000</artifactId>-->
|
||||
<!-- <version>${grib2.version}</version>-->
|
||||
<!-- </dependency>-->
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package org.jeecg.common.properties;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "prometheus")
|
||||
public class PrometheusServerProperties {
|
||||
|
||||
/**
|
||||
* prometheus 服务地址
|
||||
*/
|
||||
private String serverUrl;
|
||||
|
||||
/**
|
||||
* node-exporter实例地址
|
||||
*/
|
||||
private String instance;
|
||||
}
|
||||
|
|
@ -45,14 +45,19 @@ public class JeecgPermissionService {
|
|||
return false;
|
||||
}
|
||||
LoginUser loginUser = SecureUtil.currentUser();
|
||||
// if(loginUser.getUsername().equals("admin")) {
|
||||
// return true;
|
||||
// }
|
||||
if(loginUser.getUsername().startsWith("admin")) {
|
||||
return true;
|
||||
}
|
||||
Object cache = redisUtil.get(buildKey("permission", loginUser.getId()));
|
||||
List<String> permissionList;
|
||||
if (Objects.nonNull(cache)) {
|
||||
List<String> permissionList = List.of();
|
||||
boolean flag = false;
|
||||
if (Objects.nonNull(cache) && cache instanceof List) {
|
||||
if(!((List<?>) cache).isEmpty()){
|
||||
flag = true;
|
||||
permissionList = (List<String>) cache;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
if(!flag){
|
||||
permissionList = commonAPI.queryUserAuths(loginUser.getId());
|
||||
redisUtil.set(buildKey("permission", loginUser.getId()), permissionList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@
|
|||
<groupId>org.jeecgframework.boot3</groupId>
|
||||
<artifactId>hibernate-re</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package org.jeecg.modules.monitor.actuator.undertow;
|
||||
package org.jeecg.config.init;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.undertow.server.HttpHandler;
|
||||
|
|
@ -9,12 +9,6 @@ import org.springframework.stereotype.Component;
|
|||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
|
||||
/**
|
||||
* 自定义undertow监控指标工具类
|
||||
* for [QQYUN-11902]tomcat 替换undertow 这里的功能还没修改
|
||||
* @author chenrui
|
||||
* @date 2025/4/8 19:06
|
||||
*/
|
||||
@Component("jeecgCustomUndertowMetricsHandler")
|
||||
public class CustomUndertowMetricsHandler {
|
||||
|
||||
|
|
@ -3,7 +3,6 @@ package org.jeecg.config.init;
|
|||
import io.undertow.server.DefaultByteBufferPool;
|
||||
import io.undertow.server.handlers.BlockingHandler;
|
||||
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
|
||||
import org.jeecg.modules.monitor.actuator.undertow.CustomUndertowMetricsHandler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
package org.jeecg.modules.monitor.actuator;
|
||||
|
||||
import org.jeecg.modules.monitor.actuator.httptrace.CustomInMemoryHttpTraceRepository;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesProperties;
|
||||
import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 自定义健康监控配置类
|
||||
*
|
||||
* @Author: chenrui
|
||||
* @Date: 2024/5/13 17:20
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(HttpExchangesProperties.class)
|
||||
@AutoConfigureBefore(HttpExchangesAutoConfiguration.class)
|
||||
public class CustomActuatorConfig {
|
||||
|
||||
/**
|
||||
* 请求追踪
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2024/5/14 14:52
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "management.trace.http", name = "enabled", matchIfMissing = true)
|
||||
@ConditionalOnMissingBean(HttpExchangeRepository.class)
|
||||
public CustomInMemoryHttpTraceRepository traceRepository() {
|
||||
return new CustomInMemoryHttpTraceRepository();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
package org.jeecg.modules.monitor.actuator.httptrace;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Selector;
|
||||
import org.springframework.boot.actuate.web.exchanges.HttpExchange;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.springframework.boot.actuate.endpoint.annotation.Selector.Match.ALL_REMAINING;
|
||||
|
||||
/**
|
||||
* @Description: ENDPOINT: 请求追踪(新),支持通过responseCode筛选
|
||||
* @Author: chenrui
|
||||
* @Date: 2024/5/13 17:02
|
||||
*/
|
||||
@Component
|
||||
@Endpoint(id = "jeecghttptrace")
|
||||
public class CustomHttpTraceEndpoint{
|
||||
private final CustomInMemoryHttpTraceRepository repository;
|
||||
|
||||
public CustomHttpTraceEndpoint(CustomInMemoryHttpTraceRepository repository) {
|
||||
Assert.notNull(repository, "Repository must not be null");
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@ReadOperation
|
||||
public HttpTraceDescriptor traces(@Selector(match = ALL_REMAINING) String query) {
|
||||
return new HttpTraceDescriptor(this.repository.findAll(query));
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static final class HttpTraceDescriptor {
|
||||
private final List<HttpExchange> traces;
|
||||
|
||||
private HttpTraceDescriptor(List<HttpExchange> traces) {
|
||||
this.traces = traces;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
package org.jeecg.modules.monitor.actuator.httptrace;
|
||||
|
||||
import org.springframework.boot.actuate.web.exchanges.HttpExchange;
|
||||
import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @Description: 自定义内存请求追踪存储
|
||||
* @Author: chenrui
|
||||
* @Date: 2024/5/13 17:02
|
||||
*/
|
||||
public class CustomInMemoryHttpTraceRepository extends InMemoryHttpExchangeRepository {
|
||||
|
||||
@Override
|
||||
public List<HttpExchange> findAll() {
|
||||
return super.findAll();
|
||||
}
|
||||
|
||||
public List<HttpExchange> findAll(String query) {
|
||||
List<HttpExchange> allTrace = super.findAll();
|
||||
if (null != allTrace && !allTrace.isEmpty()) {
|
||||
Stream<HttpExchange> stream = allTrace.stream();
|
||||
String[] params = query.split(",");
|
||||
stream = filter(params, stream);
|
||||
stream = sort(params, stream);
|
||||
allTrace = stream.collect(Collectors.toList());
|
||||
}
|
||||
return allTrace;
|
||||
}
|
||||
|
||||
private Stream<HttpExchange> sort(String[] params, Stream<HttpExchange> stream) {
|
||||
if (params.length < 2) {
|
||||
return stream;
|
||||
}
|
||||
String sortBy = params[1];
|
||||
String order;
|
||||
if (params.length > 2) {
|
||||
order = params[2];
|
||||
} else {
|
||||
order = "desc";
|
||||
}
|
||||
return stream.sorted((o1, o2) -> {
|
||||
int i = 0;
|
||||
if("timeTaken".equalsIgnoreCase(sortBy)) {
|
||||
i = o1.getTimeTaken().compareTo(o2.getTimeTaken());
|
||||
}else if("timestamp".equalsIgnoreCase(sortBy)){
|
||||
i = o1.getTimestamp().compareTo(o2.getTimestamp());
|
||||
}
|
||||
if("desc".equalsIgnoreCase(order)){
|
||||
i *=-1;
|
||||
}
|
||||
return i;
|
||||
});
|
||||
}
|
||||
|
||||
private static Stream<HttpExchange> filter(String[] params, Stream<HttpExchange> stream) {
|
||||
if (params.length == 0) {
|
||||
return stream;
|
||||
}
|
||||
String statusQuery = params[0];
|
||||
if (null != statusQuery && !statusQuery.isEmpty()) {
|
||||
statusQuery = statusQuery.toLowerCase().trim();
|
||||
switch (statusQuery) {
|
||||
case "error":
|
||||
stream = stream.filter(httpTrace -> {
|
||||
int status = httpTrace.getResponse().getStatus();
|
||||
return status >= 404 && status < 501;
|
||||
});
|
||||
break;
|
||||
case "warn":
|
||||
stream = stream.filter(httpTrace -> {
|
||||
int status = httpTrace.getResponse().getStatus();
|
||||
return status >= 201 && status < 404;
|
||||
});
|
||||
break;
|
||||
case "success":
|
||||
stream = stream.filter(httpTrace -> {
|
||||
int status = httpTrace.getResponse().getStatus();
|
||||
return status == 200;
|
||||
});
|
||||
break;
|
||||
case "all":
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
package org.jeecg.modules.monitor.controller;
|
||||
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: 内存健康检查
|
||||
* @author: chenrui
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/actuator/memory")
|
||||
public class ActuatorMemoryController {
|
||||
|
||||
|
||||
/**
|
||||
* 内存详情
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/info")
|
||||
public Result<?> getRedisInfo() {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
Map<String,Number> result = new HashMap<>();
|
||||
result.put("memory.runtime.total", runtime.totalMemory());
|
||||
result.put("memory.runtime.used", runtime.freeMemory());
|
||||
result.put("memory.runtime.max", runtime.totalMemory() - runtime.freeMemory());
|
||||
result.put("memory.runtime.free", runtime.maxMemory() - runtime.totalMemory() + runtime.freeMemory());
|
||||
result.put("memory.runtime.usage", NumberUtil.div(runtime.totalMemory() - runtime.freeMemory(), runtime.totalMemory()));
|
||||
//update-begin---author:chenrui ---date:20240705 for:[TV360X-1695]内存信息-立即更新 功能报错 #6635------------
|
||||
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
|
||||
if (operatingSystemMXBean instanceof com.sun.management.OperatingSystemMXBean) {
|
||||
com.sun.management.OperatingSystemMXBean opBean = (com.sun.management.OperatingSystemMXBean) operatingSystemMXBean;
|
||||
// JSONObject operatingSystemJson = JSONObject.parseObject(JSONObject.toJSONString(operatingSystemMXBean));
|
||||
long totalPhysicalMemory = opBean.getTotalPhysicalMemorySize();
|
||||
long freePhysicalMemory = opBean.getFreePhysicalMemorySize();
|
||||
long usedPhysicalMemory = totalPhysicalMemory - freePhysicalMemory;
|
||||
result.put("memory.physical.total", totalPhysicalMemory);
|
||||
result.put("memory.physical.used", freePhysicalMemory);
|
||||
result.put("memory.physical.free", usedPhysicalMemory);
|
||||
result.put("memory.physical.usage", NumberUtil.div(usedPhysicalMemory, totalPhysicalMemory));
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240705 for:[TV360X-1695]内存信息-立即更新 功能报错 #6635------------
|
||||
return Result.ok(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
package org.jeecg.modules.monitor.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.modules.monitor.domain.RedisInfo;
|
||||
import org.jeecg.modules.monitor.service.RedisService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import javax.swing.filechooser.FileSystemView;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: ActuatorRedisController
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/actuator/redis")
|
||||
public class ActuatorRedisController {
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
/**
|
||||
* Redis详细信息
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@GetMapping("/info")
|
||||
public Result<?> getRedisInfo() throws Exception {
|
||||
List<RedisInfo> infoList = this.redisService.getRedisInfo();
|
||||
//log.info(infoList.toString());
|
||||
return Result.ok(infoList);
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20240514 for:[QQYUN-9247]系统监控功能优化------------
|
||||
/**
|
||||
* Redis历史性能指标查询(过去一小时)
|
||||
* @return
|
||||
* @throws Exception
|
||||
* @author chenrui
|
||||
* @date 2024/5/14 14:56
|
||||
*/
|
||||
@GetMapping(value = "/metrics/history")
|
||||
public Result<?> getMetricsHistory() throws Exception {
|
||||
Map<String,List<Map<String,Object>>> metricsHistory = this.redisService.getMetricsHistory();
|
||||
return Result.OK(metricsHistory);
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240514 for:[QQYUN-9247]系统监控功能优化------------
|
||||
|
||||
@GetMapping("/keysSize")
|
||||
public Map<String, Object> getKeysSize() throws Exception {
|
||||
return redisService.getKeysSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取redis key数量 for 报表
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@GetMapping("/keysSizeForReport")
|
||||
public Map<String, JSONArray> getKeysSizeReport() throws Exception {
|
||||
return redisService.getMapForReport("1");
|
||||
}
|
||||
/**
|
||||
* 获取redis 内存 for 报表
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@GetMapping("/memoryForReport")
|
||||
public Map<String, JSONArray> memoryForReport() throws Exception {
|
||||
return redisService.getMapForReport("2");
|
||||
}
|
||||
/**
|
||||
* 获取redis 全部信息 for 报表
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@GetMapping("/infoForReport")
|
||||
public Map<String, JSONArray> infoForReport() throws Exception {
|
||||
return redisService.getMapForReport("3");
|
||||
}
|
||||
|
||||
@GetMapping("/memoryInfo")
|
||||
public Map<String, Object> getMemoryInfo() throws Exception {
|
||||
return redisService.getMemoryInfo();
|
||||
}
|
||||
|
||||
//update-begin--Author:zhangweijian Date:20190425 for:获取磁盘信息
|
||||
/**
|
||||
* @功能:获取磁盘信息
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryDiskInfo")
|
||||
public Result<List<Map<String,Object>>> queryDiskInfo(HttpServletRequest request, HttpServletResponse response){
|
||||
Result<List<Map<String,Object>>> res = new Result<>();
|
||||
try {
|
||||
// 当前文件系统类
|
||||
FileSystemView fsv = FileSystemView.getFileSystemView();
|
||||
// 列出所有windows 磁盘
|
||||
File[] fs = File.listRoots();
|
||||
log.info("查询磁盘信息:"+fs.length+"个");
|
||||
List<Map<String,Object>> list = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < fs.length; i++) {
|
||||
if(fs[i].getTotalSpace()==0) {
|
||||
continue;
|
||||
}
|
||||
Map<String,Object> map = new HashMap(5);
|
||||
map.put("name", fsv.getSystemDisplayName(fs[i]));
|
||||
map.put("max", fs[i].getTotalSpace());
|
||||
map.put("rest", fs[i].getFreeSpace());
|
||||
map.put("restPPT", (fs[i].getTotalSpace()-fs[i].getFreeSpace())*100/fs[i].getTotalSpace());
|
||||
list.add(map);
|
||||
log.info(map.toString());
|
||||
}
|
||||
res.setResult(list);
|
||||
res.success("查询成功");
|
||||
} catch (Exception e) {
|
||||
res.error500("查询失败"+e.getMessage());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
//update-end--Author:zhangweijian Date:20190425 for:获取磁盘信息
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
//package org.jeecg.modules.monitor.controller;
|
||||
//
|
||||
//import lombok.RequiredArgsConstructor;
|
||||
//import org.jeecg.common.api.vo.Result;
|
||||
//import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
//import org.jeecg.modules.monitor.service.DatabaseMonitorService;
|
||||
//import org.springframework.web.bind.annotation.GetMapping;
|
||||
//import org.springframework.web.bind.annotation.RequestMapping;
|
||||
//import org.springframework.web.bind.annotation.RestController;
|
||||
//
|
||||
//@RestController
|
||||
//@RequestMapping("monitor")
|
||||
//@RequiredArgsConstructor
|
||||
//public class DatabaseMonitorController {
|
||||
//
|
||||
// private final DatabaseMonitorService databaseMonitorService;
|
||||
//
|
||||
// @AutoLog(value = "获取CPU信息")
|
||||
// @GetMapping("getCpuInfo")
|
||||
// public Result<?> getCpuInfo() {
|
||||
// return Result.OK(databaseMonitorService.getCpuInfo());
|
||||
// }
|
||||
//
|
||||
// @AutoLog(value = "获取内存监测数据")
|
||||
// @GetMapping("getMemoryInfo")
|
||||
// public Result<?> getMemoryInfo() {
|
||||
// return Result.OK(databaseMonitorService.getMemoryInfo());
|
||||
// }
|
||||
//
|
||||
// @AutoLog(value = "获取表空间信息")
|
||||
// @GetMapping("getTableSpaceInfo")
|
||||
// public Result<?> getNetworkInfo() {
|
||||
// return Result.OK(databaseMonitorService.getTableSpaceInfo());
|
||||
// }
|
||||
//
|
||||
// @AutoLog(value = "获取活跃连接数信息")
|
||||
// @GetMapping("getActiveSessionInfo")
|
||||
// public Result<?> getDiskInfo() {
|
||||
// return Result.OK(databaseMonitorService.getActiveSessionInfo());
|
||||
// }
|
||||
//
|
||||
// @AutoLog(value = "获取死锁信息")
|
||||
// @GetMapping("getDeadlocksInfo")
|
||||
// public Result<?> getDeadlocksInfo() {
|
||||
// return Result.OK(databaseMonitorService.getDeadlocksInfo());
|
||||
// }
|
||||
//
|
||||
// @AutoLog(value = "获取数据库占比信息")
|
||||
// @GetMapping("getDatabaseProportionInfo")
|
||||
// public Result<?> getDatabaseProportionInfo() {
|
||||
// return Result.OK(databaseMonitorService.getDatabaseProportionInfo());
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package org.jeecg.modules.monitor.controller;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.jeecg.modules.monitor.service.HostMonitorService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("monitor")
|
||||
@RequiredArgsConstructor
|
||||
public class ServiceMonitorController {
|
||||
|
||||
private final HostMonitorService hostMonitorService;
|
||||
|
||||
@AutoLog(value = "获取CPU信息")
|
||||
@GetMapping("getCpuInfo")
|
||||
public Result<?> getCpuInfo() {
|
||||
return Result.OK(hostMonitorService.getCpuInfo());
|
||||
}
|
||||
|
||||
@AutoLog(value = "获取CPU核心数")
|
||||
@GetMapping("getCpuCoreInfo")
|
||||
public Result<?> getCpuCoreInfo() {
|
||||
return Result.OK(hostMonitorService.getCpuCoreInfo());
|
||||
}
|
||||
|
||||
@AutoLog(value = "获取内存监测数据")
|
||||
@GetMapping("getMemoryInfo")
|
||||
public Result<?> getMemoryInfo() {
|
||||
return Result.OK(hostMonitorService.getMemoryInfo());
|
||||
}
|
||||
|
||||
@AutoLog(value = "获取网络带宽监测数据")
|
||||
@GetMapping("getNetworkInfo")
|
||||
public Result<?> getNetworkInfo() {
|
||||
return Result.OK(hostMonitorService.getNetworkInfo());
|
||||
}
|
||||
|
||||
@AutoLog(value = "获取磁盘使用率")
|
||||
@GetMapping("getDiskInfo")
|
||||
public Result<?> getDiskInfo() {
|
||||
return Result.OK(hostMonitorService.getDiskInfo());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
package org.jeecg.modules.monitor.domain;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: redis信息
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public class RedisInfo {
|
||||
|
||||
private static Map<String, String> map = new HashMap(5);
|
||||
|
||||
static {
|
||||
map.put("redis_version", "Redis 服务器版本");
|
||||
map.put("redis_git_sha1", "Git SHA1");
|
||||
map.put("redis_git_dirty", "Git dirty flag");
|
||||
map.put("os", "Redis 服务器的宿主操作系统");
|
||||
map.put("arch_bits", " 架构(32 或 64 位)");
|
||||
map.put("multiplexing_api", "Redis 所使用的事件处理机制");
|
||||
map.put("gcc_version", "编译 Redis 时所使用的 GCC 版本");
|
||||
map.put("process_id", "服务器进程的 PID");
|
||||
map.put("run_id", "Redis 服务器的随机标识符(用于 Sentinel 和集群)");
|
||||
map.put("tcp_port", "TCP/IP 监听端口");
|
||||
map.put("uptime_in_seconds", "自 Redis 服务器启动以来,经过的秒数");
|
||||
map.put("uptime_in_days", "自 Redis 服务器启动以来,经过的天数");
|
||||
map.put("lru_clock", " 以分钟为单位进行自增的时钟,用于 LRU 管理");
|
||||
map.put("connected_clients", "已连接客户端的数量(不包括通过从属服务器连接的客户端)");
|
||||
map.put("client_longest_output_list", "当前连接的客户端当中,最长的输出列表");
|
||||
map.put("client_longest_input_buf", "当前连接的客户端当中,最大输入缓存");
|
||||
map.put("blocked_clients", "正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量");
|
||||
map.put("used_memory", "由 Redis 分配器分配的内存总量,以字节(byte)为单位");
|
||||
map.put("used_memory_human", "以人类可读的格式返回 Redis 分配的内存总量");
|
||||
map.put("used_memory_rss", "从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致");
|
||||
map.put("used_memory_peak", " Redis 的内存消耗峰值(以字节为单位)");
|
||||
map.put("used_memory_peak_human", "以人类可读的格式返回 Redis 的内存消耗峰值");
|
||||
map.put("used_memory_lua", "Lua 引擎所使用的内存大小(以字节为单位)");
|
||||
map.put("mem_fragmentation_ratio", "sed_memory_rss 和 used_memory 之间的比率");
|
||||
map.put("mem_allocator", "在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc");
|
||||
|
||||
map.put("redis_build_id", "redis_build_id");
|
||||
map.put("redis_mode", "运行模式,单机(standalone)或者集群(cluster)");
|
||||
map.put("atomicvar_api", "atomicvar_api");
|
||||
map.put("hz", "redis内部调度(进行关闭timeout的客户端,删除过期key等等)频率,程序规定serverCron每秒运行10次。");
|
||||
map.put("executable", "server脚本目录");
|
||||
map.put("config_file", "配置文件目录");
|
||||
map.put("client_biggest_input_buf", "当前连接的客户端当中,最大输入缓存,用client list命令观察qbuf和qbuf-free两个字段最大值");
|
||||
map.put("used_memory_rss_human", "以人类可读的方式返回 Redis 已分配的内存总量");
|
||||
map.put("used_memory_peak_perc", "内存使用率峰值");
|
||||
map.put("total_system_memory", "系统总内存");
|
||||
map.put("total_system_memory_human", "以人类可读的方式返回系统总内存");
|
||||
map.put("used_memory_lua_human", "以人类可读的方式返回Lua 引擎所使用的内存大小");
|
||||
map.put("maxmemory", "最大内存限制,0表示无限制");
|
||||
map.put("maxmemory_human", "以人类可读的方式返回最大限制内存");
|
||||
map.put("maxmemory_policy", "超过内存限制后的处理策略");
|
||||
map.put("loading", "服务器是否正在载入持久化文件");
|
||||
map.put("rdb_changes_since_last_save", "离最近一次成功生成rdb文件,写入命令的个数,即有多少个写入命令没有持久化");
|
||||
map.put("rdb_bgsave_in_progress", "服务器是否正在创建rdb文件");
|
||||
map.put("rdb_last_save_time", "离最近一次成功创建rdb文件的时间戳。当前时间戳 - rdb_last_save_time=多少秒未成功生成rdb文件");
|
||||
map.put("rdb_last_bgsave_status", "最近一次rdb持久化是否成功");
|
||||
map.put("rdb_last_bgsave_time_sec", "最近一次成功生成rdb文件耗时秒数");
|
||||
map.put("rdb_current_bgsave_time_sec", "如果服务器正在创建rdb文件,那么这个域记录的就是当前的创建操作已经耗费的秒数");
|
||||
map.put("aof_enabled", "是否开启了aof");
|
||||
map.put("aof_rewrite_in_progress", "标识aof的rewrite操作是否在进行中");
|
||||
map.put("aof_rewrite_scheduled", "rewrite任务计划,当客户端发送bgrewriteaof指令,如果当前rewrite子进程正在执行,那么将客户端请求的bgrewriteaof变为计划任务,待aof子进程结束后执行rewrite ");
|
||||
|
||||
map.put("aof_last_rewrite_time_sec", "最近一次aof rewrite耗费的时长");
|
||||
map.put("aof_current_rewrite_time_sec", "如果rewrite操作正在进行,则记录所使用的时间,单位秒");
|
||||
map.put("aof_last_bgrewrite_status", "上次bgrewrite aof操作的状态");
|
||||
map.put("aof_last_write_status", "上次aof写入状态");
|
||||
|
||||
map.put("total_commands_processed", "redis处理的命令数");
|
||||
map.put("total_connections_received", "新创建连接个数,如果新创建连接过多,过度地创建和销毁连接对性能有影响,说明短连接严重或连接池使用有问题,需调研代码的连接设置");
|
||||
map.put("instantaneous_ops_per_sec", "redis当前的qps,redis内部较实时的每秒执行的命令数");
|
||||
map.put("total_net_input_bytes", "redis网络入口流量字节数");
|
||||
map.put("total_net_output_bytes", "redis网络出口流量字节数");
|
||||
|
||||
map.put("instantaneous_input_kbps", "redis网络入口kps");
|
||||
map.put("instantaneous_output_kbps", "redis网络出口kps");
|
||||
map.put("rejected_connections", "拒绝的连接个数,redis连接个数达到maxclients限制,拒绝新连接的个数");
|
||||
map.put("sync_full", "主从完全同步成功次数");
|
||||
|
||||
map.put("sync_partial_ok", "主从部分同步成功次数");
|
||||
map.put("sync_partial_err", "主从部分同步失败次数");
|
||||
map.put("expired_keys", "运行以来过期的key的数量");
|
||||
map.put("evicted_keys", "运行以来剔除(超过了maxmemory后)的key的数量");
|
||||
map.put("keyspace_hits", "命中次数");
|
||||
map.put("keyspace_misses", "没命中次数");
|
||||
map.put("pubsub_channels", "当前使用中的频道数量");
|
||||
map.put("pubsub_patterns", "当前使用的模式的数量");
|
||||
map.put("latest_fork_usec", "最近一次fork操作阻塞redis进程的耗时数,单位微秒");
|
||||
map.put("role", "实例的角色,是master or slave");
|
||||
map.put("connected_slaves", "连接的slave实例个数");
|
||||
map.put("master_repl_offset", "主从同步偏移量,此值如果和上面的offset相同说明主从一致没延迟");
|
||||
map.put("repl_backlog_active", "复制积压缓冲区是否开启");
|
||||
map.put("repl_backlog_size", "复制积压缓冲大小");
|
||||
map.put("repl_backlog_first_byte_offset", "复制缓冲区里偏移量的大小");
|
||||
map.put("repl_backlog_histlen", "此值等于 master_repl_offset - repl_backlog_first_byte_offset,该值不会超过repl_backlog_size的大小");
|
||||
map.put("used_cpu_sys", "将所有redis主进程在核心态所占用的CPU时求和累计起来");
|
||||
map.put("used_cpu_user", "将所有redis主进程在用户态所占用的CPU时求和累计起来");
|
||||
map.put("used_cpu_sys_children", "将后台进程在核心态所占用的CPU时求和累计起来");
|
||||
map.put("used_cpu_user_children", "将后台进程在用户态所占用的CPU时求和累计起来");
|
||||
map.put("cluster_enabled", "实例是否启用集群模式");
|
||||
map.put("db0", "db0的key的数量,以及带有生存期的key的数,平均存活时间");
|
||||
|
||||
}
|
||||
|
||||
private String key;
|
||||
private String value;
|
||||
private String description;
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
this.description = map.get(this.key);
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RedisInfo{" + "key='" + key + '\'' + ", value='" + value + '\'' + ", desctiption='" + description + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
package org.jeecg.modules.monitor.exception;
|
||||
|
||||
/**
|
||||
* Redis 连接异常
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public class RedisConnectException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1639374111871115063L;
|
||||
|
||||
public RedisConnectException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package org.jeecg.modules.monitor.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.jeecg.modules.monitor.vo.DatabaseProportionInfo;
|
||||
import java.util.List;
|
||||
|
||||
public interface DatabaseMonitorMapper extends BaseMapper {
|
||||
|
||||
@Select("SELECT " +
|
||||
"datname AS databaseName," +
|
||||
"pg_database_size(datname) AS dataSize " +
|
||||
"FROM pg_database " +
|
||||
"WHERE datistemplate = false")
|
||||
List<DatabaseProportionInfo> getActiveSessionInfo();
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package org.jeecg.modules.monitor.service;
|
||||
|
||||
import org.jeecg.modules.monitor.vo.DatabaseProportionInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface DatabaseMonitorService {
|
||||
|
||||
/**
|
||||
* 获取CPU信息
|
||||
*/
|
||||
Map<String,Object> getCpuInfo();
|
||||
|
||||
/**
|
||||
* 获取内存信息
|
||||
*/
|
||||
Map<String,Object> getMemoryInfo();
|
||||
|
||||
/**
|
||||
* 获取表空间信息
|
||||
* @return
|
||||
*/
|
||||
Map<String,Object> getTableSpaceInfo();
|
||||
|
||||
/**
|
||||
* 获取活跃连接数信息
|
||||
* @return
|
||||
*/
|
||||
Map<String,Object> getActiveSessionInfo();
|
||||
|
||||
/**
|
||||
* 获取死锁信息
|
||||
* @return
|
||||
*/
|
||||
Map<String,Object> getDeadlocksInfo();
|
||||
|
||||
/**
|
||||
* 获取数据库占比信息
|
||||
* @return
|
||||
*/
|
||||
List<DatabaseProportionInfo> getDatabaseProportionInfo();
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package org.jeecg.modules.monitor.service;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface HostMonitorService {
|
||||
|
||||
/**
|
||||
* 获取CPU信息
|
||||
*/
|
||||
Map<String,Object> getCpuInfo();
|
||||
|
||||
/**
|
||||
* 获取CPU核心数
|
||||
*/
|
||||
Map<String,Object> getCpuCoreInfo();
|
||||
|
||||
/**
|
||||
* 获取内存信息
|
||||
*/
|
||||
Map<String,Object> getMemoryInfo();
|
||||
|
||||
/**
|
||||
* 获取网络信息
|
||||
*/
|
||||
Map<String,Object> getNetworkInfo();
|
||||
|
||||
/**
|
||||
* 获取磁盘使用率
|
||||
*/
|
||||
Map<String,Object> getDiskInfo();
|
||||
|
||||
/**
|
||||
* 获取磁盘吞吐量
|
||||
* @return
|
||||
*/
|
||||
Map<String,Object> getDiskThroughputInfo();
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
package org.jeecg.modules.monitor.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import org.jeecg.modules.monitor.domain.RedisInfo;
|
||||
import org.jeecg.modules.monitor.exception.RedisConnectException;
|
||||
|
||||
/**
|
||||
* @Description: redis信息service接口
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public interface RedisService {
|
||||
|
||||
/**
|
||||
* 获取 redis 的详细信息
|
||||
*
|
||||
* @return List
|
||||
* @throws RedisConnectException
|
||||
*/
|
||||
List<RedisInfo> getRedisInfo() throws RedisConnectException;
|
||||
|
||||
/**
|
||||
* 获取 redis key 数量
|
||||
*
|
||||
* @return Map
|
||||
* @throws RedisConnectException
|
||||
*/
|
||||
Map<String, Object> getKeysSize() throws RedisConnectException;
|
||||
|
||||
/**
|
||||
* 获取 redis 内存信息
|
||||
*
|
||||
* @return Map
|
||||
* @throws RedisConnectException
|
||||
*/
|
||||
Map<String, Object> getMemoryInfo() throws RedisConnectException;
|
||||
/**
|
||||
* 获取 报表需要个redis信息
|
||||
* @param type
|
||||
* @return Map
|
||||
* @throws RedisConnectException
|
||||
*/
|
||||
Map<String, JSONArray> getMapForReport(String type) throws RedisConnectException ;
|
||||
|
||||
/**
|
||||
* 获取历史性能指标
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2024/5/14 14:57
|
||||
*/
|
||||
Map<String, List<Map<String, Object>>> getMetricsHistory();
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package org.jeecg.modules.monitor.service.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.jeecg.modules.monitor.mapper.DatabaseMonitorMapper;
|
||||
import org.jeecg.modules.monitor.service.DatabaseMonitorService;
|
||||
import org.jeecg.modules.monitor.vo.DatabaseProportionInfo;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DatabaseMonitorServiceImpl implements DatabaseMonitorService {
|
||||
|
||||
private final DatabaseMonitorMapper databaseMonitorMapper;
|
||||
|
||||
/**
|
||||
* 获取CPU信息
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getCpuInfo() {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取内存信息
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getMemoryInfo() {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表空间信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getTableSpaceInfo() {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取活跃连接数信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getActiveSessionInfo() {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取死锁信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getDeadlocksInfo() {
|
||||
//irate(pg_stat_database_deadlocks{instance="192.168.186.143:9187", datname=~"postgres"}[5m])
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库占比信息
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<DatabaseProportionInfo> getDatabaseProportionInfo() {
|
||||
return databaseMonitorMapper.getActiveSessionInfo();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,294 @@
|
|||
package org.jeecg.modules.monitor.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.properties.PrometheusServerProperties;
|
||||
import org.jeecg.modules.monitor.service.HostMonitorService;
|
||||
import org.jeecg.modules.monitor.vo.PrometheusResponse;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 基于Prometheus的主机监控
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class HostMonitorServiceImpl implements HostMonitorService {
|
||||
|
||||
private final WebClient webClient;
|
||||
private final PrometheusServerProperties serverProperties;
|
||||
|
||||
/**
|
||||
* 获取CPU信息
|
||||
*/
|
||||
@Override
|
||||
public Map<String,Object> getCpuInfo() {
|
||||
Map<String,Object> result = new HashMap<>();
|
||||
try {
|
||||
//Prometheus 服务器地址
|
||||
String url = serverProperties.getServerUrl();
|
||||
//目标主机实例(node-exporter 的地址)
|
||||
String instance = serverProperties.getInstance();
|
||||
//查询CPU利用率
|
||||
String cpuQuery = "100 * (1 - avg(rate(node_cpu_seconds_total{mode=\"idle\", instance=\""+instance+"\"}[1m0s])))";
|
||||
PrometheusResponse response = webClient.get()
|
||||
.uri(buildUri(url,cpuQuery))
|
||||
.retrieve()
|
||||
.bodyToMono(PrometheusResponse.class)
|
||||
.block();
|
||||
if(Objects.nonNull(response) &&
|
||||
Objects.nonNull(response.getData()) &&
|
||||
CollUtil.isNotEmpty(response.getData().getResult())
|
||||
) {
|
||||
PrometheusResponse.Result cpuInfo = response.getData().getResult().get(0);
|
||||
if(CollUtil.isNotEmpty(cpuInfo.getValue())) {
|
||||
Date date = new Date(cpuInfo.getValue().get(0).longValue()*1000);
|
||||
Double useRate = BigDecimal.valueOf(cpuInfo.getValue().get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||
result.put("date", DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"));
|
||||
result.put("usageRate", useRate);
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("获取CPU信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取CPU核心数
|
||||
*/
|
||||
@Override
|
||||
public Map<String,Object> getCpuCoreInfo() {
|
||||
Map<String,Object> result = new HashMap<>();
|
||||
try {
|
||||
//Prometheus 服务器地址
|
||||
String url = serverProperties.getServerUrl();
|
||||
//目标主机实例(node-exporter 的地址)
|
||||
String instance = serverProperties.getInstance();
|
||||
//查询CPU核数
|
||||
String cpuCoreQuery = "count(count by (cpu) (node_cpu_seconds_total{instance=\"" + instance + "\"}))";
|
||||
PrometheusResponse response = webClient.get()
|
||||
.uri(buildUri(url,cpuCoreQuery))
|
||||
.retrieve()
|
||||
.bodyToMono(PrometheusResponse.class)
|
||||
.block();
|
||||
if(Objects.nonNull(response) &&
|
||||
Objects.nonNull(response.getData()) &&
|
||||
CollUtil.isNotEmpty(response.getData().getResult())
|
||||
) {
|
||||
PrometheusResponse.Result cpuInfo = response.getData().getResult().get(0);
|
||||
if(CollUtil.isNotEmpty(cpuInfo.getValue())) {
|
||||
Integer cpuCores = cpuInfo.getValue().get(1).intValue();
|
||||
result.put("cpuCores", cpuCores);
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("获取CPU核心数错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取内存信息
|
||||
*/
|
||||
@Override
|
||||
public Map<String,Object> getMemoryInfo() {
|
||||
Map<String,Object> result = new HashMap<>();
|
||||
try {
|
||||
//Prometheus 服务器地址
|
||||
String url = serverProperties.getServerUrl();
|
||||
//目标主机实例(node-exporter 的地址)
|
||||
String instance = serverProperties.getInstance();
|
||||
//查询总内存
|
||||
String totalMemoryQuery = "node_memory_MemTotal_bytes{instance=\"" + instance + "\"}";
|
||||
PrometheusResponse totalMemoryResponse = webClient.get()
|
||||
.uri(buildUri(url,totalMemoryQuery))
|
||||
.retrieve()
|
||||
.bodyToMono(PrometheusResponse.class)
|
||||
.block();
|
||||
if(Objects.nonNull(totalMemoryResponse) &&
|
||||
Objects.nonNull(totalMemoryResponse.getData()) &&
|
||||
CollUtil.isNotEmpty(totalMemoryResponse.getData().getResult())
|
||||
) {
|
||||
PrometheusResponse.Result totalMemoryInfo = totalMemoryResponse.getData().getResult().get(0);
|
||||
if(CollUtil.isNotEmpty(totalMemoryInfo.getValue())) {
|
||||
Double totalMemory = BigDecimal.valueOf(totalMemoryInfo.getValue().get(1)/1024/1024/1024).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||
result.put("totalMemory",totalMemory);
|
||||
}
|
||||
}
|
||||
//剩余可用内存
|
||||
String availableMemoryQuery = "node_memory_MemAvailable_bytes{instance=\"" + instance + "\"}";
|
||||
PrometheusResponse availableMemoryResponse = webClient.get()
|
||||
.uri(buildUri(url,availableMemoryQuery))
|
||||
.retrieve()
|
||||
.bodyToMono(PrometheusResponse.class)
|
||||
.block();;
|
||||
if(Objects.nonNull(availableMemoryResponse) &&
|
||||
Objects.nonNull(availableMemoryResponse.getData()) &&
|
||||
CollUtil.isNotEmpty(availableMemoryResponse.getData().getResult())
|
||||
) {
|
||||
PrometheusResponse.Result availableMemoryInfo = availableMemoryResponse.getData().getResult().get(0);
|
||||
if(CollUtil.isNotEmpty(availableMemoryInfo.getValue())) {
|
||||
Double availableMemory = BigDecimal.valueOf(availableMemoryInfo.getValue().get(1)/1024/1024/1024).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||
result.put("availableMemory",availableMemory);
|
||||
}
|
||||
}
|
||||
//使用率
|
||||
String usageRateQuery = "(1 - (node_memory_MemAvailable_bytes{instance=\""+instance+"\"} / node_memory_MemTotal_bytes{instance=\""+instance+"\"})) * 100";
|
||||
PrometheusResponse usageRateResponse = webClient.get()
|
||||
.uri(buildUri(url,usageRateQuery))
|
||||
.retrieve()
|
||||
.bodyToMono(PrometheusResponse.class)
|
||||
.block();
|
||||
if(Objects.nonNull(usageRateResponse) &&
|
||||
Objects.nonNull(usageRateResponse.getData()) &&
|
||||
CollUtil.isNotEmpty(usageRateResponse.getData().getResult())
|
||||
) {
|
||||
PrometheusResponse.Result usageRateInfo = usageRateResponse.getData().getResult().get(0);
|
||||
if(CollUtil.isNotEmpty(usageRateInfo.getValue())) {
|
||||
Date date = new Date(usageRateInfo.getValue().get(0).longValue()*1000);
|
||||
Double usageRate = BigDecimal.valueOf(usageRateInfo.getValue().get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||
result.put("date", DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"));
|
||||
result.put("usageRate", usageRate);
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("获取内存信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取网络信息
|
||||
*/
|
||||
@Override
|
||||
public Map<String,Object> getNetworkInfo() {
|
||||
Map<String,Object> result = new HashMap<>();
|
||||
try {
|
||||
//Prometheus 服务器地址
|
||||
String url = serverProperties.getServerUrl();
|
||||
//目标主机实例(node-exporter 的地址)
|
||||
String instance = serverProperties.getInstance();
|
||||
//接收带宽 (Kbps)
|
||||
String receiveKbpsQuery = "rate(node_network_receive_bytes_total{instance=\"" + instance + "\", device=\"ens32\"}[1m]) * 8 / 1000";
|
||||
PrometheusResponse receiveKbpsResponse = webClient.get()
|
||||
.uri(buildUri(url,receiveKbpsQuery))
|
||||
.retrieve()
|
||||
.bodyToMono(PrometheusResponse.class)
|
||||
.block();
|
||||
if(Objects.nonNull(receiveKbpsResponse) &&
|
||||
Objects.nonNull(receiveKbpsResponse.getData()) &&
|
||||
CollUtil.isNotEmpty(receiveKbpsResponse.getData().getResult())
|
||||
) {
|
||||
PrometheusResponse.Result receiveKbpsInfo = receiveKbpsResponse.getData().getResult().get(0);
|
||||
if(CollUtil.isNotEmpty(receiveKbpsInfo.getValue())) {
|
||||
Date date = new Date(receiveKbpsInfo.getValue().get(0).longValue()*1000);
|
||||
Double receiveKbps = BigDecimal.valueOf(receiveKbpsInfo.getValue().get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||
result.put("receiveDate", DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"));
|
||||
result.put("receiveKbps", receiveKbps);
|
||||
}
|
||||
}
|
||||
|
||||
//发送带宽 (Kbps)
|
||||
String transmitKbpsQuery = "rate(node_network_transmit_bytes_total{instance=\"" + instance + "\", device=\"ens32\"}[1m]) * 8 / 1000";
|
||||
PrometheusResponse transmitKbpsResponse = webClient.get()
|
||||
.uri(buildUri(url,transmitKbpsQuery))
|
||||
.retrieve()
|
||||
.bodyToMono(PrometheusResponse.class)
|
||||
.block();
|
||||
if(Objects.nonNull(transmitKbpsResponse) &&
|
||||
Objects.nonNull(transmitKbpsResponse.getData()) &&
|
||||
CollUtil.isNotEmpty(transmitKbpsResponse.getData().getResult())
|
||||
) {
|
||||
PrometheusResponse.Result transmitKbpsInfo = transmitKbpsResponse.getData().getResult().get(0);
|
||||
if(CollUtil.isNotEmpty(transmitKbpsInfo.getValue())) {
|
||||
Date date = new Date(transmitKbpsInfo.getValue().get(0).longValue()*1000);
|
||||
Double transmitKbps = BigDecimal.valueOf(transmitKbpsInfo.getValue().get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||
result.put("transmitDate", DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"));
|
||||
result.put("transmitKbps", transmitKbps);
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("获取网络信息错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取磁盘使用率
|
||||
*/
|
||||
@Override
|
||||
public Map<String,Object> getDiskInfo() {
|
||||
Map<String,Object> result = new HashMap<>();
|
||||
try {
|
||||
//Prometheus 服务器地址
|
||||
String url = serverProperties.getServerUrl();
|
||||
//目标主机实例(node-exporter 的地址)
|
||||
String instance = serverProperties.getInstance();
|
||||
//磁盘使用率
|
||||
String diskUsageQuery = "((node_filesystem_size_bytes{instance=\""+instance+"\", device!~\"rootfs\"} - node_filesystem_avail_bytes{instance=\""+instance+"\", device!~\"rootfs\"}) / node_filesystem_size_bytes{instance=\""+instance+"\", device!~\"rootfs\"}) * 100";
|
||||
PrometheusResponse diskUsageResponse = webClient.get()
|
||||
.uri(buildUri(url,diskUsageQuery))
|
||||
.retrieve()
|
||||
.bodyToMono(PrometheusResponse.class)
|
||||
.block();
|
||||
if(Objects.nonNull(diskUsageResponse) &&
|
||||
Objects.nonNull(diskUsageResponse.getData()) &&
|
||||
CollUtil.isNotEmpty(diskUsageResponse.getData().getResult())
|
||||
) {
|
||||
for (PrometheusResponse.Result responseData :diskUsageResponse.getData().getResult()){
|
||||
String mountpoint = responseData.getMetric().getMountpoint();
|
||||
Double usageRate = BigDecimal.valueOf(responseData.getValue().get(1)).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||
result.put(mountpoint,usageRate);
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("获取磁盘使用率错误,请检查Prometheus服务是否正常启动或Java请求参数是否正确,详细堆栈错误为:{}",e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取磁盘吞吐量
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getDiskThroughputInfo() {
|
||||
//Expr: irate(node_disk_read_bytes_total{instance="192.168.186.143:9100",job="Prometheus服务器",device=~"[a-z]+|nvme[0-9]+n[0-9]+|mmcblk[0-9]+"}[1m0s])
|
||||
//irate(node_disk_written_bytes_total{instance="192.168.186.143:9100",job="Prometheus服务器",device=~"[a-z]+|nvme[0-9]+n[0-9]+|mmcblk[0-9]+"}[1m0s])
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建URI
|
||||
* @param url
|
||||
* @param query
|
||||
* @return
|
||||
*/
|
||||
private URI buildUri(String url,String query){
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(url + "/api/v1/query")
|
||||
.queryParam("query", query)
|
||||
.build()
|
||||
.toUri();
|
||||
return uri;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Date date = new Date(1758868629*1000L);
|
||||
System.out.println(DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
package org.jeecg.modules.monitor.service.impl;
|
||||
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 功能说明:自定义邮件检测
|
||||
*
|
||||
* @author: 李波
|
||||
* @email: 503378406@qq.com
|
||||
* @date: 2019-06-29
|
||||
*/
|
||||
@Component
|
||||
public class MailHealthIndicator implements HealthIndicator {
|
||||
|
||||
|
||||
@Override public Health health() {
|
||||
int errorCode = check();
|
||||
if (errorCode != 0) {
|
||||
return Health.down().withDetail("Error Code", errorCode) .build();
|
||||
}
|
||||
return Health.up().build();
|
||||
}
|
||||
int check(){
|
||||
//可以实现自定义的数据库检测逻辑
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,174 +0,0 @@
|
|||
package org.jeecg.modules.monitor.service.impl;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.monitor.domain.RedisInfo;
|
||||
import org.jeecg.modules.monitor.exception.RedisConnectException;
|
||||
import org.jeecg.modules.monitor.service.RedisService;
|
||||
import org.springframework.cglib.beans.BeanMap;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Redis 监控信息获取
|
||||
*
|
||||
* @Author MrBird
|
||||
*/
|
||||
@Service("redisService")
|
||||
@Slf4j
|
||||
public class RedisServiceImpl implements RedisService {
|
||||
|
||||
@Resource
|
||||
private RedisConnectionFactory redisConnectionFactory;
|
||||
|
||||
/**
|
||||
* redis信息
|
||||
*/
|
||||
private static final String REDIS_MESSAGE = "3";
|
||||
|
||||
/**
|
||||
* redis性能信息记录
|
||||
*/
|
||||
private static final Map<String,List<Map<String, Object>>> REDIS_METRICS = new HashMap<>(2);
|
||||
|
||||
/**
|
||||
* Redis详细信息
|
||||
*/
|
||||
@Override
|
||||
public List<RedisInfo> getRedisInfo() throws RedisConnectException {
|
||||
Properties info = redisConnectionFactory.getConnection().info();
|
||||
List<RedisInfo> infoList = new ArrayList<>();
|
||||
RedisInfo redisInfo = null;
|
||||
for (Map.Entry<Object, Object> entry : info.entrySet()) {
|
||||
redisInfo = new RedisInfo();
|
||||
redisInfo.setKey(oConvertUtils.getString(entry.getKey()));
|
||||
redisInfo.setValue(oConvertUtils.getString(entry.getValue()));
|
||||
infoList.add(redisInfo);
|
||||
}
|
||||
return infoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getKeysSize() throws RedisConnectException {
|
||||
Long dbSize = redisConnectionFactory.getConnection().dbSize();
|
||||
Map<String, Object> map = new HashMap(5);
|
||||
map.put("create_time", System.currentTimeMillis());
|
||||
map.put("dbSize", dbSize);
|
||||
|
||||
log.debug("--getKeysSize--: " + map.toString());
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getMemoryInfo() throws RedisConnectException {
|
||||
Map<String, Object> map = null;
|
||||
Properties info = redisConnectionFactory.getConnection().info();
|
||||
for (Map.Entry<Object, Object> entry : info.entrySet()) {
|
||||
String key = oConvertUtils.getString(entry.getKey());
|
||||
if ("used_memory".equals(key)) {
|
||||
map = new HashMap(5);
|
||||
map.put("used_memory", entry.getValue());
|
||||
map.put("create_time", System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
log.debug("--getMemoryInfo--: " + map.toString());
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询redis信息for报表
|
||||
* @param type 1redis key数量 2 占用内存 3redis信息
|
||||
* @return
|
||||
* @throws RedisConnectException
|
||||
*/
|
||||
@Override
|
||||
public Map<String, JSONArray> getMapForReport(String type) throws RedisConnectException {
|
||||
Map<String,JSONArray> mapJson=new HashMap(5);
|
||||
JSONArray json = new JSONArray();
|
||||
if(REDIS_MESSAGE.equals(type)){
|
||||
List<RedisInfo> redisInfo = getRedisInfo();
|
||||
for(RedisInfo info:redisInfo){
|
||||
Map<String, Object> map= Maps.newHashMap();
|
||||
BeanMap beanMap = BeanMap.create(info);
|
||||
for (Object key : beanMap.keySet()) {
|
||||
map.put(key+"", beanMap.get(key));
|
||||
}
|
||||
json.add(map);
|
||||
}
|
||||
mapJson.put("data",json);
|
||||
return mapJson;
|
||||
}
|
||||
int length = 5;
|
||||
for(int i = 0; i < length; i++){
|
||||
JSONObject jo = new JSONObject();
|
||||
Map<String, Object> map;
|
||||
if("1".equals(type)){
|
||||
map= getKeysSize();
|
||||
jo.put("value",map.get("dbSize"));
|
||||
}else{
|
||||
map = getMemoryInfo();
|
||||
Integer usedMemory = Integer.valueOf(map.get("used_memory").toString());
|
||||
jo.put("value",usedMemory/1000);
|
||||
}
|
||||
String createTime = DateUtil.formatTime(DateUtil.date((Long) map.get("create_time")-(4-i)*1000));
|
||||
jo.put("name",createTime);
|
||||
json.add(jo);
|
||||
}
|
||||
mapJson.put("data",json);
|
||||
return mapJson;
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20240514 for:[QQYUN-9247]系统监控功能优化------------
|
||||
/**
|
||||
* 获取历史性能指标
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2024/5/14 14:57
|
||||
*/
|
||||
@Override
|
||||
public Map<String, List<Map<String, Object>>> getMetricsHistory() {
|
||||
return REDIS_METRICS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录近一小时redis监控数据 <br/>
|
||||
* 60s一次,,记录存储keysize和内存
|
||||
* @throws RedisConnectException
|
||||
* @author chenrui
|
||||
* @date 2024/5/14 14:09
|
||||
*/
|
||||
@Scheduled(fixedRate = 60000)
|
||||
public void recordCustomMetric() throws RedisConnectException {
|
||||
List<Map<String, Object>> list= new ArrayList<>();
|
||||
if(REDIS_METRICS.containsKey("dbSize")){
|
||||
list = REDIS_METRICS.get("dbSize");
|
||||
}else{
|
||||
REDIS_METRICS.put("dbSize",list);
|
||||
}
|
||||
if(list.size()>60){
|
||||
list.remove(0);
|
||||
}
|
||||
list.add(getKeysSize());
|
||||
list= new ArrayList<>();
|
||||
if(REDIS_METRICS.containsKey("memory")){
|
||||
list = REDIS_METRICS.get("memory");
|
||||
}else{
|
||||
REDIS_METRICS.put("memory",list);
|
||||
}
|
||||
if(list.size()>60){
|
||||
list.remove(0);
|
||||
}
|
||||
list.add(getMemoryInfo());
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240514 for:[QQYUN-9247]系统监控功能优化------------
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package org.jeecg.modules.monitor.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 每个数据库数据量
|
||||
*/
|
||||
@Data
|
||||
public class DatabaseProportionInfo {
|
||||
|
||||
private String databaseName;
|
||||
|
||||
private Long dataSize;
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
package org.jeecg.modules.monitor.vo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PrometheusResponse {
|
||||
|
||||
private String status;
|
||||
private Data data;
|
||||
|
||||
public static class Data {
|
||||
private String resultType;
|
||||
private List<Result> result;
|
||||
|
||||
public String getResultType() {
|
||||
return resultType;
|
||||
}
|
||||
|
||||
public void setResultType(String resultType) {
|
||||
this.resultType = resultType;
|
||||
}
|
||||
|
||||
public List<Result> getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(List<Result> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Data{" +
|
||||
"resultType=" + resultType +
|
||||
", result=" + result +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public static class Result {
|
||||
private Metric metric;
|
||||
private List<Double> value; // 单值查询
|
||||
|
||||
public Metric getMetric() {
|
||||
return metric;
|
||||
}
|
||||
|
||||
public void setMetric(Metric metric) {
|
||||
this.metric = metric;
|
||||
}
|
||||
|
||||
public List<Double> getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(List<Double> value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Result{" +
|
||||
"metric=" + metric +
|
||||
", value=" + value +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Data getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Data data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PrometheusResponse{" +
|
||||
"status='" + status + '\'' +
|
||||
", data=" + data +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static class Metric {
|
||||
|
||||
private String app;
|
||||
|
||||
private String device;
|
||||
|
||||
private String fstype;
|
||||
|
||||
private String instance;
|
||||
|
||||
private String job;
|
||||
|
||||
private String mountpoint;
|
||||
|
||||
public String getApp() {
|
||||
return app;
|
||||
}
|
||||
|
||||
public void setApp(String app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
public String getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
public void setDevice(String device) {
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
public String getFstype() {
|
||||
return fstype;
|
||||
}
|
||||
|
||||
public void setFstype(String fstype) {
|
||||
this.fstype = fstype;
|
||||
}
|
||||
|
||||
public String getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void setInstance(String instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public String getJob() {
|
||||
return job;
|
||||
}
|
||||
|
||||
public void setJob(String job) {
|
||||
this.job = job;
|
||||
}
|
||||
|
||||
public String getMountpoint() {
|
||||
return mountpoint;
|
||||
}
|
||||
|
||||
public void setMountpoint(String mountpoint) {
|
||||
this.mountpoint = mountpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Metric{" +
|
||||
"app='" + app + '\'' +
|
||||
", device='" + device + '\'' +
|
||||
", fstype='" + fstype + '\'' +
|
||||
", instance='" + instance + '\'' +
|
||||
", job='" + job + '\'' +
|
||||
", mountpoint='" + mountpoint + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package org.jeecg.modules.system.config;
|
||||
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||
import io.netty.handler.timeout.WriteTimeoutHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.netty.http.client.HttpClient;
|
||||
import reactor.netty.resources.ConnectionProvider;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class WebClientConfig {
|
||||
|
||||
@Bean
|
||||
public WebClient webClient() {
|
||||
// 配置HTTP连接池
|
||||
ConnectionProvider provider = ConnectionProvider.builder("custom")
|
||||
.maxConnections(100)
|
||||
.maxIdleTime(Duration.ofSeconds(20))
|
||||
.build();
|
||||
// 配置HTTP客户端
|
||||
HttpClient httpClient = HttpClient.create(provider)
|
||||
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
|
||||
.responseTimeout(Duration.ofSeconds(5))
|
||||
.doOnConnected(conn ->
|
||||
conn.addHandlerLast(new ReadTimeoutHandler(5))
|
||||
.addHandlerLast(new WriteTimeoutHandler(5)));
|
||||
// 构建WebClient实例
|
||||
return WebClient.builder()
|
||||
.clientConnector(new ReactorClientHttpConnector(httpClient))
|
||||
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
|
||||
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
|
||||
// 添加请求日志记录功能
|
||||
.filter(ExchangeFilterFunction.ofRequestProcessor(
|
||||
clientRequest -> {
|
||||
log.debug("Request: {} {}",
|
||||
clientRequest.method(),
|
||||
clientRequest.url());
|
||||
return Mono.just(clientRequest);
|
||||
}
|
||||
))
|
||||
// 添加响应日志记录功能
|
||||
.filter(ExchangeFilterFunction.ofResponseProcessor(
|
||||
clientResponse -> {
|
||||
log.debug("Response status: {}",
|
||||
clientResponse.statusCode());
|
||||
return Mono.just(clientResponse);
|
||||
}
|
||||
))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
@ -170,7 +170,7 @@ public class LoginController {
|
|||
//3.设置登录用户信息
|
||||
obj.put("userInfo", sysUser);
|
||||
obj.put("auth",authUserService.getUserPermissionsSet(sysUser.getId()));
|
||||
obj.put("menu",authUserService.getUserRoleSetById(sysUser.getId()));
|
||||
obj.put("menu",authUserService.getUserMenuPaths(sysUser.getId()));
|
||||
result.setResult(obj);
|
||||
result.success("登录成功");
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import org.jeecg.common.system.query.PageRequest;
|
|||
import org.jeecg.modules.system.entity.SysLog;
|
||||
import org.jeecg.modules.system.service.ISysLogService;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
|
|
@ -29,7 +28,6 @@ public class SysLogController {
|
|||
private final ISysLogService sysLogService;
|
||||
|
||||
@GetMapping(value = "page")
|
||||
@PreAuthorize("@jps.requiresPermissions('system:log:page')")
|
||||
public Result<?> page(PageRequest pageRequest,
|
||||
@NotNull(message = "日志类型不能为空") Integer logType,
|
||||
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ public class SysPermissionController {
|
|||
private final ISysPermissionService sysPermissionService;
|
||||
|
||||
@AutoLog(value = "查询菜单树")
|
||||
@PreAuthorize("@jps.requiresPermissions('system:permission:tree')")
|
||||
@GetMapping(value = "getPermissionTree")
|
||||
public Result<?> getPermissionTree() {
|
||||
return Result.ok(sysPermissionService.getPermissionTree());
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ public class SysRoleController {
|
|||
|
||||
private final ISysRoleService sysRoleService;
|
||||
|
||||
@AutoLog(value = "分页查询用户数据")
|
||||
@PreAuthorize("@jps.requiresPermissions('system:role:page')")
|
||||
@AutoLog(value = "分页查询角色数据")
|
||||
@GetMapping(value = "page")
|
||||
public Result<?> page(PageRequest pageRequest, String roleName, String roleCode) {
|
||||
IPage<SysRole> page = sysRoleService.page(pageRequest, roleName, roleCode);
|
||||
|
|
@ -47,7 +46,14 @@ public class SysRoleController {
|
|||
return Result.OK(rspData);
|
||||
}
|
||||
|
||||
@AutoLog(value = "添加用户")
|
||||
@AutoLog(value = "查询所有角色数据")
|
||||
@PreAuthorize("@jps.requiresPermissions('system:role:getAll')")
|
||||
@GetMapping(value = "getAll")
|
||||
public Result<?> getAll(PageRequest pageRequest, String roleName, String roleCode) {
|
||||
return Result.OK(sysRoleService.getAll());
|
||||
}
|
||||
|
||||
@AutoLog(value = "添加角色")
|
||||
@PreAuthorize("@jps.requiresPermissions('system:role:create')")
|
||||
@PostMapping("create")
|
||||
public Result<?> create(@Validated(value = InsertGroup.class) @RequestBody SysRole role) {
|
||||
|
|
@ -55,7 +61,7 @@ public class SysRoleController {
|
|||
return Result.OK();
|
||||
}
|
||||
|
||||
@AutoLog(value = "编辑用户")
|
||||
@AutoLog(value = "编辑角色")
|
||||
@PreAuthorize("@jps.requiresPermissions('system:role:update')")
|
||||
@PutMapping("update")
|
||||
public Result<SysRole> update(@Validated(value = UpdateGroup.class) @RequestBody SysRole role) {
|
||||
|
|
@ -85,4 +91,11 @@ public class SysRoleController {
|
|||
this.sysRoleService.saveRolePermissionRelation(authorisationVo);
|
||||
return Result.OK();
|
||||
}
|
||||
|
||||
@AutoLog(value = "查询指定角色已授权的信息")
|
||||
@PreAuthorize("@jps.requiresPermissions('system:role:authorized')")
|
||||
@GetMapping(value = "authorized")
|
||||
public Result<?> authorized(@NotBlank(message = "roleId不能为空") String roleId) {
|
||||
return Result.OK(this.sysRoleService.getAuthorizedInfo(roleId));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package org.jeecg.modules.system.controller;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
|
@ -33,7 +32,6 @@ public class SysUserController {
|
|||
private final IAuthUserService authUserService;
|
||||
|
||||
@AutoLog(value = "分页获取用户信息")
|
||||
@PreAuthorize("@jps.requiresPermissions('system:user:page')")
|
||||
@GetMapping(value = "page")
|
||||
public Result<?> page(PageRequest pageRequest,String username,Integer status) {
|
||||
IPage<SysUser> page = authUserService.page(pageRequest, username,status);
|
||||
|
|
@ -100,4 +98,11 @@ public class SysUserController {
|
|||
this.authUserService.updateStatus(userId,status);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@AutoLog(value = "查询用户有权限的菜单")
|
||||
@PreAuthorize("@jps.requiresPermissions('system:user:selectUserPermissions')")
|
||||
@GetMapping(value = "selectUserPermissions")
|
||||
public Result<?> selectUserPermissions() {
|
||||
return Result.ok(this.authUserService.selectUserPermissions());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,9 +37,6 @@ public class SysUserRole implements Serializable {
|
|||
*/
|
||||
private String roleId;
|
||||
|
||||
/**租户ID*/
|
||||
private java.lang.Integer tenantId;
|
||||
|
||||
public SysUserRole() {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,13 @@ public interface SysPermissionMapper extends BaseMapper<SysPermission> {
|
|||
*/
|
||||
List<SysPermission> queryByUserId(@Param("userId") String userId);
|
||||
|
||||
/**
|
||||
* 根据用户id查询菜单路径
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
List<String> getUserMenuPaths(@Param("userId") String userId);
|
||||
|
||||
/**
|
||||
* 根据用户查询用户权限
|
||||
* @param userName 用户ID
|
||||
|
|
@ -61,5 +68,10 @@ public interface SysPermissionMapper extends BaseMapper<SysPermission> {
|
|||
*/
|
||||
List<SysPermission> getChildNodeInfo();
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户拥有权限的菜单信息
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
List<SysPermission> selectUserPermissions(@Param("userId") String userId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,9 @@
|
|||
package org.jeecg.modules.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.jeecg.modules.system.entity.SysRole;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
|
@ -20,23 +15,6 @@ import java.util.List;
|
|||
* @since 2018-12-19
|
||||
*/
|
||||
public interface SysRoleMapper extends BaseMapper<SysRole> {
|
||||
/**
|
||||
* 查询全部的角色(不做租户隔离)
|
||||
* @param page
|
||||
* @param role
|
||||
* @return
|
||||
*/
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
List<SysRole> listAllSysRole(@Param("page") Page<SysRole> page, @Param("role") SysRole role);
|
||||
|
||||
/**
|
||||
* 查询角色是否存在不做租户隔离
|
||||
*
|
||||
* @param roleCode
|
||||
* @return
|
||||
*/
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
SysRole getRoleNoTenant(@Param("roleCode") String roleCode);
|
||||
|
||||
/**
|
||||
* 根据用户id查询用户拥有的角色Code
|
||||
|
|
@ -64,4 +42,11 @@ public interface SysRoleMapper extends BaseMapper<SysRole> {
|
|||
*/
|
||||
@Delete("delete from sys_role_permission where role_id = #{roleId}")
|
||||
void deleteRolePermissionRelation(@Param("roleId") String roleId);
|
||||
|
||||
/**
|
||||
* 查询指定角色已授权的信息
|
||||
* @param roleId
|
||||
* @return
|
||||
*/
|
||||
List<String> getAuthorizedInfo(@Param("roleId") String roleId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
</select>
|
||||
|
||||
<select id="queryByUserId" parameterType="String">
|
||||
select sp.perms from sys_permission_copy1 sp
|
||||
select sp.perms from sys_permission sp
|
||||
inner join sys_role_permission srp on sp.id = srp.permission_id
|
||||
inner join sys_user_role sur on srp.role_id = sur.role_id
|
||||
where sp.perms is not null
|
||||
|
|
@ -37,4 +37,31 @@
|
|||
and sur.user_id = #{userId}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getUserMenuPaths" parameterType="String" resultType="String">
|
||||
select sp.url from sys_permission sp
|
||||
inner join sys_role_permission srp on sp.id = srp.permission_id
|
||||
inner join sys_user_role sur on srp.role_id = sur.role_id
|
||||
<if test="userId != null and userId != ''">
|
||||
where sur.user_id = #{userId}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="selectUserPermissions" parameterType="String">
|
||||
select
|
||||
sp.id,
|
||||
sp.parent_id as parentId,
|
||||
sp.name,
|
||||
sp.component,
|
||||
sp.url,
|
||||
sp.icon,
|
||||
sp.menu_type as menuType,
|
||||
sp.sort_no as sortNo
|
||||
from sys_permission sp
|
||||
inner join sys_role_permission srp on sp.id = srp.permission_id
|
||||
inner join sys_user_role sur on srp.role_id = sur.role_id
|
||||
<if test="userId != null and userId != ''">
|
||||
where sur.user_id = #{userId}
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
@ -2,54 +2,18 @@
|
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.jeecg.modules.system.mapper.SysRoleMapper">
|
||||
|
||||
<select id="listAllSysRole" resultType="org.jeecg.modules.system.entity.SysRole">
|
||||
SELECT * from sys_role
|
||||
WHERE 1=1
|
||||
<if test="role.roleName!='' and role.roleName!=null">
|
||||
<bind name="bindKeyword" value="'%'+role.roleName+'%'"/>
|
||||
AND role_name like #{bindKeyword}
|
||||
</if>
|
||||
<if test="role.roleCode!='' and role.roleCode!=null">
|
||||
<choose>
|
||||
<when test="role.roleCode.indexOf(',') != -1">
|
||||
AND role_code in
|
||||
<foreach item="item" index="index" collection="role.roleCode.split(',')" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</when>
|
||||
<otherwise>
|
||||
<bind name="bindRoleCode" value="'%'+role.roleCode+'%'"/>
|
||||
AND role_code like #{bindRoleCode}
|
||||
</otherwise>
|
||||
</choose>
|
||||
</if>
|
||||
<!--增加id查询 for:【issues/7948】角色解决根据id查询回显不对-->
|
||||
<if test="role.id!='' and role.id!=null">
|
||||
<choose>
|
||||
<when test="role.id.indexOf(',') != -1">
|
||||
AND id in
|
||||
<foreach item="item" index="index" collection="role.id.split(',')" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</when>
|
||||
<otherwise>
|
||||
AND id = #{role.id}
|
||||
</otherwise>
|
||||
</choose>
|
||||
</if>
|
||||
order by create_time desc
|
||||
</select>
|
||||
|
||||
|
||||
<select id="getRoleNoTenant" resultType="org.jeecg.modules.system.entity.SysRole">
|
||||
SELECT * from sys_role
|
||||
WHERE role_code = #{roleCode}
|
||||
</select>
|
||||
|
||||
<!-- 根据用户id查询用户拥有的角色 -->
|
||||
<select id="getRoleCodeListByUserId" resultType="org.jeecg.modules.system.entity.SysRole">
|
||||
SELECT id, role_code from sys_role
|
||||
WHERE id in (SELECT role_id from sys_user_role WHERE user_id = #{userId})
|
||||
</select>
|
||||
|
||||
<select id="getAuthorizedInfo" parameterType="String">
|
||||
select
|
||||
sp.id
|
||||
from sys_role_permission srp
|
||||
inner join sys_permission sp on srp.permission_id = sp."id"
|
||||
where srp.role_id = #{roleId}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
@ -6,6 +6,7 @@ import org.jeecg.common.system.query.PageRequest;
|
|||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.modules.system.entity.SysPermission;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.model.PermissionTreeModel;
|
||||
import org.jeecg.modules.system.vo.SysUserVo;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
|
@ -88,6 +89,13 @@ public interface IAuthUserService extends IService<SysUser> {
|
|||
*/
|
||||
List<String> getUserPermissionsSet(String userId);
|
||||
|
||||
/**
|
||||
* 获取用户所属菜单路径
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
List<String> getUserMenuPaths(String userId);
|
||||
|
||||
/**
|
||||
* 保存用户
|
||||
* @param userVo 用户
|
||||
|
|
@ -122,4 +130,9 @@ public interface IAuthUserService extends IService<SysUser> {
|
|||
|
||||
|
||||
LoginUser getEncodeUserInfo(String username);
|
||||
|
||||
/**
|
||||
* 查询用户有权限的菜单
|
||||
*/
|
||||
List<PermissionTreeModel<SysPermission>> selectUserPermissions();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,11 @@
|
|||
package org.jeecg.modules.system.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import org.jeecg.common.system.query.PageRequest;
|
||||
import org.jeecg.modules.system.entity.SysRole;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.vo.SysRoleAuthorisationVo;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
|
@ -33,6 +27,12 @@ public interface ISysRoleService extends IService<SysRole> {
|
|||
*/
|
||||
Page<SysRole> page(PageRequest pageRequest, String roleName, String roleCode);
|
||||
|
||||
/**
|
||||
* 获取所有角色
|
||||
* @return
|
||||
*/
|
||||
List<SysRole> getAll();
|
||||
|
||||
/**
|
||||
* 查询单条角色数据
|
||||
* @param roleId
|
||||
|
|
@ -65,4 +65,9 @@ public interface ISysRoleService extends IService<SysRole> {
|
|||
*/
|
||||
void deleteRole(String roleid);
|
||||
|
||||
/**
|
||||
* 查询指定角色已授权的信息
|
||||
* @param id
|
||||
*/
|
||||
List<String> getAuthorizedInfo(@NotBlank(message = "id不能为空") String id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
|
@ -10,7 +11,6 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
|
|
@ -18,9 +18,13 @@ import org.jeecg.common.system.query.PageRequest;
|
|||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.*;
|
||||
import org.jeecg.config.datasource.DataSourceSwitcher;
|
||||
import org.jeecg.config.security.utils.SecureUtil;
|
||||
import org.jeecg.modules.system.entity.*;
|
||||
import org.jeecg.modules.system.mapper.*;
|
||||
import org.jeecg.modules.system.model.PermissionTreeModel;
|
||||
import org.jeecg.modules.system.service.IAuthUserService;
|
||||
import org.jeecg.modules.system.util.SecurityUtil;
|
||||
import org.jeecg.modules.system.util.TreeUtil;
|
||||
import org.jeecg.modules.system.vo.SysUserVo;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
|
@ -153,7 +157,8 @@ public class AuthUserServiceImpl extends ServiceImpl<AuthUserMapper, SysUser> im
|
|||
if (!newpassword.equals(confirmpassword)) {
|
||||
throw new RuntimeException("两次输入密码不一致");
|
||||
}
|
||||
user.setPassword(password);
|
||||
String newPassword = PasswordUtil.encrypt(user.getUsername(),newpassword, user.getSalt());
|
||||
user.setPassword(newPassword);
|
||||
this.baseMapper.updateById(user);
|
||||
this.transactionManager.commit(transactionStatus);
|
||||
}catch (Exception e){
|
||||
|
|
@ -296,6 +301,17 @@ public class AuthUserServiceImpl extends ServiceImpl<AuthUserMapper, SysUser> im
|
|||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户所属菜单路径
|
||||
*
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<String> getUserMenuPaths(String userId) {
|
||||
return this.sysPermissionMapper.getUserMenuPaths(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存用户
|
||||
* @param userVo 用户
|
||||
|
|
@ -368,7 +384,6 @@ public class AuthUserServiceImpl extends ServiceImpl<AuthUserMapper, SysUser> im
|
|||
user.setRealname(userVo.getRealname());
|
||||
user.setEmail(userVo.getEmail());
|
||||
user.setPhone(userVo.getPhone());
|
||||
user.setStatus(userVo.getStatus());
|
||||
this.updateById(user);
|
||||
this.transactionManager.commit(authTransactionStatus);
|
||||
}catch (Exception e){
|
||||
|
|
@ -410,6 +425,13 @@ public class AuthUserServiceImpl extends ServiceImpl<AuthUserMapper, SysUser> im
|
|||
DataSourceSwitcher.switchToAuth();
|
||||
final TransactionStatus authTransactionStatus = this.transactionManager.getTransaction(this.transactionDefinition);
|
||||
try {
|
||||
SysUser sysUser = this.baseMapper.selectById(id);
|
||||
if(Objects.isNull(sysUser)){
|
||||
throw new RuntimeException("此用户不存在");
|
||||
}
|
||||
if(CommonConstant.ADMIN_USER.equals(sysUser.getUsername()) && CommonConstant.STATUS_DISABLE.equals(status)){
|
||||
throw new RuntimeException("不允许修改管理员用户为禁用状态");
|
||||
}
|
||||
this.baseMapper.update(new SysUser().setStatus(status),
|
||||
new UpdateWrapper<SysUser>().lambda().eq(SysUser::getId,id));
|
||||
this.transactionManager.commit(authTransactionStatus);
|
||||
|
|
@ -478,6 +500,38 @@ public class AuthUserServiceImpl extends ServiceImpl<AuthUserMapper, SysUser> im
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户有权限的菜单
|
||||
*/
|
||||
@Override
|
||||
public List<PermissionTreeModel<SysPermission>> selectUserPermissions() {
|
||||
LoginUser loginUser = SecureUtil.currentUser();
|
||||
//如果当前用户是超级管理员,则返回所有
|
||||
List<SysPermission> childNodeInfoList = null;
|
||||
if(!CommonConstant.ADMIN_USER.equals(loginUser.getUsername())){
|
||||
childNodeInfoList = this.sysPermissionMapper.selectUserPermissions(loginUser.getId());
|
||||
}else {
|
||||
childNodeInfoList = this.sysPermissionMapper.selectList(new QueryWrapper<>());
|
||||
}
|
||||
if (CollUtil.isNotEmpty(childNodeInfoList)) {
|
||||
List<PermissionTreeModel<SysPermission>> treeList = new ArrayList<>();
|
||||
for(SysPermission node : childNodeInfoList){
|
||||
PermissionTreeModel<SysPermission> treeModel = new PermissionTreeModel<>();
|
||||
treeModel.setId(node.getId());
|
||||
treeModel.setParentId(node.getParentId());
|
||||
treeModel.setTitle(node.getName());
|
||||
treeModel.setComponent(node.getComponent());
|
||||
treeModel.setPath(node.getUrl());
|
||||
treeModel.setIcon(node.getIcon());
|
||||
treeModel.setType(node.getMenuType());
|
||||
treeModel.setOrderNum(node.getSortNo());
|
||||
treeList.add(treeModel);
|
||||
}
|
||||
return TreeUtil.build(treeList);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户的角色code(多个逗号分割)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, S
|
|||
*/
|
||||
@Override
|
||||
public List<PermissionTreeModel<SysPermission>> getPermissionTree() {
|
||||
List<SysPermission> childNodeInfoList = this.baseMapper.getChildNodeInfo();
|
||||
List<SysPermission> childNodeInfoList = this.list();
|
||||
if (CollUtil.isNotEmpty(childNodeInfoList)) {
|
||||
List<PermissionTreeModel<SysPermission>> treeList = new ArrayList<>();
|
||||
for(SysPermission node : childNodeInfoList){
|
||||
|
|
@ -42,6 +42,7 @@ public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, S
|
|||
treeModel.setParentId(node.getParentId());
|
||||
treeModel.setTitle(node.getName());
|
||||
treeModel.setComponent(node.getComponent());
|
||||
treeModel.setPath(node.getUrl());
|
||||
treeModel.setIcon(node.getIcon());
|
||||
treeModel.setType(node.getMenuType());
|
||||
treeModel.setOrderNum(node.getSortNo());
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.jeecg.common.system.query.PageRequest;
|
||||
import org.jeecg.modules.system.entity.SysPermission;
|
||||
import org.jeecg.modules.system.entity.SysRole;
|
||||
import org.jeecg.modules.system.entity.SysRolePermission;
|
||||
import org.jeecg.modules.system.mapper.AuthRoleMapper;
|
||||
|
|
@ -17,8 +18,8 @@ import org.jeecg.modules.system.service.ISysRoleService;
|
|||
import org.jeecg.modules.system.vo.SysRoleAuthorisationVo;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
|
@ -51,6 +52,18 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
return this.baseMapper.selectPage(page, queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有角色
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<SysRole> getAll() {
|
||||
LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.select(SysRole::getId, SysRole::getRoleCode, SysRole::getRoleName);
|
||||
return this.list(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单条角色数据
|
||||
*
|
||||
|
|
@ -147,4 +160,15 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
//3.删除角色
|
||||
this.removeById(roleid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定角色已授权的信息
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
@Override
|
||||
public List<String> getAuthorizedInfo(String id) {
|
||||
List<String> permissionIds = sysRoleMapper.getAuthorizedInfo(id);
|
||||
return CollUtil.isNotEmpty(permissionIds)?permissionIds: Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ public class TreeUtil {
|
|||
|
||||
}
|
||||
|
||||
private final static Integer TOP_NODE_ID = 0;
|
||||
private final static String TOP_NODE_ID = "0";
|
||||
|
||||
/**
|
||||
* 用于构建菜单树
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user