代码提交
This commit is contained in:
36
pom.xml
36
pom.xml
@@ -17,41 +17,33 @@
|
|||||||
<java.version>21</java.version>
|
<java.version>21</java.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>metona-maven</id>
|
||||||
|
<url>https://gitee.com/thzxx/maven/raw/master</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.aspectj</groupId>
|
|
||||||
<artifactId>aspectjweaver</artifactId>
|
|
||||||
<version>1.9.7</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.rocksdb</groupId>
|
|
||||||
<artifactId>rocksdbjni</artifactId>
|
|
||||||
<version>8.3.2</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-json</artifactId>
|
<artifactId>hutool-json</artifactId>
|
||||||
<version>5.8.21</version>
|
<version>5.8.25</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.metona</groupId>
|
||||||
|
<artifactId>metona-cache-spring-boot-starter</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
package cn.somkit.fmt.action;
|
package cn.somkit.fmt.action;
|
||||||
|
|
||||||
import cn.somkit.fmt.annotation.ApiOperate;
|
|
||||||
import cn.somkit.fmt.config.RocksDBConfig;
|
|
||||||
import cn.somkit.fmt.utils.MD5Utils;
|
|
||||||
import cn.somkit.fmt.utils.OsInfoUtil;
|
import cn.somkit.fmt.utils.OsInfoUtil;
|
||||||
import cn.somkit.fmt.utils.RocksDBUtils;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@@ -50,48 +45,15 @@ public class DownloadAction {
|
|||||||
File folder = new File(path);
|
File folder = new File(path);
|
||||||
File[] listOfFiles = folder.listFiles();
|
File[] listOfFiles = folder.listFiles();
|
||||||
List<Map<String, Object>> list = new ArrayList<>();
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
List<String> keys = RocksDBUtils.getAllKey(RocksDBConfig.RocksDB_Column_Family);
|
|
||||||
if(listOfFiles != null){
|
if(listOfFiles != null){
|
||||||
for (File file : listOfFiles) {
|
for (File file : listOfFiles) {
|
||||||
if(!file.isFile()){
|
if(!file.isFile()){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(!keys.contains(file.getName())){
|
Map<String, Object> map = getObjectMap(file);
|
||||||
try (FileInputStream is = new FileInputStream(file)) {
|
|
||||||
String hash = MD5Utils.md5HashCode(is);
|
|
||||||
RocksDBUtils.put(RocksDBConfig.RocksDB_Column_Family, file.getName(), hash);
|
|
||||||
}catch (Exception e){e.printStackTrace();}
|
|
||||||
}
|
|
||||||
BigDecimal filesize = BigDecimal.valueOf(file.length())
|
|
||||||
.divide(BigDecimal.valueOf(1024 * 1024), 2, RoundingMode.HALF_UP);
|
|
||||||
Long time = file.lastModified();
|
|
||||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
||||||
String filetime = format.format(time);
|
|
||||||
Map<String, Object> map = new HashMap<>();
|
|
||||||
map.put("filename", file.getName());
|
|
||||||
map.put("filepath", file.getAbsolutePath());
|
|
||||||
map.put("filesize", filesize);
|
|
||||||
map.put("filetime", filetime);
|
|
||||||
list.add(map);
|
list.add(map);
|
||||||
}
|
}
|
||||||
List<String> filenames = list.stream().map(map -> String.valueOf(map.get("filename"))).toList();
|
|
||||||
keys.forEach(key -> {
|
|
||||||
try {
|
|
||||||
if(!filenames.contains(key)){
|
|
||||||
RocksDBUtils.delete(RocksDBConfig.RocksDB_Column_Family, key);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
keys.forEach(key -> {
|
|
||||||
try {
|
|
||||||
RocksDBUtils.delete(RocksDBConfig.RocksDB_Column_Family, key);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if(StringUtils.hasText(keyboard) && !CollectionUtils.isEmpty(list)){
|
if(StringUtils.hasText(keyboard) && !CollectionUtils.isEmpty(list)){
|
||||||
list = list.stream().filter(map -> String.valueOf(map.get("filename"))
|
list = list.stream().filter(map -> String.valueOf(map.get("filename"))
|
||||||
@@ -104,7 +66,20 @@ public class DownloadAction {
|
|||||||
return mv;
|
return mv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperate(description = "StreamingResponseBody方式下载文件")
|
private static Map<String, Object> getObjectMap(File file) {
|
||||||
|
BigDecimal filesize = BigDecimal.valueOf(file.length())
|
||||||
|
.divide(BigDecimal.valueOf(1024 * 1024), 2, RoundingMode.HALF_UP);
|
||||||
|
Long time = file.lastModified();
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
String filetime = format.format(time);
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("filename", file.getName());
|
||||||
|
map.put("filepath", file.getAbsolutePath());
|
||||||
|
map.put("filesize", filesize);
|
||||||
|
map.put("filetime", filetime);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/file", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
@GetMapping(value = "/file", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
||||||
public DeferredResult<ResponseEntity<StreamingResponseBody>> downloadFileByPath(String path, Boolean temp) throws Exception {
|
public DeferredResult<ResponseEntity<StreamingResponseBody>> downloadFileByPath(String path, Boolean temp) throws Exception {
|
||||||
final File file = new File(path);
|
final File file = new File(path);
|
||||||
@@ -147,7 +122,6 @@ public class DownloadAction {
|
|||||||
|
|
||||||
@PostMapping("/packZip")
|
@PostMapping("/packZip")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@ApiOperate(description = "批量文件打包下载")
|
|
||||||
public Map<String, Object> packZip(String filenames) throws Exception{
|
public Map<String, Object> packZip(String filenames) throws Exception{
|
||||||
try {
|
try {
|
||||||
String path = OsInfoUtil.isWindows() ? windows_path :
|
String path = OsInfoUtil.isWindows() ? windows_path :
|
||||||
@@ -191,17 +165,14 @@ public class DownloadAction {
|
|||||||
|
|
||||||
@PostMapping("/delete")
|
@PostMapping("/delete")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@ApiOperate(description = "单文件删除")
|
|
||||||
public String delete(String path) throws Exception{
|
public String delete(String path) throws Exception{
|
||||||
File file = new File(path);
|
File file = new File(path);
|
||||||
RocksDBUtils.delete(RocksDBConfig.RocksDB_Column_Family, file.getName());
|
|
||||||
FileSystemUtils.deleteRecursively(file);
|
FileSystemUtils.deleteRecursively(file);
|
||||||
return "删除成功";
|
return "删除成功";
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/batchDel")
|
@PostMapping("/batchDel")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@ApiOperate(description = "批量文件删除")
|
|
||||||
public String batchDel(String filenames) throws Exception{
|
public String batchDel(String filenames) throws Exception{
|
||||||
String path = OsInfoUtil.isWindows() ? windows_path :
|
String path = OsInfoUtil.isWindows() ? windows_path :
|
||||||
OsInfoUtil.isLinux() ? linux_path : null;
|
OsInfoUtil.isLinux() ? linux_path : null;
|
||||||
@@ -213,7 +184,6 @@ public class DownloadAction {
|
|||||||
if(!Arrays.asList(filenames.split(",")).contains(file.getName())){
|
if(!Arrays.asList(filenames.split(",")).contains(file.getName())){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RocksDBUtils.delete(RocksDBConfig.RocksDB_Column_Family, file.getName());
|
|
||||||
FileSystemUtils.deleteRecursively(file);
|
FileSystemUtils.deleteRecursively(file);
|
||||||
}
|
}
|
||||||
return "删除成功";
|
return "删除成功";
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package cn.somkit.fmt.action;
|
package cn.somkit.fmt.action;
|
||||||
|
|
||||||
import cn.somkit.fmt.annotation.ApiOperate;
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package cn.somkit.fmt.action;
|
package cn.somkit.fmt.action;
|
||||||
|
|
||||||
import cn.somkit.fmt.annotation.ApiOperate;
|
import cn.somkit.fmt.entity.LoggerMessage;
|
||||||
|
import cn.somkit.fmt.utils.LoggerQueue;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/logging")
|
@RequestMapping("/logging")
|
||||||
@@ -13,4 +16,10 @@ public class LoggingAction {
|
|||||||
public String index() throws Exception{
|
public String index() throws Exception{
|
||||||
return "logging";
|
return "logging";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ResponseBody
|
||||||
|
@PostMapping("/get")
|
||||||
|
public LoggerMessage getLoggerMessage() {
|
||||||
|
return LoggerQueue.getInstance().poll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
package cn.somkit.fmt.action;
|
package cn.somkit.fmt.action;
|
||||||
|
|
||||||
import cn.somkit.fmt.annotation.ApiOperate;
|
|
||||||
import cn.somkit.fmt.config.RocksDBConfig;
|
|
||||||
import cn.somkit.fmt.utils.MD5Utils;
|
|
||||||
import cn.somkit.fmt.utils.OsInfoUtil;
|
import cn.somkit.fmt.utils.OsInfoUtil;
|
||||||
import cn.somkit.fmt.utils.RocksDBUtils;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -36,7 +31,6 @@ public class UploadAction {
|
|||||||
|
|
||||||
@PostMapping("/execute")
|
@PostMapping("/execute")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@ApiOperate(description = "文件上传")
|
|
||||||
public Map<String, Object> execute(HttpServletRequest request) throws Exception{
|
public Map<String, Object> execute(HttpServletRequest request) throws Exception{
|
||||||
//多个文件上传 就只是简单的多文件上传保存在本地的磁盘
|
//多个文件上传 就只是简单的多文件上传保存在本地的磁盘
|
||||||
if (request instanceof MultipartHttpServletRequest mrequest) {
|
if (request instanceof MultipartHttpServletRequest mrequest) {
|
||||||
@@ -67,28 +61,9 @@ public class UploadAction {
|
|||||||
assert path != null;
|
assert path != null;
|
||||||
String filePath = "";
|
String filePath = "";
|
||||||
if (file != null && file.getSize() > 0) { // 有文件上传
|
if (file != null && file.getSize() > 0) { // 有文件上传
|
||||||
String fileName = verify(file, null);// 创建文件名称
|
filePath = path + File.separator + file.getOriginalFilename();
|
||||||
if(StringUtils.hasText(fileName)){
|
File saveFile = new File(filePath) ;
|
||||||
String hash = MD5Utils.md5HashCode(file.getInputStream());
|
file.transferTo(saveFile); // 文件保存
|
||||||
RocksDBUtils.put(RocksDBConfig.RocksDB_Column_Family, fileName, hash);
|
|
||||||
filePath = path + File.separator + fileName;
|
|
||||||
File saveFile = new File(filePath) ;
|
|
||||||
file.transferTo(saveFile); // 文件保存
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String verify(MultipartFile file, String filename) throws Exception {
|
|
||||||
String key = StringUtils.hasText(filename) ? filename : Objects.requireNonNull(file.getOriginalFilename());
|
|
||||||
String hash = RocksDBUtils.get(RocksDBConfig.RocksDB_Column_Family, key);
|
|
||||||
if(!StringUtils.hasText(hash)){
|
|
||||||
return StringUtils.hasText(filename) ? filename : file.getOriginalFilename();
|
|
||||||
}
|
|
||||||
String newHash = MD5Utils.md5HashCode(file.getInputStream());
|
|
||||||
if(!hash.equals(newHash)){
|
|
||||||
String newFilename = "(1)" + file.getOriginalFilename();
|
|
||||||
return verify(file, newFilename);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
package cn.somkit.fmt.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target({ElementType.METHOD})
|
|
||||||
@Documented
|
|
||||||
public @interface ApiOperate {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 描述
|
|
||||||
*/
|
|
||||||
String description() default "";
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
package cn.somkit.fmt.annotation.aspect;
|
|
||||||
|
|
||||||
import cn.hutool.json.JSONUtil;
|
|
||||||
import cn.somkit.fmt.annotation.ApiOperate;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
|
||||||
import org.aspectj.lang.annotation.Around;
|
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
|
||||||
import org.aspectj.lang.annotation.Pointcut;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Aspect
|
|
||||||
@Component
|
|
||||||
public class ApiOperateAspect {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
||||||
|
|
||||||
/** 换行符 */
|
|
||||||
private static final String LINE_SEPARATOR = System.lineSeparator();
|
|
||||||
|
|
||||||
/** 以自定义 @ApiOperate 注解为切点 */
|
|
||||||
@Pointcut("@annotation(apiOperate)")
|
|
||||||
public void ApiOperate(ApiOperate apiOperate) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 环绕注入
|
|
||||||
* @param joinPoint
|
|
||||||
* @param apiOperate
|
|
||||||
* @return
|
|
||||||
* @throws Throwable
|
|
||||||
*/
|
|
||||||
@Around(value = "ApiOperate(apiOperate)", argNames = "joinPoint,apiOperate")
|
|
||||||
public Object doAround(ProceedingJoinPoint joinPoint, ApiOperate apiOperate) throws Throwable {
|
|
||||||
long startTime = System.currentTimeMillis();
|
|
||||||
Object result = joinPoint.proceed();
|
|
||||||
|
|
||||||
// 开始打印请求日志
|
|
||||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
|
||||||
assert attributes != null;
|
|
||||||
HttpServletRequest request = attributes.getRequest();
|
|
||||||
|
|
||||||
long timeConsuming = System.currentTimeMillis() - startTime;
|
|
||||||
|
|
||||||
// 打印请求相关参数
|
|
||||||
logger.info("========================================== Start ==========================================");
|
|
||||||
// 打印请求 url
|
|
||||||
logger.info("URL : {}", request.getRequestURL().toString());
|
|
||||||
// 打印描述信息
|
|
||||||
logger.info("Description : {}", apiOperate.description());
|
|
||||||
// 打印 Http method
|
|
||||||
logger.info("HTTP Method : {}", request.getMethod());
|
|
||||||
// 打印调用 controller 的全路径以及执行方法
|
|
||||||
logger.info("Class Method : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
|
|
||||||
// 打印请求的 IP
|
|
||||||
logger.info("IP : {}", request.getRemoteAddr());
|
|
||||||
// 打印请求Headers
|
|
||||||
logger.info("Header Args : {}", headers(request));
|
|
||||||
// 打印请求入参
|
|
||||||
logger.info("Request Args : {}", Arrays.toString(joinPoint.getArgs()));
|
|
||||||
// 打印出参
|
|
||||||
logger.info("Response Args : {}", JSONUtil.toJsonStr(result));
|
|
||||||
// 执行耗时
|
|
||||||
logger.info("Time-Consuming : {} ms", timeConsuming);
|
|
||||||
// 接口结束后换行,方便分割查看
|
|
||||||
logger.info("=========================================== End ===========================================" + LINE_SEPARATOR);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有header参数
|
|
||||||
* @param request
|
|
||||||
* @return Map<String, String> headers
|
|
||||||
*/
|
|
||||||
private Map<String, String> headers(HttpServletRequest request){
|
|
||||||
Map<String, String> headerMap = new HashMap<>();
|
|
||||||
Enumeration<String> enumeration = request.getHeaderNames();
|
|
||||||
while (enumeration.hasMoreElements()) {
|
|
||||||
String name = enumeration.nextElement();
|
|
||||||
String value = request.getHeader(name);
|
|
||||||
headerMap.put(name, value);
|
|
||||||
}
|
|
||||||
return headerMap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package cn.somkit.fmt.config;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class RocksDBConfig {
|
|
||||||
|
|
||||||
public static String RocksDB_Path_Windows = "D://RocksDB";
|
|
||||||
|
|
||||||
public static String RocksDB_Path_Linux = "/usr/local/rocksdb";
|
|
||||||
|
|
||||||
public static String RocksDB_Column_Family = "default";
|
|
||||||
|
|
||||||
@Value("${somkit.db.rocks.path.windows}")
|
|
||||||
public void setRocksDB_Path_Windows(String rocksDB_Path_Windows) {
|
|
||||||
if(StringUtils.hasText(rocksDB_Path_Windows)){
|
|
||||||
RocksDB_Path_Windows = rocksDB_Path_Windows;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Value("${somkit.db.rocks.path.linux}")
|
|
||||||
public void setRocksDB_Path_Linux(String rocksDB_Path_Linux) {
|
|
||||||
if(StringUtils.hasText(rocksDB_Path_Linux)){
|
|
||||||
RocksDB_Path_Linux = rocksDB_Path_Linux;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Value("${somkit.db.rocks.column-family}")
|
|
||||||
public void setRocksDB_Column_Family(String rocksDB_Column_Family){
|
|
||||||
if(StringUtils.hasText(rocksDB_Column_Family)){
|
|
||||||
RocksDB_Column_Family = rocksDB_Column_Family;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package cn.somkit.fmt.config;
|
|
||||||
|
|
||||||
import cn.somkit.fmt.entity.LoggerMessage;
|
|
||||||
import cn.somkit.fmt.utils.ApplicationContextProvider;
|
|
||||||
import cn.somkit.fmt.utils.LoggerQueue;
|
|
||||||
import jakarta.annotation.PostConstruct;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
|
||||||
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
|
|
||||||
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
|
|
||||||
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
|
|
||||||
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableWebSocketMessageBroker
|
|
||||||
public class WebSocketLogConfig implements WebSocketMessageBrokerConfigurer {
|
|
||||||
|
|
||||||
/* 不再通过构造函数注入,而是第一次使用时再拿 */
|
|
||||||
private volatile SimpMessagingTemplate template;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
|
||||||
registry.addEndpoint("/ws-logs").setAllowedOriginPatterns("*").withSockJS();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void configureMessageBroker(MessageBrokerRegistry config) {
|
|
||||||
config.enableSimpleBroker("/topic");
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void startPush() {
|
|
||||||
new Thread(() -> {
|
|
||||||
while (true) {
|
|
||||||
LoggerMessage log = LoggerQueue.getInstance().poll();
|
|
||||||
if (log != null) {
|
|
||||||
if (template == null) {
|
|
||||||
// 延迟获取
|
|
||||||
template = ApplicationContextProvider.getBean(SimpMessagingTemplate.class);
|
|
||||||
}
|
|
||||||
template.convertAndSend("/topic/logs", log);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, "log-push").start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package cn.somkit.fmt.filter;
|
package cn.somkit.fmt.filter;
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.Level;
|
||||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
import ch.qos.logback.core.filter.Filter;
|
import ch.qos.logback.core.filter.Filter;
|
||||||
import ch.qos.logback.core.spi.FilterReply;
|
import ch.qos.logback.core.spi.FilterReply;
|
||||||
@@ -11,15 +12,35 @@ import java.time.ZoneId;
|
|||||||
|
|
||||||
public class LogStashFilter extends Filter<ILoggingEvent> {
|
public class LogStashFilter extends Filter<ILoggingEvent> {
|
||||||
|
|
||||||
|
Level level;
|
||||||
|
|
||||||
|
public LogStashFilter() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FilterReply decide(ILoggingEvent e) {
|
public FilterReply decide(ILoggingEvent e) {
|
||||||
LoggerMessage msg = new LoggerMessage(
|
if (!this.isStarted()) {
|
||||||
e.getLevel().toString(),
|
return FilterReply.NEUTRAL;
|
||||||
e.getLoggerName(),
|
} else {
|
||||||
e.getFormattedMessage(),
|
LoggerMessage msg = new LoggerMessage(
|
||||||
Instant.ofEpochMilli(e.getTimeStamp()).atZone(ZoneId.systemDefault()).toLocalDateTime()
|
e.getLevel().toString(),
|
||||||
);
|
e.getLoggerName(),
|
||||||
LoggerQueue.getInstance().push(msg); // 单例阻塞队列
|
e.getFormattedMessage(),
|
||||||
return FilterReply.ACCEPT;
|
Instant.ofEpochMilli(e.getTimeStamp()).atZone(ZoneId.systemDefault()).toLocalDateTime()
|
||||||
|
);
|
||||||
|
LoggerQueue.getInstance().push(msg); // 单例阻塞队列
|
||||||
|
return e.getLevel().isGreaterOrEqual(this.level) ? FilterReply.NEUTRAL : FilterReply.DENY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLevel(String level) {
|
||||||
|
this.level = Level.toLevel(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
if (this.level != null) {
|
||||||
|
super.start();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,235 +0,0 @@
|
|||||||
package cn.somkit.fmt.utils;
|
|
||||||
|
|
||||||
import cn.somkit.fmt.config.RocksDBConfig;
|
|
||||||
import org.rocksdb.*;
|
|
||||||
import org.springframework.util.ObjectUtils;
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.IntStream;
|
|
||||||
|
|
||||||
public class RocksDBUtils {
|
|
||||||
|
|
||||||
private static RocksDB rocksDB;
|
|
||||||
public static ConcurrentMap<String, ColumnFamilyHandle> columnFamilyHandleMap = new ConcurrentHashMap<>();
|
|
||||||
public static int GET_KEYS_BATCH_SIZE = 100000;
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
String rocksDBPath = null; //RocksDB文件目录
|
|
||||||
if (OsInfoUtil.isWindows()) {
|
|
||||||
rocksDBPath = RocksDBConfig.RocksDB_Path_Windows; // 指定windows系统下RocksDB文件目录
|
|
||||||
} else if(OsInfoUtil.isLinux()){
|
|
||||||
rocksDBPath = RocksDBConfig.RocksDB_Path_Linux; // 指定linux系统下RocksDB文件目录
|
|
||||||
}
|
|
||||||
RocksDB.loadLibrary();
|
|
||||||
Options options = new Options();
|
|
||||||
options.setCreateIfMissing(true); //如果数据库不存在则创建
|
|
||||||
List<byte[]> cfArr = RocksDB.listColumnFamilies(options, rocksDBPath); // 初始化所有已存在列族
|
|
||||||
List<ColumnFamilyDescriptor> columnFamilyDescriptors = new ArrayList<>(); //ColumnFamilyDescriptor集合
|
|
||||||
if (!ObjectUtils.isEmpty(cfArr)) {
|
|
||||||
for (byte[] cf : cfArr) {
|
|
||||||
columnFamilyDescriptors.add(new ColumnFamilyDescriptor(cf, new ColumnFamilyOptions()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
columnFamilyDescriptors.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, new ColumnFamilyOptions()));
|
|
||||||
}
|
|
||||||
DBOptions dbOptions = new DBOptions();
|
|
||||||
dbOptions.setCreateIfMissing(true);
|
|
||||||
List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>(); //ColumnFamilyHandle集合
|
|
||||||
rocksDB = RocksDB.open(dbOptions, rocksDBPath, columnFamilyDescriptors, columnFamilyHandles);
|
|
||||||
for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
|
|
||||||
ColumnFamilyHandle columnFamilyHandle = columnFamilyHandles.get(i);
|
|
||||||
String cfName = new String(columnFamilyDescriptors.get(i).getName(), StandardCharsets.UTF_8);
|
|
||||||
columnFamilyHandleMap.put(cfName, columnFamilyHandle);
|
|
||||||
}
|
|
||||||
System.out.println("RocksDB init success!! path:" + rocksDBPath);
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.out.println("RocksDB init failure!! error:" + e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private RocksDBUtils(){}
|
|
||||||
|
|
||||||
public static ColumnFamilyHandle cfAddIfNotExist(String cfName) throws RocksDBException {
|
|
||||||
ColumnFamilyHandle columnFamilyHandle;
|
|
||||||
if (!columnFamilyHandleMap.containsKey(cfName)) {
|
|
||||||
columnFamilyHandle = rocksDB.createColumnFamily(new ColumnFamilyDescriptor(cfName.getBytes(), new ColumnFamilyOptions()));
|
|
||||||
columnFamilyHandleMap.put(cfName, columnFamilyHandle);
|
|
||||||
System.out.println("cfAddIfNotExist success!! cfName:" + cfName);
|
|
||||||
} else {
|
|
||||||
columnFamilyHandle = columnFamilyHandleMap.get(cfName);
|
|
||||||
}
|
|
||||||
return columnFamilyHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 列族,删除(如果存在)
|
|
||||||
*/
|
|
||||||
public static void cfDeleteIfExist(String cfName) throws RocksDBException {
|
|
||||||
if (columnFamilyHandleMap.containsKey(cfName)) {
|
|
||||||
rocksDB.dropColumnFamily(columnFamilyHandleMap.get(cfName));
|
|
||||||
columnFamilyHandleMap.remove(cfName);
|
|
||||||
System.out.println("cfDeleteIfExist success!! cfName:" + cfName);
|
|
||||||
} else {
|
|
||||||
System.out.println("cfDeleteIfExist containsKey!! cfName:" + cfName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 增
|
|
||||||
*/
|
|
||||||
public static void put(String cfName, String key, String value) throws RocksDBException {
|
|
||||||
ColumnFamilyHandle columnFamilyHandle = cfAddIfNotExist(cfName); //获取列族Handle
|
|
||||||
rocksDB.put(columnFamilyHandle, key.getBytes(), value.getBytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 增(批量)
|
|
||||||
*/
|
|
||||||
public static void batchPut(String cfName, Map<String, String> map) throws RocksDBException {
|
|
||||||
ColumnFamilyHandle columnFamilyHandle = cfAddIfNotExist(cfName); //获取列族Handle
|
|
||||||
WriteOptions writeOptions = new WriteOptions();
|
|
||||||
WriteBatch writeBatch = new WriteBatch();
|
|
||||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
|
||||||
writeBatch.put(columnFamilyHandle, entry.getKey().getBytes(), entry.getValue().getBytes());
|
|
||||||
}
|
|
||||||
rocksDB.write(writeOptions, writeBatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删
|
|
||||||
*/
|
|
||||||
public static void delete(String cfName, String key) throws RocksDBException {
|
|
||||||
ColumnFamilyHandle columnFamilyHandle = cfAddIfNotExist(cfName); //获取列族Handle
|
|
||||||
rocksDB.delete(columnFamilyHandle, key.getBytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查
|
|
||||||
*/
|
|
||||||
public static String get(String cfName, String key) throws RocksDBException {
|
|
||||||
String value = null;
|
|
||||||
ColumnFamilyHandle columnFamilyHandle = cfAddIfNotExist(cfName); //获取列族Handle
|
|
||||||
byte[] bytes = rocksDB.get(columnFamilyHandle, key.getBytes());
|
|
||||||
if (!ObjectUtils.isEmpty(bytes)) {
|
|
||||||
value = new String(bytes, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查(多个键值对)
|
|
||||||
*/
|
|
||||||
public static Map<String, String> multiGetAsMap(String cfName, List<String> keys) throws RocksDBException {
|
|
||||||
Map<String, String> map = new HashMap<>(keys.size());
|
|
||||||
ColumnFamilyHandle columnFamilyHandle = cfAddIfNotExist(cfName); //获取列族Handle
|
|
||||||
List<ColumnFamilyHandle> columnFamilyHandles;
|
|
||||||
List<byte[]> keyBytes = keys.stream().map(String::getBytes).collect(Collectors.toList());
|
|
||||||
columnFamilyHandles = IntStream.range(0, keys.size()).mapToObj(i -> columnFamilyHandle).collect(Collectors.toList());
|
|
||||||
List<byte[]> bytes = rocksDB.multiGetAsList(columnFamilyHandles, keyBytes);
|
|
||||||
for (int i = 0; i < bytes.size(); i++) {
|
|
||||||
byte[] valueBytes = bytes.get(i);
|
|
||||||
String value = "";
|
|
||||||
if (!ObjectUtils.isEmpty(valueBytes)) {
|
|
||||||
value = new String(valueBytes, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
map.put(keys.get(i), value);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查(多个值)
|
|
||||||
*/
|
|
||||||
public static List<String> multiGetValueAsList(String cfName, List<String> keys) throws RocksDBException {
|
|
||||||
List<String> values = new ArrayList<>(keys.size());
|
|
||||||
ColumnFamilyHandle columnFamilyHandle = cfAddIfNotExist(cfName); //获取列族Handle
|
|
||||||
List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
|
|
||||||
List<byte[]> keyBytes = keys.stream().map(String::getBytes).collect(Collectors.toList());
|
|
||||||
for (int i = 0; i < keys.size(); i++) {
|
|
||||||
columnFamilyHandles.add(columnFamilyHandle);
|
|
||||||
}
|
|
||||||
List<byte[]> bytes = rocksDB.multiGetAsList(columnFamilyHandles, keyBytes);
|
|
||||||
for (byte[] valueBytes : bytes) {
|
|
||||||
String value = "";
|
|
||||||
if (!ObjectUtils.isEmpty(valueBytes)) {
|
|
||||||
value = new String(valueBytes, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
values.add(value);
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查(所有键)
|
|
||||||
*/
|
|
||||||
public static List<String> getAllKey(String cfName) throws RocksDBException {
|
|
||||||
List<String> list = new ArrayList<>();
|
|
||||||
ColumnFamilyHandle columnFamilyHandle = cfAddIfNotExist(cfName); //获取列族Handle
|
|
||||||
try (RocksIterator rocksIterator = rocksDB.newIterator(columnFamilyHandle)) {
|
|
||||||
for (rocksIterator.seekToFirst(); rocksIterator.isValid(); rocksIterator.next()) {
|
|
||||||
list.add(new String(rocksIterator.key(), StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分片查(键)
|
|
||||||
*/
|
|
||||||
public static List<String> getKeysFrom(String cfName, String lastKey) throws RocksDBException {
|
|
||||||
List<String> list = new ArrayList<>(GET_KEYS_BATCH_SIZE);
|
|
||||||
// 获取列族Handle
|
|
||||||
ColumnFamilyHandle columnFamilyHandle = cfAddIfNotExist(cfName);
|
|
||||||
try (RocksIterator rocksIterator = rocksDB.newIterator(columnFamilyHandle)) {
|
|
||||||
if (lastKey != null) {
|
|
||||||
rocksIterator.seek(lastKey.getBytes(StandardCharsets.UTF_8));
|
|
||||||
rocksIterator.next();
|
|
||||||
} else {
|
|
||||||
rocksIterator.seekToFirst();
|
|
||||||
}
|
|
||||||
// 一批次最多 GET_KEYS_BATCH_SIZE 个 key
|
|
||||||
while (rocksIterator.isValid() && list.size() < GET_KEYS_BATCH_SIZE) {
|
|
||||||
list.add(new String(rocksIterator.key(), StandardCharsets.UTF_8));
|
|
||||||
rocksIterator.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查(所有键值)
|
|
||||||
*/
|
|
||||||
public static Map<String, String> getAll(String cfName) throws RocksDBException {
|
|
||||||
Map<String, String> map = new HashMap<>();
|
|
||||||
ColumnFamilyHandle columnFamilyHandle = cfAddIfNotExist(cfName); //获取列族Handle
|
|
||||||
try (RocksIterator rocksIterator = rocksDB.newIterator(columnFamilyHandle)) {
|
|
||||||
for (rocksIterator.seekToFirst(); rocksIterator.isValid(); rocksIterator.next()) {
|
|
||||||
map.put(new String(rocksIterator.key(), StandardCharsets.UTF_8), new String(rocksIterator.value(), StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查总条数
|
|
||||||
*/
|
|
||||||
public static int getCount(String cfName) throws RocksDBException {
|
|
||||||
int count = 0;
|
|
||||||
ColumnFamilyHandle columnFamilyHandle = cfAddIfNotExist(cfName); //获取列族Handle
|
|
||||||
try (RocksIterator rocksIterator = rocksDB.newIterator(columnFamilyHandle)) {
|
|
||||||
for (rocksIterator.seekToFirst(); rocksIterator.isValid(); rocksIterator.next()) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,18 +15,52 @@ spring:
|
|||||||
multipart:
|
multipart:
|
||||||
max-file-size: 1024MB
|
max-file-size: 1024MB
|
||||||
max-request-size: 10240MB
|
max-request-size: 10240MB
|
||||||
|
threads:
|
||||||
|
virtual:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
somkit:
|
somkit:
|
||||||
upload:
|
upload:
|
||||||
path:
|
path:
|
||||||
windows: D://data/install/upload
|
windows: D://data/install/upload
|
||||||
linux: /mnt/files
|
linux: /mnt/files
|
||||||
db:
|
|
||||||
rocks:
|
|
||||||
path:
|
|
||||||
windows: D://RocksDB//fmt
|
|
||||||
linux: /usr/local/rocksdb/fmt
|
|
||||||
column-family: default
|
|
||||||
|
|
||||||
logging:
|
logging:
|
||||||
config: classpath:logback-spring.xml
|
config: classpath:logback-spring.xml
|
||||||
|
|
||||||
|
metona:
|
||||||
|
cache:
|
||||||
|
# 缓存类型,支持以下类型:
|
||||||
|
# - CONCURRENT_HASH_MAP: 基于 ConcurrentHashMap 的线程安全缓存
|
||||||
|
# - WEAK_HASH_MAP: 基于 WeakHashMap 的弱引用缓存
|
||||||
|
# - LINKED_HASH_MAP: 基于 LinkedHashMap 的 LRU 缓存
|
||||||
|
type: LINKED_HASH_MAP
|
||||||
|
|
||||||
|
# 缓存的初始容量,默认值为 16
|
||||||
|
initial-capacity: 128
|
||||||
|
|
||||||
|
# 缓存的最大容量,当缓存条目数超过该值时,会根据策略移除旧条目
|
||||||
|
# 仅对 LINKED_HASH_MAP 类型有效
|
||||||
|
maximum-size: 2000
|
||||||
|
|
||||||
|
# 写入后过期时间(单位由 time-unit 指定)
|
||||||
|
# 默认值为 -1,表示永不过期
|
||||||
|
expire-after-write: -1
|
||||||
|
|
||||||
|
# 访问后过期时间(单位由 time-unit 指定)
|
||||||
|
# 默认值为 -1,表示永不过期
|
||||||
|
expire-after-access: -1
|
||||||
|
|
||||||
|
# 时间单位,支持以下值:
|
||||||
|
# - NANOSECONDS: 纳秒
|
||||||
|
# - MICROSECONDS: 微秒
|
||||||
|
# - MILLISECONDS: 毫秒(默认)
|
||||||
|
# - SECONDS: 秒
|
||||||
|
# - MINUTES: 分钟
|
||||||
|
# - HOURS: 小时
|
||||||
|
# - DAYS: 天
|
||||||
|
time-unit: MILLISECONDS
|
||||||
|
|
||||||
|
# 是否记录缓存统计信息(如命中率、加载次数等)
|
||||||
|
# 默认值为 false
|
||||||
|
record-stats: true
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<level>DEBUG</level>
|
<level>DEBUG</level>
|
||||||
</filter>
|
</filter>
|
||||||
<filter class="cn.somkit.fmt.filter.LogStashFilter">
|
<filter class="cn.somkit.fmt.filter.LogStashFilter">
|
||||||
|
<level>DEBUG</level>
|
||||||
</filter>
|
</filter>
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
||||||
|
|||||||
@@ -40,6 +40,12 @@ class LogMonitorAdaptive {
|
|||||||
enableFontSize: true, // 是否提供“字体大小 +/-”按钮
|
enableFontSize: true, // 是否提供“字体大小 +/-”按钮
|
||||||
enableWordWrap: true, // 是否提供“换行/不换行”切换按钮
|
enableWordWrap: true, // 是否提供“换行/不换行”切换按钮
|
||||||
|
|
||||||
|
/* --- 暂停/继续 的回调函数 --- */
|
||||||
|
onTogglePause: () => {},
|
||||||
|
|
||||||
|
/* --- 创建完成 的回调函数 --- */
|
||||||
|
onCreated: () => {},
|
||||||
|
|
||||||
...opts
|
...opts
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -59,6 +65,11 @@ class LogMonitorAdaptive {
|
|||||||
this.initDOM();
|
this.initDOM();
|
||||||
this.bindResize();
|
this.bindResize();
|
||||||
this.bindGlobalEvents();
|
this.bindGlobalEvents();
|
||||||
|
|
||||||
|
//执行回调函数
|
||||||
|
if(this.cfg.onCreated && typeof this.cfg.onCreated === 'function'){
|
||||||
|
this.cfg.onCreated();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------ 初始化 ------------------------ */
|
/* ------------------------ 初始化 ------------------------ */
|
||||||
@@ -332,6 +343,10 @@ class LogMonitorAdaptive {
|
|||||||
this.pauseBtn.style.backgroundColor = this.isPaused
|
this.pauseBtn.style.backgroundColor = this.isPaused
|
||||||
? (this.cfg.theme === 'dark' ? '#d32f2f' : '#ff5252')
|
? (this.cfg.theme === 'dark' ? '#d32f2f' : '#ff5252')
|
||||||
: (this.cfg.theme === 'dark' ? '#444' : '#e7e7e7');
|
: (this.cfg.theme === 'dark' ? '#444' : '#e7e7e7');
|
||||||
|
//执行回调函数
|
||||||
|
if(this.cfg.onTogglePause && typeof this.cfg.onTogglePause === 'function'){
|
||||||
|
this.cfg.onTogglePause(this.isPaused);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleTheme() {
|
toggleTheme() {
|
||||||
|
|||||||
@@ -15,9 +15,8 @@
|
|||||||
<body>
|
<body>
|
||||||
<!-- 日志容器 -->
|
<!-- 日志容器 -->
|
||||||
<div id="logContainer"></div>
|
<div id="logContainer"></div>
|
||||||
|
<script th:src="@{/common/js/basic.js}" type="text/javascript" charset="utf-8"></script>
|
||||||
<script th:src="@{/common/js/LogMonitorAdaptive.js}" type="text/javascript" charset="utf-8"></script>
|
<script th:src="@{/common/js/LogMonitorAdaptive.js}" type="text/javascript" charset="utf-8"></script>
|
||||||
<script th:src="@{/common/js/sockjs.js}" type="text/javascript" charset="utf-8"></script>
|
|
||||||
<script th:src="@{/common/js/stomp.js}" type="text/javascript" charset="utf-8"></script>
|
|
||||||
<script type="text/javascript" th:inline="javascript" charset="utf-8">
|
<script type="text/javascript" th:inline="javascript" charset="utf-8">
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
const logger = new LogMonitorAdaptive('#logContainer', {
|
const logger = new LogMonitorAdaptive('#logContainer', {
|
||||||
@@ -35,16 +34,24 @@
|
|||||||
enableWordWrap: true,
|
enableWordWrap: true,
|
||||||
showTimestamp: true, // 是否显示时间戳
|
showTimestamp: true, // 是否显示时间戳
|
||||||
showLevel: true, // 是否显示日志级别标签
|
showLevel: true, // 是否显示日志级别标签
|
||||||
});
|
//暂停/继续 回调函数
|
||||||
|
onTogglePause: (isPaused) => {
|
||||||
const socket = new SockJS('/fmt/ws-logs');
|
console.log(isPaused ? '暂停' : '继续');
|
||||||
const stomp = Stomp.over(socket);
|
},
|
||||||
stomp.connect({}, () => {
|
onCreated: () => {
|
||||||
stomp.subscribe('/topic/logs', (payload) => {
|
console.log('日志容器已创建');
|
||||||
const log = JSON.parse(payload.body);
|
let index = setInterval(() => {
|
||||||
console.log(log);
|
const options = {
|
||||||
logger.log(log.message, log.level);
|
url: Fmt.ctx() + '/logging/get',
|
||||||
});
|
data: {},
|
||||||
|
method: 'post'
|
||||||
|
};
|
||||||
|
Fmt.axios(options).then((result) => {
|
||||||
|
console.log(result);
|
||||||
|
logger.log(result.message, result.level);
|
||||||
|
}).catch((err) => clearInterval(index));
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
<span class="ax-line"></span>
|
<span class="ax-line"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ax-item">
|
<div class="ax-item">
|
||||||
<a th:href="@{/logging/index}" class="ax-text">在线日志</a>
|
<a th:href="@{/logging/index}" target="_blank" class="ax-text">在线日志</a>
|
||||||
<span class="ax-line"></span>
|
<span class="ax-line"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package cn.somkit.fmt;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
|
|
||||||
@SpringBootTest
|
|
||||||
class FmtApplicationTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void contextLoads() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user