在项目部署到正式环境中不免会出现一些bug,出现bug时需要查看日志,为了方便查看日志可以在后台做一个实时Console查看功能!

Controller:

import com.alibaba.fastjson.JSONObject;
import com.xffjs.framework.config.SystemConfig;
import com.xffjs.framework.web.controller.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 实时日志
 *
 * @author xiaofei
 */
@Slf4j
@Controller
@RequestMapping("/tool/console")
public class ConsoleController extends BaseController {

    private String prefix = "tool/console";

    @RequiresPermissions("tool:console:view")
    @GetMapping()
    public String console() {
        return prefix + "/console";
    }

    // *************************************** 业务处理 *************************************************************

    @GetMapping("/list")
    @ResponseBody
    public JSONObject list(Integer start, int type) {
        Map<String, Object> map = new LinkedHashMap<>();
        try {
            File file = null;
            if (0 == type) {
                // 获取info日志路径--换成自己日志所在的位置
                file = new File(SystemConfig.getLogPath() + "system-info.log");
            }else{
                // 获取error日志路径--换成自己日志所在的位置
                file = new File(SystemConfig.getLogPath() + "system-error.log");
            }
            // 由于正式环境日志数据太多建议只显示前10行或者100行
            if (0 == start) {
                int sum = getTotalLines(file);
                start = sum - 10;
            }
            List<String> list = readAppointedLineNumber(file, start);
            StringBuilder sb = new StringBuilder();
            for (String str : list) {
                sb.append(str).append("\n");
            }
            map.put("count", list.size());
            map.put("next", start + list.size());
            map.put("contents", sb.toString());
            JSONObject json = new JSONObject(map);
            return json;
        } catch (Exception ex) {
            ex.printStackTrace();
            map.put("count", 0);
            map.put("next", start);
            map.put("content", "");
            JSONObject json = new JSONObject(map);
            return json;
        }
    }


    /**
     * 根据文件行号获取内容
     */
    List<String> readAppointedLineNumber(File sourceFile, int lineNumber) {
        try {
            FileReader in = new FileReader(sourceFile);
            LineNumberReader reader = new LineNumberReader(in);
            List<String> list = new ArrayList<>();
            if (lineNumber < 0 || lineNumber > getTotalLines(sourceFile)) {
                log.error("不在文件的行数范围之内");
            } else {
                String line = "";
                while ((line = reader.readLine()) != null) {
                    if (reader.getLineNumber() > lineNumber) {
                        list.add(line);
                    }
                }
            }
            reader.close();
            in.close();
            return list;
        } catch (IOException e) {
            log.error("读取文件内容出错!");
        }
        return new ArrayList<>();
    }

    /**
     * 文件内容的总行数。
     */
    int getTotalLines(File file) {
        try {
            FileReader in = new FileReader(file);
            LineNumberReader reader = new LineNumberReader(in);
            String s = reader.readLine();
            int lines = 0;
            while (s != null) {
                lines++;
                s = reader.readLine();
            }
            reader.close();
            in.close();
            return lines;
        } catch (IOException e) {
            log.error("获取文件总行数出现错误");
        }
        return 0;
    }

}

Html:

<div class="col-sm-12 select-table table-striped">
    <textarea id="console" class="span12" readonly="readonly" cols="30" rows="30" style="background: black; color: #00FF00;width: 100%;" placeholder="暂无日志!"></textarea>
</div>

JS:

<script>
    var prefix = ctx + "tool/console";

    var start = 0;
    // 0: info 1: error
    var tyep = 0;

    function info() {
        tyep = 0;
        start = 0;
        $("#console").val("");
        log();
    }
    function error() {
        tyep = 1;
        start = 0;
        $("#console").val("");
        log();
    }

    function log() {
        $.ajax({
            url : prefix + "/list?start=" + start + "&type=" + tyep,
            global : false,
            cache : false
        }).done(function(resp) {
            if (resp) {
                $("#console").val($("#console").val() + resp.contents);
                start = resp.next;
                $("#console")[0].scrollTop = $("#console")[0].scrollHeight;
            }
        });
    }
    $(document).ready(function() {
        log();
    });
</script>

效果: