WebSocket页面显示日志的代码
在前端html页面显示后台的服务器日志信息
主要是为了方便,前端也不会ssh去连接服务器tail -f日志。为了方便前端和测试调试,将日志 染色 并显示在页面上。
页面效果
前端页面代码
前面引用的easyui库这些是为了页面布局和原系统支持。其实对读者没啥用,不需要的去掉就行。
<!--showServiceLog.html-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WebSocket查看服务日志页面</title>
<!-- easyUI样式 -->
<link rel="stylesheet" type="text/css" href="../../Font-Awesome-master/css/font-awesome.min.css" />
<link rel="stylesheet" type="text/css" href="../../css/common/main.css" />
<link rel="stylesheet" type="text/css" href="../../css/common/my.css" />
<link rel="stylesheet" type="text/css" href="../../css/themes/default/easyui.css" />
<link rel="stylesheet" type="text/css" href="../../css/themes/icon.css" />
<script type="text/javascript" src="../../js/jquery.min.js"></script>
<script type="text/javascript" src="../../js/jquery.easyui.min.js"></script>
<script type="text/javascript" src="../../js/easyui-lang-zh_CN.js"></script>
<script type="text/javascript" src="../../js/common.js"></script>
<script type="text/javascript" src="../../js/common/Cookie.js"></script>
<script type="text/javascript" src="../../js/sockjs.js"></script>
<style type="text/css">
.datagrid-cell, .datagrid-cell-group, .datagrid-header-rownumber, .datagrid-cell-rownumber
{
text-overflow: ellipsis;
}
</style>
</head>
<body>
<!-- 标题和操作菜单 -->
<table class="title" style="width:100%;padding:5px;">
<tbody>
<tr>
<td style="width:25%;color: #407EAC">
<img src="../../images/common/title.gif" style="vertical-align:middle;">查看服务日志</td>
<td style="text-align: right;">
<!--按钮区域-->
<a class="easyui-linkbutton l-btn l-btn-small" data-options="iconCls:'icon-search'" onclick="loadSocket2()"> 查看日志 </a>
<a class="easyui-linkbutton l-btn l-btn-small" data-options="iconCls:'icon-search'" onclick="looknearly()"> 查看最近 </a>
<a class="easyui-linkbutton l-btn l-btn-small" data-options="iconCls:'icon-search'" onclick="cleanText()"> 清屏 </a>
</td>
</tr>
</tbody>
</table>
<!-- 模糊查询 -->
<table class="btbForm">
<tbody>
<tr>
<!--<td>-->
<!--小组发送<input id="groupId" class="easyui-combobox" data-options="editable:false,panelHeight:'auto',limitToList:'true'" style="width: 110px;">-->
<!-- 组员 <input id="userId" class="easyui-combobox" data-options="editable:false,panelHeight:'auto',limitToList:'true'" style="width: 110px;">-->
<!--</td>-->
</tr>
</tbody>
</table>
<!-- 表格间距 -->
<div style="margin-top:5px"></div>
<!-- 数据表格 -->
<div>
<div id="text" style=" overflow-y:scroll; width:100%; height:400px;word-break:break-word;">初始化完毕...</div>
</div>
<!--隐藏的昵称信息-->
<input id="nickName" style="display: none">
<script type="text/javascript">
//定义WebSocket接口
var ws;
/**
* jQuery初始化完毕执行的代码
*/
$(function(){
loadSocket2();
setInterval(function(){
$('#text').css("height",$(document.body).height()*0.8);
},300);
});
/**
* 下滑到底部
*/
function looknearly() {
try {
$("#text").scrollTop($("#text")[0].scrollHeight);
} catch (e) {
console.error(e);
}
}
/**
* 获取WebSocket根地址
*/
function wsPath() {
//定义ws接口开头协议
var wsPath = "ws://"+basePath.split("://")[1];
if(basePath.split("://")[0].trim().toLowerCase().indexOf("https")>-1){
wsPath = "wss://"+basePath.split("://")[1];
}
return wsPath;
}
function testOhter() {
$.messager.prompt('提示信息', '请输入ws地址:', function(r){
if (r){
loadSocket2(r);
}else{
loadSocket2();
}
});
}
/**
* 加载websocket数据
*/
function loadSocket2(file){
//console.log(ws);
if(ws!=null&&ws!=undefined&&ws.readyState == 1){
$('#text').append("连接已存在..<br/>");
return;
}
if(file!=null&&file!=undefined&&file!=''){
if ("WebSocket" in window){
ws=new WebSocket(wsPath()+"/websocket/"+file+".json");
}else{
ws=new SockJS(wsPath()+"/sockjs/"+file+".ws");
}
}else{
if ("WebSocket" in window){
ws=new WebSocket(wsPath()+"/ws_showLog.json");
}else{
ws=new SockJS(wsPath()+"/sockjs/ws_showLog.ws");
}
}
$('#text').append("<br/>开始建立连接...<br/>");
ws.onopen=function(event){
$('#text').append("连接已建立..<br/>");
$('#start').linkbutton('disable');
}
/**接收消息*/
ws.onmessage=function(event){
//console.log(event);
var msg=event.data;
$('#text').append(msg);
// 滚动条滚动到最低部
try {
$("#text").scrollTop($("#text")[0].scrollHeight);
} catch (e) {
console.error(e);
}
}
ws.onclose=function(){
$('#text').append("连接已关闭..<br/>");
$('#start').linkbutton('enable');
}
ws.onerror = function(){
$('#text').append("发生了错误..<br/>");
$('#start').linkbutton('enable');
}
}
/**
* 手动加载websocket数据
*/
function loadSocket(file){
if(file!=null&&file!=undefined&&file!=''){
if ("WebSocket" in window){
ws=new WebSocket(wsPath()+"/websocket/"+file+".json");
}else{
ws=new SockJS(wsPath()+"/sockjs/"+file+".ws");
}
}else{
if ("WebSocket" in window){
ws=new WebSocket(wsPath()+"/ws_showLog.json");
}else{
ws=new SockJS(wsPath()+"/sockjs/ws_showLog.ws");
}
}
$('#text').append("<br/>开始建立连接...<br/>");
ws.onopen=function(event){
$('#text').append("连接已建立..<br/>");
$('#start').linkbutton('disable');
}
/**接收消息*/
ws.onmessage=function(event){
//console.log(event);
var msg=event.data;
$('#text').append(msg);
// 滚动条滚动到最低部
try {
$("#text").scrollTop($("#text")[0].scrollHeight);
} catch (e) {
console.error(e);
}
}
ws.onclose=function(){
$('#text').append("连接已关闭..<br/>");
$('#start').linkbutton('enable');
}
ws.onerror = function(){
$('#text').append("发生了错误..<br/>");
$('#start').linkbutton('enable');
}
}
/**
* 清除屏幕
*/
function cleanText() {
$('#text').html("屏幕已清除...<br/>");
}
</script>
</body>
</html>
后台代码
WebSocketInterceptor拦截器
package com.faker.filter;
import com.faker.app.util.ToolsUtil;
import org.apache.log4j.Logger;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
import javax.servlet.http.HttpSession;
import java.util.Map;
/**
* <p>Title: WebSocketInterceptor拦截器 - WebSocketInterceptor_ShowLog</p>
*
* <p>Description:WebSocket 适配器 拦截器 显示tomcat日志的拦截器</p>
*
* <p>Copyright: Copyright Faker(c) 2018</p>
*
* <p>Company: 无</p>
*
* @author Anlinxi
*
* @version 1.0
*/
public class WebSocketInterceptor_ShowLog implements HandshakeInterceptor {
/**
* 日志
*/
private final static Logger log= Logger.getLogger(WebSocketInterceptor_ShowLog.class);
/**
* 握手前
* @param request 请求
* @param response 响应
* @param handler ws握手
* @param attributes 属性
* @return 是否握手成功
* @throws Exception 异常
*/
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,
Map<String, Object> attributes) throws Exception {
log.info("执行握手: "+handler+"map: "+attributes.values());
if(request != null){
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession();
if(session!=null){
String userId = (String) session.getAttribute("WEBSOCKET_SL_ID");
if(userId!=null){
session.setAttribute("SESSION_SL_ID", userId);
attributes.put("WEBSOCKET_SL_ID", userId);
}else{
session.setAttribute("SESSION_SL_ID", session.getId());
attributes.put("WEBSOCKET_SL_ID", session.getId());
}
}
}
return true;
}
/**
* 将属性设置到session里
* @param session session
* @param attributes Map
* @param attributeName 待设置的属性名
* @param attribute 待设置的属性
*/
private void setAttributes(HttpSession session,Map<String, Object> attributes,String attributeName,String attribute){
if (ToolsUtil.isNotNull(attribute)) {
String attributeNameUp = attributeName.toUpperCase();
session.setAttribute("SESSION_"+attributeNameUp, attribute);
attributes.put("WEBSOCKET_"+attributeNameUp, attribute);
}
}
/**
* 握手后
* @param request 请求
* @param response 响应
* @param handler ws握手
* @param exceptions 错误
*/
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler, Exception exceptions) {
log.info("握手后: "+handler+"exceptions: "+exceptions);
}
}
WebSocketHandler握手动作
package com.faker.filter;
import com.faker.app.util.CpdetectorUtils;
import com.faker.app.util.TailLogThread;
import com.faker.app.util.ToolsUtil;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.springframework.web.util.HtmlUtils;
import java.io.*;
import java.util.*;
import static java.lang.Thread.sleep;
/**
* <p>Title: Websocket处理器 - WebSocketHandler_ShowLog</p>
*
* <p>Description:统一发送信息等操作的</p>
*
* <p>Copyright: Copyright Faker(c) 2018</p>
*
* <p>Company: 无</p>
*
* @author Anlinxi
*
* @version 1.0
*/
public class WebSocketHandler_ShowLog extends TextWebSocketHandler {
private final static Logger logger = LoggerFactory.getLogger(WebSocketHandler_ShowLog.class);
/**储存分组信息 分组名:用户分组list*/
public static final Map<Object, WebSocketSession> userSocketSessionMap;
static {
userSocketSessionMap = new HashMap<Object, WebSocketSession>();
}
/**实例化的类*/
public static WebSocketHandler_ShowLog webSocketHandler;
/**运行的日志程序cmd*/
private static Process process;
/**输入流*/
private static InputStream inputStream;
/**
* 实例化方法
* @return webSocketHandler
*/
public static WebSocketHandler_ShowLog getBeans(){
if(webSocketHandler == null){
webSocketHandler = new WebSocketHandler_ShowLog();
}
return webSocketHandler;
}
/**
* 处理前端发送的文本信息
* js调用websocket.send时候,会调用该方法
* @param session session
* @param message 发送信息
* @throws Exception 异常
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
if(message.getPayloadLength()==0){
return;
}
// message.getPayload().toString() 获取消息具体内容
Map<String, Object> msg = JSONObject.fromObject(message);
logger.info("handleMessage......."+message.getPayload()+"..........."+msg);
session.sendMessage(message);
// 调用方法(发送消息给所有人)
this.sendMessageToAllUsers(msg.get("msgContent").toString());
}
/**
* 当新连接建立的时候,被调用
* 连接成功时候,会触发页面上onOpen方法
* @param session session
* @throws Exception 异常
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String uid = (String) session.getAttributes().get("WEBSOCKET_SL_ID");
if (userSocketSessionMap.get(uid) == null) {//获取用户id
uid = session.getId();
userSocketSessionMap.put(uid, session);
}
logger.info("======"+uid+" 建立连接完成======");
//读取配置文件里日志文件地址
String fileAddr = ToolsUtil.getInstence().getProperties("myConfig","log.tomcat.catalina");
if(ToolsUtil.isNotNull(fileAddr)){
//读取现有日志信息
this.readCatalinaFile(fileAddr,session);
//进程为空或者未激活时执行cmd命令
// 执行tail -f命令
String cmd = "tail -f "+fileAddr;
try {
process = Runtime.getRuntime().exec(cmd);
inputStream = process.getInputStream();
if(process.isAlive()){
// 一定要启动新的线程,防止InputStream阻塞处理WebSocket的线程
TailLogThread thread = new TailLogThread(inputStream, session );
thread.start();
}
} catch (IOException e) {
//logger.error(cmd);
System.err.println(cmd);
e.printStackTrace();
this.close();
}
}else{
logger.error("======未配置myConfig文件中log.tomcat.catalina属性(tomcat日志路径)======");
}
}
/**
* 读取现有日志信息
* @param fileAddr 文件地址
* @param session WebSocketSession
*/
private void readCatalinaFile(String fileAddr, WebSocketSession session) {
Map<String,Object> result = new HashMap<>(4);
FileInputStream inStream = null;
try {
File file = new File(fileAddr);
//如果文件夹不存在,先创建文件夹
if(!file.exists()){
System.err.println("文件不存在");
return;
}
inStream = new FileInputStream(file);
String bm = CpdetectorUtils.getInstence().getFileOrIOEncode(fileAddr,"file");
InputStreamReader isr = new InputStreamReader(inStream, bm);
BufferedReader reader = new BufferedReader(isr);
String pythonText;
//读取的一行
String readline;
List<String> sbList = new ArrayList();
while((readline = reader.readLine())!=null){
sbList.add(this.setColorToMsg(readline));
}
reader.close();
int rowsNum = sbList.size();
int sendNum = 0;
StringBuffer sb = new StringBuffer();
for(String l:sbList){
if(1<=rowsNum&&rowsNum<=400){
sb.append(l);
}
if(sb.length()>4096){
session.sendMessage(new TextMessage(sb.toString()));
sb.setLength(0);
sendNum++;
try {
//发送一次的时间间隔,给浏览器反映的时间
sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else if(rowsNum<=1&&sb.length()>0){
session.sendMessage(new TextMessage(sb.toString()));
sb.setLength(0);
sendNum++;
}
rowsNum--;
}
logger.info("原始日志共计"+sbList.size()+"行。发送信息"+sendNum+"次。");
session.sendMessage(new TextMessage(System.lineSeparator()+System.lineSeparator()+"最近日志加载完毕......"+System.lineSeparator()+System.lineSeparator()));
inStream.close();
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
return;
}
/**
* 给日志上色!
* @param msg 日志消息
* @return html
*/
private String setColorToMsg(String msg){
String color = "";
if(msg.toLowerCase().contains("error")){
color = "#ff0000";
}else if(msg.toLowerCase().contains("warn")){
color = "#ff9900";
}else if(msg.toLowerCase().contains("debug")){
color = "#336600";
}else if(msg.toLowerCase().contains("info")){
color = "#0033cc";
}else if(msg.contains("定时清除游离文件中(时间间隔5分钟)")){
color = "#C1CDCD";
}else if(msg.contains("Exception")){
color = "#FFD700";
}
//对文本中含有的html代码进行转义
msg = HtmlUtils.htmlEscape(msg);
String html = "<p class='log_msg' style='color:"+color+"'>"+msg+"</p>";
return html;
}
/**
* 当连接关闭时被调用
* @param session session
* @param status 连接状态
* @throws Exception 异常
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
logger.info("Websocket:" + session.getId() + "已经关闭");
Iterator<Map.Entry<Object, WebSocketSession>> it = userSocketSessionMap
.entrySet().iterator();
// 移除Socket会话
logger.info("======关闭连接======");
while (it.hasNext()) {
Map.Entry<Object, WebSocketSession> entry = it.next();
if (entry.getValue().getId().equals(session.getId())) {
userSocketSessionMap.remove(entry.getKey());
logger.warn("Socket会话已经移除:用户ID" + entry.getKey());
break;
}
}
this.close();
}
/**
* 关闭程序和流
*/
private void close(){
// logger.info("关闭ws的程序和流!");
// try {
// if(inputStream != null)
// inputStream.close();
// } catch (Exception e) {
// e.printStackTrace();
// }
// if(process != null){
// process.destroy();
// }
}
/**
* 传输错误时调用
* @param session session
* @param exception 异常
* @throws Exception 异常
*/
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
if (session.isOpen()) {
session.close();
}
Iterator<Map.Entry<Object, WebSocketSession>> it = userSocketSessionMap
.entrySet().iterator();
logger.info("======消息传输错误======");
// 移除Socket会话
while (it.hasNext()) {
Map.Entry<Object, WebSocketSession> entry = it.next();
if (entry.getValue().getId().equals(session.getId())) {
userSocketSessionMap.remove(entry.getKey());
logger.error("Socket会话已经移除:用户ID" + entry.getKey());
break;
}
}
this.close();
}
/**
* 给所有在线用户发送消息
* @param message 发送消息
*/
public void sendMessageToAllUsers(String message) {
Iterator<Map.Entry<Object, WebSocketSession>> it = userSocketSessionMap
.entrySet().iterator();
logger.info("======群发======");
// 多线程群发
while (it.hasNext()) {
final Map.Entry<Object, WebSocketSession> entry = it.next();
if (entry.getValue().isOpen()) {
new Thread(new Runnable() {
public void run() {
try {
if (entry.getValue().isOpen()) {
entry.getValue().sendMessage(new TextMessage(message));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
/**
* 给某个用户发送消息
* @param userId 用户id
* @param message 发送信息
*/
public void sendMessageToUser(String userId,String message) throws IOException {
WebSocketSession session = userSocketSessionMap.get(userId);
logger.info("======给某个用户发送消息======");
if (session != null && session.isOpen()) {
session.sendMessage(new TextMessage(message));
}
}
}
WebSocketConfig配置类
package com.faker.filter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
/**
* <p>Title: websocket配置类 - WebSocketConfig_ShowLog</p>
*
* <p>Description:websocket日志显示的配置信息</p>
*
* <p>Copyright: Copyright Faker(c) 2018</p>
*
* <p>Company: 无</p>
*
* @author Anlinxi
*
* @version 1.0
*/
@Configuration
//这个标注可以不加,如果有加,要extends WebMvcConfigurerAdapter
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig_ShowLog extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
/**
* 注册websocket的信息
* @param registry registry
*/
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
//设置websocket的地址,注册Handler,注册Interceptor
registry.addHandler(SocketHandler(), "/ws_showLog.json").setAllowedOrigins("*").addInterceptors(new WebSocketInterceptor_ShowLog());
//注册SockJS,提供SockJS支持(主要是兼容ie8)
registry.addHandler(SocketHandler(), "/sockjs/ws_showLog.ws")
//允许跨域
.setAllowedOrigins("*")
//注册Interceptor
.addInterceptors(new WebSocketInterceptor_ShowLog())
//支持sockjs协议
.withSockJS();
}
@Bean
public org.springframework.web.socket.WebSocketHandler SocketHandler(){
return new com.faker.filter.WebSocketHandler_ShowLog ();
}
/**
* 配置webSocket引擎
* 用于tomcat 可以不配置
* @return Bean
*/
@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
container.setMaxTextMessageBufferSize(8192);
container.setMaxBinaryMessageBufferSize(8192);
return container;
}
}
TailLogThread实时读取日志的线程
package com.faker.app.util;
import org.apache.commons.codec.StringEncoder;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.util.HtmlUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class TailLogThread extends Thread {
/**读取缓冲*/
private BufferedReader reader;
/**WebSocketSession*/
private WebSocketSession session;
/**消息队列*/
private List<String> msgs = new ArrayList<>();
/**cmd的文本编码*/
private String encoding;
public TailLogThread(InputStream in, WebSocketSession session) {
this.reader = new BufferedReader(new InputStreamReader(in));
this.session = session;
}
/**
* 读取日志的方法
*/
@Override
public void run() {
this.method1();
}
/**
* 原始读取日志的方法
*/
private void method1(){
String line;
try {
if(session.isOpen()){
//如果消息队列有数据,则先输出消息队列消息
if(msgs.size()>0){
List<String> errMsgs = new ArrayList<>();
for(String msg:msgs){
try {
//输出消息队列消息
this.sendMsg(msg,session);
} catch (IOException e) {
//未发送的信息储存在错误消息队列中
System.err.println(e.getMessage());
errMsgs.add(msg);
}
}
//清空消息队列
msgs.clear();
//如果有错误的消息队列,储存给消息队列中
if(errMsgs.size()>0){
msgs = errMsgs;
}
}
}
while((line = reader.readLine()) != null) {
if(encoding==null||encoding==""){
encoding = this.StringEncoding(line);
}
//String text = new String(line.getBytes(encoding),"UTF-8");
// 将实时日志通过WebSocket发送给客户端,给每一行添加一个HTML换行
if(session.isOpen()){
this.sendMsg(line,session);
}else{
msgs.add(line);
}
}
} catch (IOException e) {
System.err.println(e.getMessage());
e.printStackTrace();
}
}
/**
* 发送消息
* @param msg
* @param session
* @throws IOException
*/
private void sendMsg(String msg,WebSocketSession session) throws IOException {
String str = msg;
if(1==1){
str = this.setColorToMsg(msg);
}else{
//文本域
str = str + System.lineSeparator();
}
session.sendMessage(new TextMessage(str));
}
/**
* 判断字符串编码
* @param sb 字符串
* @return 编码类型
*/
private String StringEncoding(String sb){
String backEncoding = "";
String iso8859 = this.testEncoding(sb,"iso8859-1");
String gbk = this.testEncoding(sb,"gbk");
String utf8 = this.testEncoding(sb,"utf-8");
if(iso8859.equals(sb.toString())){
backEncoding = "iso8859";
}else if(gbk.equals(sb.toString())){
backEncoding = "gbk";
}else if(utf8.equals(sb.toString())){
backEncoding = "utf8";
}
return backEncoding;
}
/**
* 给日志上色!
* @param msg 日志消息
* @return html
*/
private String setColorToMsg(String msg){
String color = "";
if(msg.toLowerCase().contains("error")){
color = "#ff0000";
}else if(msg.toLowerCase().contains("warn")){
color = "#ff9900";
}else if(msg.toLowerCase().contains("debug")){
color = "#336600";
}else if(msg.toLowerCase().contains("info")){
color = "#0033cc";
}else if(msg.contains("定时清除游离文件中(时间间隔5分钟)")){
color = "#C1CDCD";
}else if(msg.contains("Exception")){
color = "#FFD700";
}
//对文本中含有的html代码进行转义
msg = HtmlUtils.htmlEscape(msg);
String html = "<p class='log_msg' style='color:"+color+"'>"+msg+"</p>";
return html;
}
/**
* 测试编码
* @param sb 文本
* @param encoding 编码
* @return
*/
private String testEncoding(String sb,String encoding){
String tmpStrin = null;
try {
tmpStrin = new String(sb.toString().getBytes(encoding));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return tmpStrin;
}
}
ToolsUtil工具类
package com.faker.app.util;
import com.sun.istack.internal.NotNull;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
/**
* <p>Title: 常用的工具类 - ToolsUtil</p>
*
* <p>Description:常用工具放这儿</p>
*
* <p>Copyright: Copyright Faker(c) 2018</p>
*
* <p>Company: 无</p>
*
* @author Anlinxi
*
* @version 1.0
*/
public class ToolsUtil {
/**
* 工具类实例化对象
*/
private static ToolsUtil toolsUtil = null;
/**
* 私有化构造函数防止new对象消耗内存
*/
private ToolsUtil() {
}
/**
* 静态实例化方法获取实例化对象
* 使用同一个lCsinginUtil,减少内存占用
* @return LCsinginUtil
*/
public static ToolsUtil getInstence(){
if(toolsUtil==null){
toolsUtil = new ToolsUtil();
}
return toolsUtil;
}
/**
* 日志
*/
private final static Logger logger = LoggerFactory.getLogger(ToolsUtil.class);
/**
* 发送json数据
* @param response 响应
* @param object 发送的对象
*/
public static void WriterJson(@NotNull HttpServletResponse response, Object object){
try {
String backJson = null;
if(object instanceof List){
JSONArray jsonArray = JSONArray.fromObject(object);
backJson = jsonArray.toString();
}else{
JSONObject jsonObject = JSONObject.fromObject(object);
backJson = jsonObject.toString();
}
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setContentType("text/json;charset=utf-8");
PrintWriter printWriter = response.getWriter();
logger.info("发送json数据>>>>>>>>>>>>>>>>"+backJson);
printWriter.write(backJson);
printWriter.flush();
printWriter.close();
} catch (IOException e) {
logger.error("发送json数据失败");
e.printStackTrace();
}
}
/**
* 判断一个字符串是否为null或空字符,是则返回false,否为true
* @param str 字符串对象
* @return 是否为null或空字符
*/
public static boolean isNotNull(Object str){
return !isNullOrEmpty(str);
}
/**
* 判断一个字符串是否为null或空字符,是则返回true,否为false
* @param str 字符串对象
* @return 是否为null或空字符
*/
public static boolean isNullOrEmpty(Object str){
String t = trim(str);
if(t.equals("") || t==null){
return true;
} else {
return false;
}
}
/**
* 字符串对象去空
* @param str 字符串对象
* @return 替换空
*/
public static String trim(Object str){
return trim(str, "");
}
/**
* 将对象转换为字符串类型
* @param obj 对象
* @param nullToString 如果为空就返回该默认值
* @return 字符串类型
*/
public static String trim(Object obj, String nullToString){
return obj == null ? nullToString : obj.toString().trim();
}
/**
* 读取python文件代码
* @param fileName 文件名(含后缀)
* @param path 文件夹路径
* @return 读取的字符串
*/
public Boolean download( HttpServletResponse response,String fileName, String path){
FileInputStream inStream = null;
try {
inStream = new FileInputStream(path+fileName);
//通过available方法取得流的最大字符数
byte[] inOutb = new byte[inStream.available()];
//读入流,保存在byte数组
inStream.read(inOutb);
//设置文件类型
response.setContentType(Files.probeContentType(Paths.get(path+fileName)));
//将response提取流
OutputStream out = response.getOutputStream();
//将byte数组写入response中
out.write(inOutb);
//刷新流
out.flush();
out.close();
inStream.close();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
return false;
}
return true;
}
/**
* 获取系统信息
*/
Properties prop = System.getProperties();
/**
* 获取当前服务器所在系统的路径
* @return 服务器的路径
*/
public String classRootPath() {
//确定jython目录的路径
String classRootPath = this.getClass().getResource("/").toString();
String os = prop.getProperty("os.name");
if (os != null && os.toLowerCase().indexOf("linux") > -1) {
return classRootPath.replace("file:", "");
} else {
return classRootPath.replace("file:/", "");
}
}
/**
* 获取properties文件配置信息
* @param fileName 文件名(不含后缀)
* @param key 取值对应的键名
* @return 值
* @throws Exception 异常
*/
public String getProperties (String fileName,String key) throws Exception {
//文件名不为空
if(fileName!=null&&!"".equals(fileName)){
//不需要后缀
if(fileName.contains(".properties")){
fileName.replace(".properties","");
}
if(key!=null&&!"".equals(key)){
//properties文件放置的位置
String fileAddr = "config/"+fileName;
ResourceBundle resource = ResourceBundle.getBundle(fileAddr);
String text = new String(resource.getString(key).getBytes("ISO-8859-1"), "UTF8");
return text;
}else{
throw new Exception("取值键名为空!");
}
}else{
throw new Exception("文件名为空!");
}
}
}
给日志上色的方法
这个方法是去匹配字符串,不是原本的错误就是红色,所以可能有误差。配色也不会配,颜色区分这些还是前端要敏感一些。
/**
* 给日志上色!
* @param msg 日志消息
* @return html
*/
private String setColorToMsg(String msg){
String color = "";
if(msg.toLowerCase().contains("error")){
color = "#ff0000";
}else if(msg.toLowerCase().contains("warn")){
color = "#ff9900";
}else if(msg.toLowerCase().contains("debug")){
color = "#336600";
}else if(msg.toLowerCase().contains("info")){
color = "#0033cc";
}else if(msg.contains("定时清除游离文件中(时间间隔5分钟)")){
color = "#C1CDCD";
}else if(msg.contains("Exception")){
color = "#FFD700";
}
//对文本中含有的html代码进行转义
msg = HtmlUtils.htmlEscape(msg);
String html = "<p class='log_msg' style='color:"+color+"'>"+msg+"</p>";
return html;
}
```