java 实现 tail -f 实时查看日志
2023-12-20 02:26:26
实现方式
1.参考开源项目finderWeb实现日志实时展示
2.前端实现方式采用的layui框架提交的ajax
效果图
选择目录、选择该目录下的文件、选择查看文件的编码{默认UTF-8}
点击提交按钮,就可以实时查看该文件的内容
项目代码大体展示
contorller层
package com.zkjw.cms.plugins.finderWeb;
import com.zkjw.cms.common.utils.HttpRequestUtil;
import com.zkjw.cms.plugins.finderWeb.model.Finder;
import com.zkjw.cms.plugins.finderWeb.service.FinderWebServce;
import com.zkjw.cms.plugins.finderWeb.service.LessServlet;
import com.zkjw.cms.plugins.finderWeb.template.TailTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @description tail -f 查看日志
* @author 刘洪荣
* @since 2023/11/13 12:59
* @desc
*/
@Controller
@RequestMapping("/finderWeb")
public class FinderWebController {
/**
* 如何在window下像linux下一样tail -f catalina.out查看tomcat日志
* 原文链接:https://blog.csdn.net/bud407/article/details/84534416
*
* 大家都有在linux下使用tail -f catalina.out查看tomcat日志的习惯,
* 在window下可以吗?当然可以下面就介绍一下如何操作。
* 1、打开bin下面的startup.bat文件,把call "%EXECUTABLE%" start %CMD_LINE_ARGS%
* 改为call "%EXECUTABLE%" run %CMD_LINE_ARGS% 。
* 2、打开bin下面的catalina.bat文件,会发现共有4处%ACTION%,在后面分别加上
* “>>%CATALINA_BASE%\logs\catalina.out”。
* 重启tomcat,就会发现在logs文件夹下出现了catalina.out文件,把原来控制台的信息全写进去了。
*
* 如果中文乱码则添加{-Dfile.encoding="UTF-8"}
* -Dcatalina.home="%CATALINA_HOME%" -Dfile.encoding="UTF-8"
*/
FinderWebServce finderWebServce =new FinderWebServce();
/**
* 查看实时日志
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
@RequestMapping(value = "/lessGetTail",method = {RequestMethod.GET,RequestMethod.POST})
public void getTail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
File file = Finder.getFile(request);
finderWebServce.getTail(request, response, file);
}
/**
* 加载实时日志界面,并获取容器日志目录
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
@RequestMapping(value = "/finderTail",method = {RequestMethod.GET,RequestMethod.POST})
public void tail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if(LessServlet.prepare(request, response)) {
TailTemplate.execute(request, response);
}
}
}
service层
/**
* @param request
* @param response
* @return boolean
* @throws ServletException
* @throws IOException
*/
public static boolean prepare(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String request_workspace = request.getParameter("workspace");
String request_path = request.getParameter("path");
String work ="";//日志工作空间
String path ="";//文件名称
File file_workspace = new File(request_workspace);
if(file_workspace.exists() || file_workspace.isFile()) {
work=request_workspace;
path=request_path;
}else{
work = Path.getWebWork(request);
path= Path.getWebPath(request,work);
}
String charset = request.getParameter("charset");
String realPath = Finder.getRealPath(work, path);
if(realPath == null) {
FinderServlet.error(request, response, 404, work + "/" + path + " not exists.");
return false;
}
if(charset == null || charset.trim().length() < 1) {
charset = "utf-8";
}
File file = new File(realPath);
if(!file.exists() || !file.isFile()) {
FinderServlet.error(request, response, 404, realPath + " not exists.");
return false;
}
String parent = Path.getRelativePath(work, file.getParent());
String relativePath = Path.getRelativePath(work, realPath);
request.setAttribute("workspace", request_workspace);
request.setAttribute("work", work);
request.setAttribute("path", relativePath);
request.setAttribute("parent", parent);
request.setAttribute("charset", charset);
request.setAttribute("absolutePath", file.getCanonicalPath());
return true;
}
modelAndView层
/**
* @param request
* @param response
* @throws IOException
* @throws ServletException
*/
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String path=request.getScheme()+"://"+request.getServerName()+":"+request.getLocalPort()+request.getContextPath();
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\r\n");
out.write("<html>\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\r\n");
out.write("<meta http-equiv=\"Pragma\" content=\"no-cache\"/>\r\n<meta http-equiv=\"Cache-Control\" content=\"no-cache\"/>\r\n");
out.write("<meta http-equiv=\"Expires\" content=\"0\"/>\r\n<title>WebTail</title>\r\n<link rel=\"stylesheet\" type=\"text/css\" href=\"");
this.print(out, request.getAttribute("requestURI"));
out.write(path+"/web/assets/libs/finder/css/less.css\"/>\r\n<script type=\"text/javascript\" src=\"");
this.print(out, request.getAttribute("requestURI"));
out.write(path+"/web/assets/libs/finder/jquery-1.7.2.min.js\"></script>\r\n<script type=\"text/javascript\" src=\"");
this.print(out, request.getAttribute("requestURI"));
out.write(path+"/web/assets/libs/finder/config.js\"></script>\r\n<script type=\"text/javascript\" src=\"");
this.print(out, request.getAttribute("requestURI"));
out.write(path+"/web/assets/libs/finder/charset.js\"></script>\r\n<script type=\"text/javascript\" src=\"");
this.print(out, request.getAttribute("requestURI"));
out.write(path+"/web/assets/libs/finder/tail.js\"></script>\r\n<script type=\"text/javascript\">\r\n<!--\r\n");
out.write("jQuery(function() {\r\n var container = Tail.getContainer();\r\n\r\n jQuery(window).bind(\"resize\", function(){\r\n");
out.write(" jQuery(container).height(jQuery(window).height() - 56);\r\n });\r\n jQuery(window).trigger(\"resize\");\r\n");
out.write("});\r\n\r\njQuery(function(){\r\n Tail.tailURL = \"");
this.print(out, path+"/finderWeb/lessGetTail"); //读取信息action
out.write("?action=lessGetTail&\";\r\n\r\n jQuery(\"#tailButton\").toggle(function(){\r\n this.value = \" 启 动 \";\r\n");
out.write(" Tail.stop();\r\n }, function(){\r\n this.value = \" 停 止 \";\r\n Tail.start();\r\n");
out.write(" });\r\n Tail.init();\r\n});\r\n//-->\r\n</script>\r\n</head>\r\n<body contextPath=\"");
this.print(out, request.getAttribute("contextPath"));
out.write("\" workspace=\"");
this.print(out, request.getAttribute("workspace"));
out.write("\" parent=\"");
this.print(out, request.getAttribute("parent"));
out.write("\" path=\"");
this.print(out, request.getAttribute("path"));
out.write("\" charset=\"");
this.print(out, request.getAttribute("charset"));
out.write("\">\r\n<!-- 设置-语言-语言和输入设置-去掉勾选 启用拼写检查 -->\r\n<div id=\"tail-container\" class=\"less-container\" contenteditable=\"false\"></div>\r\n");
out.write("<div class=\"less-status-bar\">\r\n <div style=\"height: 18px; background-color: #333333;\">\r\n");
out.write(" <span class=\"charset\"><select name=\"charset\" selected-value=\"");
this.print(out, request.getAttribute("charset"));
out.write("\"></select></span>\r\n <span class=\"ctrl\">\r\n <input id=\"tail-reload-btn\" type=\"button\" class=\"button\" value=\"刷 新\"/>\r\n");
out.write(" <input id=\"tail-clear-btn\" type=\"button\" class=\"button\" value=\"清 空\"/>\r\n");
out.write(" <input id=\"tail-stop-btn\" type=\"button\" class=\"button\" value=\"停 止\"/>\r\n");
out.write(" <input id=\"tail-select-btn\" type=\"button\" class=\"button\" value=\"全 选\"/>\r\n");
out.write(" <input id=\"tail-find-btn\" type=\"button\" class=\"button\" value=\"查 找\"/>\r\n");
out.write(" </span>\r\n <span class=\"pad4\">重载时间:<input id=\"tail-reload-interval\" type=\"text\" class=\"text w30\" value=\"1\"/> 秒</span>\r\n");
out.write(" <span class=\"pad4\"><input id=\"tail-auto-scroll\" type=\"checkbox\" class=\"checkbox\" checked=\"true\"/>自动滚动</span>\r\n");
out.write(" </div>\r\n</div>\r\n<div id=\"find-panel\" class=\"find-panel\" style=\"display: none;\">\r\n");
out.write(" <div>\r\n 查找内容: <input id=\"grep-keyword\" type=\"text\" class=\"grep-keyword\" value=\"\" placeholder=\"正则示例: /finder/.*\\.html\"/>\r\n");
out.write(" <input id=\"grep-ensure\" type=\"button\" class=\"grep-search\" value=\"确定\"/>\r\n");
out.write(" </div>\r\n <div style=\"clear: both; padding-top: 12px; height: 20px;\">\r\n <span style=\"float: left; width: 10px; display: inline-block;\"><input id=\"grep-regexp\" type=\"checkbox\" title=\"正则表达式\"/></span>\r\n");
out.write(" <span style=\"float: left; margin-left: 6px; margin-top: -1px; width: 100px; display: inline-block;\">正则表达式</span>\r\n");
out.write(" </div>\r\n <div style=\"clear: both; margin-top: 10px;\">\r\n <p><span style=\"color: #ff0000;\">提示:</span>快捷键(Ctrl + B),再次按下可关闭。</p>\r\n");
out.write(" <p><span style=\"color: #ff0000;\">说明:</span>正则相关文档请参考JavaScript正则表达式 。</p>\r\n");
out.write(" </div>\r\n <div style=\"text-align: center;\">\r\n <input id=\"grep-close\" type=\"button\" class=\"grep-button\" value=\"取消\"/>\r\n");
out.write(" </div>\r\n</div>\r\n</body>\r\n</html>");
out.flush();
}
项目源码下载地址
链接:https://pan.baidu.com/s/1LKEIes6R4IUQo-ZOnZLtJw
提取码:WSSB
文章来源:https://blog.csdn.net/qq_20025777/article/details/135085188
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!