diff --git a/pom.xml b/pom.xml index a6a8cae..17811bb 100644 --- a/pom.xml +++ b/pom.xml @@ -17,41 +17,33 @@ 21 + + + metona-maven + https://gitee.com/thzxx/maven/raw/master + + + org.springframework.boot spring-boot-starter-web - - org.springframework.boot - spring-boot-starter-test - test - org.springframework.boot spring-boot-starter-thymeleaf - - org.springframework.boot - spring-boot-starter-websocket - - - - org.aspectj - aspectjweaver - 1.9.7 - - - - org.rocksdb - rocksdbjni - 8.3.2 - cn.hutool hutool-json - 5.8.21 + 5.8.25 + + + + cn.metona + metona-cache-spring-boot-starter + 1.0.0 diff --git a/src/main/java/cn/somkit/fmt/action/DownloadAction.java b/src/main/java/cn/somkit/fmt/action/DownloadAction.java index a59f015..0c1762a 100644 --- a/src/main/java/cn/somkit/fmt/action/DownloadAction.java +++ b/src/main/java/cn/somkit/fmt/action/DownloadAction.java @@ -1,11 +1,6 @@ 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.RocksDBUtils; -import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -50,48 +45,15 @@ public class DownloadAction { File folder = new File(path); File[] listOfFiles = folder.listFiles(); List> list = new ArrayList<>(); - List keys = RocksDBUtils.getAllKey(RocksDBConfig.RocksDB_Column_Family); + if(listOfFiles != null){ for (File file : listOfFiles) { if(!file.isFile()){ continue; } - if(!keys.contains(file.getName())){ - 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 map = new HashMap<>(); - map.put("filename", file.getName()); - map.put("filepath", file.getAbsolutePath()); - map.put("filesize", filesize); - map.put("filetime", filetime); + Map map = getObjectMap(file); list.add(map); } - List 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)){ list = list.stream().filter(map -> String.valueOf(map.get("filename")) @@ -104,7 +66,20 @@ public class DownloadAction { return mv; } - @ApiOperate(description = "StreamingResponseBody方式下载文件") + private static Map 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 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) public DeferredResult> downloadFileByPath(String path, Boolean temp) throws Exception { final File file = new File(path); @@ -147,7 +122,6 @@ public class DownloadAction { @PostMapping("/packZip") @ResponseBody - @ApiOperate(description = "批量文件打包下载") public Map packZip(String filenames) throws Exception{ try { String path = OsInfoUtil.isWindows() ? windows_path : @@ -191,17 +165,14 @@ public class DownloadAction { @PostMapping("/delete") @ResponseBody - @ApiOperate(description = "单文件删除") public String delete(String path) throws Exception{ File file = new File(path); - RocksDBUtils.delete(RocksDBConfig.RocksDB_Column_Family, file.getName()); FileSystemUtils.deleteRecursively(file); return "删除成功"; } @PostMapping("/batchDel") @ResponseBody - @ApiOperate(description = "批量文件删除") public String batchDel(String filenames) throws Exception{ String path = OsInfoUtil.isWindows() ? windows_path : OsInfoUtil.isLinux() ? linux_path : null; @@ -213,7 +184,6 @@ public class DownloadAction { if(!Arrays.asList(filenames.split(",")).contains(file.getName())){ continue; } - RocksDBUtils.delete(RocksDBConfig.RocksDB_Column_Family, file.getName()); FileSystemUtils.deleteRecursively(file); } return "删除成功"; diff --git a/src/main/java/cn/somkit/fmt/action/IndexAction.java b/src/main/java/cn/somkit/fmt/action/IndexAction.java index 9d7a52a..d90d530 100644 --- a/src/main/java/cn/somkit/fmt/action/IndexAction.java +++ b/src/main/java/cn/somkit/fmt/action/IndexAction.java @@ -1,6 +1,5 @@ package cn.somkit.fmt.action; -import cn.somkit.fmt.annotation.ApiOperate; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; diff --git a/src/main/java/cn/somkit/fmt/action/LoggingAction.java b/src/main/java/cn/somkit/fmt/action/LoggingAction.java index 41f2720..f6dd35d 100644 --- a/src/main/java/cn/somkit/fmt/action/LoggingAction.java +++ b/src/main/java/cn/somkit/fmt/action/LoggingAction.java @@ -1,9 +1,12 @@ 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.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/logging") @@ -13,4 +16,10 @@ public class LoggingAction { public String index() throws Exception{ return "logging"; } + + @ResponseBody + @PostMapping("/get") + public LoggerMessage getLoggerMessage() { + return LoggerQueue.getInstance().poll(); + } } diff --git a/src/main/java/cn/somkit/fmt/action/UploadAction.java b/src/main/java/cn/somkit/fmt/action/UploadAction.java index 249b33d..2014d39 100644 --- a/src/main/java/cn/somkit/fmt/action/UploadAction.java +++ b/src/main/java/cn/somkit/fmt/action/UploadAction.java @@ -1,14 +1,9 @@ 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.RocksDBUtils; import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -36,7 +31,6 @@ public class UploadAction { @PostMapping("/execute") @ResponseBody - @ApiOperate(description = "文件上传") public Map execute(HttpServletRequest request) throws Exception{ //多个文件上传 就只是简单的多文件上传保存在本地的磁盘 if (request instanceof MultipartHttpServletRequest mrequest) { @@ -67,28 +61,9 @@ public class UploadAction { assert path != null; String filePath = ""; if (file != null && file.getSize() > 0) { // 有文件上传 - String fileName = verify(file, null);// 创建文件名称 - if(StringUtils.hasText(fileName)){ - String hash = MD5Utils.md5HashCode(file.getInputStream()); - RocksDBUtils.put(RocksDBConfig.RocksDB_Column_Family, fileName, hash); - filePath = path + File.separator + fileName; - File saveFile = new File(filePath) ; - file.transferTo(saveFile); // 文件保存 - } + filePath = path + File.separator + file.getOriginalFilename(); + 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; - } } diff --git a/src/main/java/cn/somkit/fmt/annotation/ApiOperate.java b/src/main/java/cn/somkit/fmt/annotation/ApiOperate.java deleted file mode 100644 index 957ec89..0000000 --- a/src/main/java/cn/somkit/fmt/annotation/ApiOperate.java +++ /dev/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 ""; -} diff --git a/src/main/java/cn/somkit/fmt/annotation/aspect/ApiOperateAspect.java b/src/main/java/cn/somkit/fmt/annotation/aspect/ApiOperateAspect.java deleted file mode 100644 index 1229765..0000000 --- a/src/main/java/cn/somkit/fmt/annotation/aspect/ApiOperateAspect.java +++ /dev/null @@ -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 headers - */ - private Map headers(HttpServletRequest request){ - Map headerMap = new HashMap<>(); - Enumeration enumeration = request.getHeaderNames(); - while (enumeration.hasMoreElements()) { - String name = enumeration.nextElement(); - String value = request.getHeader(name); - headerMap.put(name, value); - } - return headerMap; - } -} diff --git a/src/main/java/cn/somkit/fmt/config/RocksDBConfig.java b/src/main/java/cn/somkit/fmt/config/RocksDBConfig.java deleted file mode 100644 index 461dcbd..0000000 --- a/src/main/java/cn/somkit/fmt/config/RocksDBConfig.java +++ /dev/null @@ -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; - } - } -} diff --git a/src/main/java/cn/somkit/fmt/config/WebSocketLogConfig.java b/src/main/java/cn/somkit/fmt/config/WebSocketLogConfig.java deleted file mode 100644 index c69ad9b..0000000 --- a/src/main/java/cn/somkit/fmt/config/WebSocketLogConfig.java +++ /dev/null @@ -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(); - } -} diff --git a/src/main/java/cn/somkit/fmt/filter/LogStashFilter.java b/src/main/java/cn/somkit/fmt/filter/LogStashFilter.java index 5472311..5bc65e2 100644 --- a/src/main/java/cn/somkit/fmt/filter/LogStashFilter.java +++ b/src/main/java/cn/somkit/fmt/filter/LogStashFilter.java @@ -1,5 +1,6 @@ package cn.somkit.fmt.filter; +import ch.qos.logback.classic.Level; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.filter.Filter; import ch.qos.logback.core.spi.FilterReply; @@ -11,15 +12,35 @@ import java.time.ZoneId; public class LogStashFilter extends Filter { + Level level; + + public LogStashFilter() { + } + @Override public FilterReply decide(ILoggingEvent e) { - LoggerMessage msg = new LoggerMessage( - e.getLevel().toString(), - e.getLoggerName(), - e.getFormattedMessage(), - Instant.ofEpochMilli(e.getTimeStamp()).atZone(ZoneId.systemDefault()).toLocalDateTime() - ); - LoggerQueue.getInstance().push(msg); // 单例阻塞队列 - return FilterReply.ACCEPT; + if (!this.isStarted()) { + return FilterReply.NEUTRAL; + } else { + LoggerMessage msg = new LoggerMessage( + e.getLevel().toString(), + e.getLoggerName(), + e.getFormattedMessage(), + 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(); + } + } } diff --git a/src/main/java/cn/somkit/fmt/utils/RocksDBUtils.java b/src/main/java/cn/somkit/fmt/utils/RocksDBUtils.java deleted file mode 100644 index 9259530..0000000 --- a/src/main/java/cn/somkit/fmt/utils/RocksDBUtils.java +++ /dev/null @@ -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 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 cfArr = RocksDB.listColumnFamilies(options, rocksDBPath); // 初始化所有已存在列族 - List 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 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 map) throws RocksDBException { - ColumnFamilyHandle columnFamilyHandle = cfAddIfNotExist(cfName); //获取列族Handle - WriteOptions writeOptions = new WriteOptions(); - WriteBatch writeBatch = new WriteBatch(); - for (Map.Entry 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 multiGetAsMap(String cfName, List keys) throws RocksDBException { - Map map = new HashMap<>(keys.size()); - ColumnFamilyHandle columnFamilyHandle = cfAddIfNotExist(cfName); //获取列族Handle - List columnFamilyHandles; - List keyBytes = keys.stream().map(String::getBytes).collect(Collectors.toList()); - columnFamilyHandles = IntStream.range(0, keys.size()).mapToObj(i -> columnFamilyHandle).collect(Collectors.toList()); - List 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 multiGetValueAsList(String cfName, List keys) throws RocksDBException { - List values = new ArrayList<>(keys.size()); - ColumnFamilyHandle columnFamilyHandle = cfAddIfNotExist(cfName); //获取列族Handle - List columnFamilyHandles = new ArrayList<>(); - List keyBytes = keys.stream().map(String::getBytes).collect(Collectors.toList()); - for (int i = 0; i < keys.size(); i++) { - columnFamilyHandles.add(columnFamilyHandle); - } - List 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 getAllKey(String cfName) throws RocksDBException { - List 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 getKeysFrom(String cfName, String lastKey) throws RocksDBException { - List 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 getAll(String cfName) throws RocksDBException { - Map 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; - } -} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ccf5ed9..4fbcfbc 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -15,18 +15,52 @@ spring: multipart: max-file-size: 1024MB max-request-size: 10240MB + threads: + virtual: + enabled: true somkit: upload: path: windows: D://data/install/upload linux: /mnt/files - db: - rocks: - path: - windows: D://RocksDB//fmt - linux: /usr/local/rocksdb/fmt - column-family: default logging: - config: classpath:logback-spring.xml \ No newline at end of file + 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 \ No newline at end of file diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index ff6e0eb..eb7e062 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -9,7 +9,7 @@ DEBUG - + DEBUG ${CONSOLE_LOG_PATTERN} diff --git a/src/main/resources/static/common/js/LogMonitorAdaptive.js b/src/main/resources/static/common/js/LogMonitorAdaptive.js index 225a0c4..c5e9ee3 100644 --- a/src/main/resources/static/common/js/LogMonitorAdaptive.js +++ b/src/main/resources/static/common/js/LogMonitorAdaptive.js @@ -40,6 +40,12 @@ class LogMonitorAdaptive { enableFontSize: true, // 是否提供“字体大小 +/-”按钮 enableWordWrap: true, // 是否提供“换行/不换行”切换按钮 + /* --- 暂停/继续 的回调函数 --- */ + onTogglePause: () => {}, + + /* --- 创建完成 的回调函数 --- */ + onCreated: () => {}, + ...opts }; @@ -59,6 +65,11 @@ class LogMonitorAdaptive { this.initDOM(); this.bindResize(); 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.cfg.theme === 'dark' ? '#d32f2f' : '#ff5252') : (this.cfg.theme === 'dark' ? '#444' : '#e7e7e7'); + //执行回调函数 + if(this.cfg.onTogglePause && typeof this.cfg.onTogglePause === 'function'){ + this.cfg.onTogglePause(this.isPaused); + } } toggleTheme() { diff --git a/src/main/resources/templates/logging.html b/src/main/resources/templates/logging.html index d692225..f1ac741 100644 --- a/src/main/resources/templates/logging.html +++ b/src/main/resources/templates/logging.html @@ -15,9 +15,8 @@
+ - - diff --git a/src/main/resources/templates/upload.html b/src/main/resources/templates/upload.html index d8002ab..c68583c 100644 --- a/src/main/resources/templates/upload.html +++ b/src/main/resources/templates/upload.html @@ -33,7 +33,7 @@ diff --git a/src/test/java/cn/somkit/fmt/FmtApplicationTests.java b/src/test/java/cn/somkit/fmt/FmtApplicationTests.java deleted file mode 100644 index 02d4233..0000000 --- a/src/test/java/cn/somkit/fmt/FmtApplicationTests.java +++ /dev/null @@ -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() { - } - -}