v2.1.0 更新:

1、引入metona-mq-mini-pro消息队列,重构实时日志获取方式
This commit is contained in:
2025-07-23 23:26:56 +08:00
parent bb99e48275
commit e17e31edfd
7 changed files with 40 additions and 27 deletions

View File

@@ -55,7 +55,7 @@
<dependency> <dependency>
<groupId>cn.metona</groupId> <groupId>cn.metona</groupId>
<artifactId>metona-mq-mini-pro</artifactId> <artifactId>metona-mq-mini-pro</artifactId>
<version>1.0.1</version> <version>1.0.2</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@@ -1,8 +1,5 @@
package cn.somkit.fmt; package cn.somkit.fmt;
import cn.metona.mq.consumer.MessageListener;
import cn.metona.mq.core.Message;
import cn.metona.mq.exception.MessageConsumeException;
import cn.metona.mq.util.MetonaMQUtil; import cn.metona.mq.util.MetonaMQUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View File

@@ -2,6 +2,8 @@ package cn.somkit.fmt.action;
import cn.somkit.fmt.utils.OsInfoUtil; import cn.somkit.fmt.utils.OsInfoUtil;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -18,6 +20,8 @@ import java.util.*;
@RequestMapping("/upload") @RequestMapping("/upload")
public class UploadAction { public class UploadAction {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Value("${somkit.upload.path.windows}") @Value("${somkit.upload.path.windows}")
private String windows_path; private String windows_path;
@@ -40,7 +44,7 @@ public class UploadAction {
try { try {
this.saveFile(file); // 保存上传信息 this.saveFile(file); // 保存上传信息
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); logger.error("文件保存失败:{}", e.getMessage());
} }
} }
} }
@@ -56,14 +60,19 @@ public class UploadAction {
* @throws Exception 上传异常 * @throws Exception 上传异常
*/ */
public void saveFile(MultipartFile file) throws Exception { public void saveFile(MultipartFile file) throws Exception {
String path = OsInfoUtil.isWindows() ? windows_path : try {
OsInfoUtil.isLinux() ? linux_path : null; String path = OsInfoUtil.isWindows() ? windows_path :
assert path != null; OsInfoUtil.isLinux() ? linux_path : null;
String filePath = ""; assert path != null;
if (file != null && file.getSize() > 0) { // 有文件上传 String filePath = "";
filePath = path + File.separator + file.getOriginalFilename(); if (file != null && file.getSize() > 0) { // 有文件上传
File saveFile = new File(filePath) ; filePath = path + File.separator + file.getOriginalFilename();
file.transferTo(saveFile); // 文件保存 File saveFile = new File(filePath) ;
file.transferTo(saveFile); // 文件保存
logger.info("文件保存成功:{}", filePath);
}
} catch (Exception e) {
throw new RuntimeException(e);
} }
} }
} }

View File

@@ -30,7 +30,6 @@ public class LogStashFilter extends Filter<ILoggingEvent> {
"yyyy-MM-dd HH:mm:ss.SSS") "yyyy-MM-dd HH:mm:ss.SSS")
); );
try { try {
System.out.println(MetonaMQUtil.getConsumerStatus());
if(MetonaMQUtil.isInitialized() && MetonaMQUtil.isOrderedConsumerRunning()){ if(MetonaMQUtil.isInitialized() && MetonaMQUtil.isOrderedConsumerRunning()){
MetonaMQUtil.send("log-topic", "log-monitor", JSONUtil.toJsonStr(msg)); MetonaMQUtil.send("log-topic", "log-monitor", JSONUtil.toJsonStr(msg));
} }

View File

@@ -30,7 +30,7 @@ public class WebSocketServerHandler implements WebSocketHandler {
boolean closed = StrUtil.isNotBlank(cache.get("closed")) && Boolean.parseBoolean(cache.get("closed")); boolean closed = StrUtil.isNotBlank(cache.get("closed")) && Boolean.parseBoolean(cache.get("closed"));
if(!closed){ if(!closed){
try { try {
if(MetonaMQUtil.isInitialized()){ if(MetonaMQUtil.isInitialized() && !MetonaMQUtil.isOrderedConsumerRunning()){
logger.info("Metona MQ Mini Pro 订阅主题log-topic顺序消息..."); logger.info("Metona MQ Mini Pro 订阅主题log-topic顺序消息...");
MetonaMQUtil.subscribeOrdered("log-topic", new MessageListener() { MetonaMQUtil.subscribeOrdered("log-topic", new MessageListener() {
@Override @Override
@@ -43,10 +43,8 @@ public class WebSocketServerHandler implements WebSocketHandler {
} }
}); });
if(!MetonaMQUtil.isOrderedConsumerRunning()){ logger.info("Metona MQ Mini Pro 启动消费者(顺序消息)...");
logger.info("Metona MQ Mini Pro 启动消费者(顺序消息)..."); MetonaMQUtil.startOrderedConsuming();
MetonaMQUtil.startOrderedConsuming();
}
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("Metona MQ Mini Pro 异常", e); logger.error("Metona MQ Mini Pro 异常", e);

View File

@@ -309,7 +309,7 @@ class LogMonitorAdaptive {
debug: '#9c27b0', info: '#2196f3', warn: '#ff9800', debug: '#9c27b0', info: '#2196f3', warn: '#ff9800',
error: '#f44336', success: '#4caf50', system: '#00bcd4' error: '#f44336', success: '#4caf50', system: '#00bcd4'
}; };
lvlSpan.style.color = colors[entry.level] || colors.info; lvlSpan.style.color = colors[entry.level.toLowerCase()] || colors.info;
lvlSpan.style.minWidth = '70px'; lvlSpan.style.minWidth = '70px';
lvlSpan.style.fontWeight = 'bold'; lvlSpan.style.fontWeight = 'bold';
line.appendChild(lvlSpan); line.appendChild(lvlSpan);

View File

@@ -14,6 +14,18 @@
let ws = null; let ws = null;
let logMonitor = async (closed = false) => {
const options = {
url: Fmt.ctx() + '/logging/close',
data: {closed: closed},
method: 'post'
};
await Fmt.axios(options).then(() => {}).catch((err) => console.error(err));
if(ws){
ws.send('发送日志');
}
}
const logger = new LogMonitorAdaptive('#logContainer', { const logger = new LogMonitorAdaptive('#logContainer', {
theme: 'dark', theme: 'dark',
maxLines: 10000, maxLines: 10000,
@@ -32,13 +44,7 @@
wordWrap: true, // 日志内容是否自动换行true=换行false=横向滚动) wordWrap: true, // 日志内容是否自动换行true=换行false=横向滚动)
//暂停/继续 回调函数 //暂停/继续 回调函数
onTogglePause: async (isPaused) => { onTogglePause: async (isPaused) => {
const options = { await logMonitor(isPaused);
url: Fmt.ctx() + '/logging/close',
data: {closed: isPaused},
method: 'post'
};
await Fmt.axios(options).then((result) => console.log(result)).catch((err) => console.error(err));
ws.send('发送日志');
}, },
onCreated: () => { onCreated: () => {
console.log('日志容器已创建'); console.log('日志容器已创建');
@@ -53,6 +59,10 @@
return false; return false;
} }
ws.onopen = function () {
}
ws.onmessage = function (event) { ws.onmessage = function (event) {
if(event.data){ if(event.data){
let data = JSON.parse(event.data); let data = JSON.parse(event.data);