v2.1.3 更新:
1、使用ServletContextListener方式获取实时日志
2、页面日志要素添加进程id和线程名称,优化样式
3、日志打印级别调整为INFO
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -10,7 +10,7 @@
|
|||||||
</parent>
|
</parent>
|
||||||
<groupId>cn.somkit</groupId>
|
<groupId>cn.somkit</groupId>
|
||||||
<artifactId>fmt</artifactId>
|
<artifactId>fmt</artifactId>
|
||||||
<version>2.1.2</version>
|
<version>2.1.3</version>
|
||||||
<name>fmt</name>
|
<name>fmt</name>
|
||||||
<description>File Manage System for by SpringBoot</description>
|
<description>File Manage System for by SpringBoot</description>
|
||||||
<properties>
|
<properties>
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package cn.somkit.fmt.action;
|
package cn.somkit.fmt.action;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
import cn.somkit.fmt.utils.OsInfoUtil;
|
import cn.somkit.fmt.utils.OsInfoUtil;
|
||||||
|
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.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@@ -31,6 +34,8 @@ import java.util.zip.ZipOutputStream;
|
|||||||
@RequestMapping("/download")
|
@RequestMapping("/download")
|
||||||
public class DownloadAction {
|
public class DownloadAction {
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
@@ -41,6 +46,7 @@ public class DownloadAction {
|
|||||||
public ModelAndView index(String keyboard) throws Exception{
|
public ModelAndView index(String keyboard) throws Exception{
|
||||||
String path = OsInfoUtil.isWindows() ? windows_path :
|
String path = OsInfoUtil.isWindows() ? windows_path :
|
||||||
OsInfoUtil.isLinux() ? linux_path : null;
|
OsInfoUtil.isLinux() ? linux_path : null;
|
||||||
|
logger.info("获取文件存储路径:{}", path);
|
||||||
assert path != null;
|
assert path != null;
|
||||||
File folder = new File(path);
|
File folder = new File(path);
|
||||||
File[] listOfFiles = folder.listFiles();
|
File[] listOfFiles = folder.listFiles();
|
||||||
@@ -59,6 +65,7 @@ public class DownloadAction {
|
|||||||
list = list.stream().filter(map -> String.valueOf(map.get("filename"))
|
list = list.stream().filter(map -> String.valueOf(map.get("filename"))
|
||||||
.contains(keyboard)).collect(Collectors.toList());
|
.contains(keyboard)).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
logger.info("关键词:{},文件数量:{}", keyboard, list.size());
|
||||||
ModelAndView mv = new ModelAndView();
|
ModelAndView mv = new ModelAndView();
|
||||||
mv.setViewName("download");
|
mv.setViewName("download");
|
||||||
mv.addObject("files", list);
|
mv.addObject("files", list);
|
||||||
@@ -66,7 +73,7 @@ public class DownloadAction {
|
|||||||
return mv;
|
return mv;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, Object> getObjectMap(File file) {
|
private Map<String, Object> getObjectMap(File file) {
|
||||||
BigDecimal filesize = BigDecimal.valueOf(file.length())
|
BigDecimal filesize = BigDecimal.valueOf(file.length())
|
||||||
.divide(BigDecimal.valueOf(1024 * 1024), 2, RoundingMode.HALF_UP);
|
.divide(BigDecimal.valueOf(1024 * 1024), 2, RoundingMode.HALF_UP);
|
||||||
Long time = file.lastModified();
|
Long time = file.lastModified();
|
||||||
@@ -77,6 +84,7 @@ public class DownloadAction {
|
|||||||
map.put("filepath", file.getAbsolutePath());
|
map.put("filepath", file.getAbsolutePath());
|
||||||
map.put("filesize", filesize);
|
map.put("filesize", filesize);
|
||||||
map.put("filetime", filetime);
|
map.put("filetime", filetime);
|
||||||
|
logger.info("文件信息:{}", JSONUtil.toJsonStr(map));
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,6 +110,7 @@ public class DownloadAction {
|
|||||||
}
|
}
|
||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
logger.error("IO错误:", e);
|
||||||
throw new RuntimeException("IO错误: " + e.getMessage());
|
throw new RuntimeException("IO错误: " + e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
// 尝试在流关闭后删除文件
|
// 尝试在流关闭后删除文件
|
||||||
@@ -111,7 +120,7 @@ public class DownloadAction {
|
|||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// 记录日志或采取其他措施
|
// 记录日志或采取其他措施
|
||||||
System.err.println("删除文件失败: " + e.getMessage());
|
logger.error("删除文件失败:{}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
35
src/main/java/cn/somkit/fmt/config/LogMonitorAppender.java
Normal file
35
src/main/java/cn/somkit/fmt/config/LogMonitorAppender.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package cn.somkit.fmt.config;
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
|
import ch.qos.logback.core.UnsynchronizedAppenderBase;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import cn.metona.mq.MQToolkit;
|
||||||
|
import cn.metona.mq.core.MessageQueue;
|
||||||
|
import cn.somkit.fmt.entity.LoggerMessage;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
|
||||||
|
public class LogMonitorAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
|
||||||
|
|
||||||
|
private static final String Queue_Name = "log-monitor";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void append(ILoggingEvent event) {
|
||||||
|
LoggerMessage msg = new LoggerMessage(
|
||||||
|
event.getLevel().toString(),
|
||||||
|
event.getThreadName(),
|
||||||
|
event.getLoggerName(),
|
||||||
|
event.getFormattedMessage(),
|
||||||
|
DateUtil.format(Instant.ofEpochMilli(event.getTimeStamp()).atZone(ZoneId.systemDefault()).toLocalDateTime(),
|
||||||
|
"yyyy-MM-dd HH:mm:ss.SSS"),
|
||||||
|
ProcessHandle.current().pid()
|
||||||
|
);
|
||||||
|
//发送日志信息到日志监控队列
|
||||||
|
MessageQueue.QueueStats queueStats = MQToolkit.getQueueStats(Queue_Name);
|
||||||
|
if(queueStats != null && queueStats.isRunning() && !queueStats.isPaused()){
|
||||||
|
MQToolkit.sendMessage(Queue_Name, "log.monitor", JSONUtil.toJsonStr(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package cn.somkit.fmt.config;
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.Logger;
|
||||||
|
import ch.qos.logback.classic.LoggerContext;
|
||||||
|
import jakarta.servlet.ServletContextEvent;
|
||||||
|
import jakarta.servlet.ServletContextListener;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class LogbackConfigListener implements ServletContextListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent event) {
|
||||||
|
// 配置logback
|
||||||
|
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||||
|
Logger rootLogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||||
|
|
||||||
|
// 添加自定义appender
|
||||||
|
LogMonitorAppender appender = new LogMonitorAppender();
|
||||||
|
appender.setContext(loggerContext);
|
||||||
|
appender.start();
|
||||||
|
rootLogger.addAppender(appender);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,15 +2,19 @@ package cn.somkit.fmt.entity;
|
|||||||
|
|
||||||
public class LoggerMessage {
|
public class LoggerMessage {
|
||||||
String level;
|
String level;
|
||||||
|
String threadName;
|
||||||
String name;
|
String name;
|
||||||
String message;
|
String message;
|
||||||
String timestamp;
|
String timestamp;
|
||||||
|
long number;
|
||||||
|
|
||||||
public LoggerMessage(String level, String loggerName, String message, String timestamp) {
|
public LoggerMessage(String level, String threadName, String loggerName, String message, String timestamp, long number) {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
|
this.threadName = threadName;
|
||||||
this.name = loggerName;
|
this.name = loggerName;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
|
this.number = number;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLevel() {
|
public String getLevel() {
|
||||||
@@ -21,6 +25,14 @@ public class LoggerMessage {
|
|||||||
this.level = level;
|
this.level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getThreadName() {
|
||||||
|
return threadName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setThreadName(String threadName) {
|
||||||
|
this.threadName = threadName;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@@ -44,4 +56,12 @@ public class LoggerMessage {
|
|||||||
public void setTimestamp(String timestamp) {
|
public void setTimestamp(String timestamp) {
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumber(long number) {
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
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;
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
import cn.hutool.json.JSONUtil;
|
|
||||||
import cn.metona.mq.MQToolkit;
|
|
||||||
import cn.metona.mq.core.MessageQueue;
|
|
||||||
import cn.somkit.fmt.entity.LoggerMessage;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
|
|
||||||
public class LogStashFilter extends Filter<ILoggingEvent> {
|
|
||||||
|
|
||||||
private static final String Queue_Name = "log-monitor";
|
|
||||||
|
|
||||||
Level level;
|
|
||||||
|
|
||||||
public LogStashFilter() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FilterReply decide(ILoggingEvent e) {
|
|
||||||
LoggerMessage msg = new LoggerMessage(
|
|
||||||
e.getLevel().toString(),
|
|
||||||
e.getLoggerName(),
|
|
||||||
e.getFormattedMessage(),
|
|
||||||
DateUtil.format(Instant.ofEpochMilli(e.getTimeStamp()).atZone(ZoneId.systemDefault()).toLocalDateTime(),
|
|
||||||
"yyyy-MM-dd HH:mm:ss.SSS")
|
|
||||||
);
|
|
||||||
//发送日志信息到日志监控队列
|
|
||||||
MessageQueue.QueueStats queueStats = MQToolkit.getQueueStats(Queue_Name);
|
|
||||||
if(queueStats != null && queueStats.isRunning() && !queueStats.isPaused()){
|
|
||||||
MQToolkit.sendMessage(Queue_Name, "log.monitor", JSONUtil.toJsonStr(msg));
|
|
||||||
}
|
|
||||||
return FilterReply.NEUTRAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLevel(String level) {
|
|
||||||
this.level = Level.toLevel(level);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() {
|
|
||||||
if (this.level != null) {
|
|
||||||
super.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
<!-- 日志输出到控制台 -->
|
<!-- 日志输出到控制台 -->
|
||||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
<filter class="cn.somkit.fmt.filter.LogStashFilter">
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
<level>DEBUG</level>
|
<level>INFO</level>
|
||||||
</filter>
|
</filter>
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- 指定日志输出级别,以及启动的Appender -->
|
<!-- 指定日志输出级别,以及启动的Appender -->
|
||||||
<root level="DEBUG">
|
<root level="INFO">
|
||||||
<appender-ref ref="CONSOLE"/>
|
<appender-ref ref="CONSOLE"/>
|
||||||
</root>
|
</root>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@@ -50,7 +50,8 @@
|
|||||||
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);
|
||||||
logger.log(data.name + ' : ' + data.message, data.level, data.timestamp);
|
let message = `${data.number} --- [ ${data.threadName} ] <span style="color: #198cff;">${data.name}</span> : ${data.message}`;
|
||||||
|
logger.log(message, data.level, data.timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,4 +40,10 @@
|
|||||||
> v2.1.2
|
> v2.1.2
|
||||||
```
|
```
|
||||||
升级metona-mq-mini-pro到2.0.1
|
升级metona-mq-mini-pro到2.0.1
|
||||||
|
```
|
||||||
|
> v2.1.3
|
||||||
|
```
|
||||||
|
使用ServletContextListener方式获取实时日志
|
||||||
|
页面日志要素添加进程id和线程名称,优化样式
|
||||||
|
日志打印级别调整为INFO
|
||||||
```
|
```
|
||||||
Reference in New Issue
Block a user