v2.1.0 更新:
1、引入metona-mq-mini-pro消息队列,重构实时日志获取方式
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,6 +60,7 @@ public class UploadAction {
|
|||||||
* @throws Exception 上传异常
|
* @throws Exception 上传异常
|
||||||
*/
|
*/
|
||||||
public void saveFile(MultipartFile file) throws Exception {
|
public void saveFile(MultipartFile file) throws Exception {
|
||||||
|
try {
|
||||||
String path = OsInfoUtil.isWindows() ? windows_path :
|
String path = OsInfoUtil.isWindows() ? windows_path :
|
||||||
OsInfoUtil.isLinux() ? linux_path : null;
|
OsInfoUtil.isLinux() ? linux_path : null;
|
||||||
assert path != null;
|
assert path != null;
|
||||||
@@ -64,6 +69,10 @@ public class UploadAction {
|
|||||||
filePath = path + File.separator + file.getOriginalFilename();
|
filePath = path + File.separator + file.getOriginalFilename();
|
||||||
File saveFile = new File(filePath) ;
|
File saveFile = new File(filePath) ;
|
||||||
file.transferTo(saveFile); // 文件保存
|
file.transferTo(saveFile); // 文件保存
|
||||||
|
logger.info("文件保存成功:{}", filePath);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,11 +43,9 @@ 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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user