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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。