package cn.kofsoft.component;
import cn.emay.slf4j.Logger;
import cn.emay.slf4j.LoggerFactory;
import cn.kofsoft.config.WebSocketConfig;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ServerEndpoint(value = "/websocket/logging/{logType}")
@Component
public class WebSocketLog {
private final Logger log= LoggerFactory.getLogger(WebSocketLog.class);
/**
* 连接集合
*/
private static Map<String, Session> sessionMap=new ConcurrentHashMap<String, Session>();
private static Map<String, Integer> lengthMap=new ConcurrentHashMap<String, Integer>();
//建立连接
@OnOpen
public void onOpen(Session session,@PathParam("logType") int logType){
//添加到集合中
sessionMap.put(session.getId(),session);
lengthMap.put(session.getId(),1);//默认从第一行开始
//获取日志信息
new Thread(()-> {
log.info("LoggingWebSocketServer任务开始...");
boolean first=true;
while (sessionMap.get(session.getId())!=null){
BufferedReader reader = null;
//RandomAccessFile reader=null;
Long num=1024L;
try {
//日志文件路径,多种路径切换
String filePath ="";
if (logType==1){
filePath="logs/web/info.log";
}
else if (logType==2){
filePath="logs/web/error.log";
}else if (logType==3){
filePath="logs/web/debug.log";
}
//字符流
reader =new BufferedReader(new FileReader(filePath));
//reader = new RandomAccessFile(filePath, "r");
Object[] lines = reader.lines().toArray();
//只取上次之后生成的日志
Object[] copyOfRange = Arrays.copyOfRange(lines, lengthMap.get(session.getId()), lines.length);
// 对日志进行美化
// for (int i=0;i<copyOfRange.length;i++){
// String line= (String) copyOfRange[i];
// //先转义
// line = line.replaceAll("&", "&")
// .replaceAll("<", "<")
// .replaceAll(">", ">")
// .replaceAll("\"", """);
// //处理等级颜色
// line = line.replace("DEBUG", "<span style='color: blue;'>DEBUG</span>");
// line = line.replace("INFO", "<span style='color: green;'>INFO</span>");
// line = line.replace("ERROR", "<span style='color: red;'>ERROR</span>");
// //处理类名
// String[] split = line.split("]");
// if (split.length>=2){
// String[] split1 = split[1].split("-");
// if (split1.length>=2){
// line = split[0] + "]" + "<span style='color: #298a8a;'>" + split1[0] + "</span>" + "-" + split1[1];
//
// }
// }
// //匹配日期开头换行
// Pattern r = Pattern.compile("[\\d+][\\d+][\\d+][\\d+]-[\\d+][\\d+]-[\\d+][\\d+] [\\d+][\\d+]:[\\d+][\\d+]:[\\d+][\\d+]");
// Matcher m = r.matcher(line);
// if (m.find()){
// //找到下标
// int start=m.start();
// StringBuilder sb = new StringBuilder(line);
// sb.insert(start,"<br/><br/>");
// line=sb.toString();
// }
// copyOfRange[i]=line;
// }
//存储最新一行开始
lengthMap.put(session.getId(),lines.length);
//如果第一次太大,截取最新的200行
// if (first && copyOfRange.length>200){
// copyOfRange = Arrays.copyOfRange(copyOfRange,copyOfRange.length-200,copyOfRange.length);
// first=false;
// }
String result = StringUtils.join(copyOfRange, "<br/>");
//发送数据到客户端
send(session, result);
//休眠疫苗
Thread.sleep(1000);
} catch (Exception e){
//捕获异常但不处理
e.printStackTrace();
} finally {
try {
reader.close();//关闭
}catch (Exception e){
e.printStackTrace();
}
}
}
log.info("LoggingWebSocketServer任务结束..");
} ).start();
}
/**
* 连接关闭
*/
@OnClose
public void onClose(Session session){
//从集合中删除
sessionMap.remove(session.getId());
lengthMap.remove(session.getId());
}
/**
* 发生错误时调用
*/
@OnError
public void onError(Session session,Throwable error){
error.printStackTrace();
}
/**
* 服务器接收到客户端消息时调用
* @param session
*/
@OnMessage
public void onMessage(Session session,String message){
}
/**
* 封装一个send方法,发送消息给WEB前段
* @param session
* @param message
*/
private void send(Session session, String message) {
try {
session.getBasicRemote().sendText(message);
}catch (Exception e){
e.printStackTrace();
}
}
}