日志筛选工具(三)

service

    /**
     * 正在运行的进程
     */
    private static Map<String, TaskProcess> runningProcess = new ConcurrentHashMap<String, TaskProcess>();

/**
     * 查看其它机器日志
     * @param instanceAddr
     * @param instance
     * @param logFileName
     */
    public static void addAssistantTask(String instanceAddr, String instance, String logFileName, String username, String pwd){
        String processName = instanceAddr + instance;
        //如果没有任务则创建任务
        if(!runningProcess.containsKey(processName)){
            synchronized(CrtRunner.class){
                if(runningProcess.containsKey(processName)){
                    return;
                }
                String jsFile = StatusSupervisor.class.getResource("/log-stg-other.js").getPath();
                jsFile = jsFile.substring(1, jsFile.length());
                try {
                    String ins = instance.replaceAll("_", "-") ;
                    String localLog = crtlogpath + "\\" + ins + "-" + instanceAddr + ".log";
                    //替换非法字符以便生成日志文件
                    localLog = localLog.replaceAll("@", "-");
                    new File(localLog).delete();
                    new File(localLog).createNewFile();
                    Process exec = Runtime.getRuntime().exec("C:\\SecureCRT\\SecureCRT.exe "
                            + "/SCRIPT " + jsFile + " "
                            + "/ARG " + instanceAddr + " "              //机器地址
                            + "/ARG " + instance + " "                  //实例名
                            + "/ARG " + logFileName + " "
                            + "/ARG " + username + " "
                            + "/ARG " + pwd + " "
                            + "/LOG " + localLog + " "
                            + "/PASSWORD " + crtPwd + " "
                            + crtUser + "@ts");
                    runningProcess.put(processName, new TaskProcess(exec, new LogTask(localLog)));
                    tasks.add(processName);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
    }


/**
     * 在实例上注册数据通道
     * @param instanceIp    实例ip
     * @param instance      实例名
     * @param remoteAddr    客户端ip
     * @param token
     * @throws Exception
     */
    public static boolean registerChannel(String instanceIp, String instance, String remoteAddr, String token) throws Exception{
        TaskProcess tp = runningProcess.get(instanceIp + instance);
        if(tp == null){
            throw new Exception("通道已关闭, 请重新连接");
        }
        return tp.getTask().registerChannel(remoteAddr, token);
    }

/**
     * 读取数据
     * @param instanceAddr
     * @param instance
     * @param start
     * @param addr
     * @param channelId
     * @throws Exception
     */
    public static LogTask readData(String instanceAddr, String instance, int start, String addr, String channelId, String filter) throws Exception{
        TaskProcess tp = runningProcess.get(instanceAddr + instance);
        if(null == tp){
            throw new Exception("通道已关闭, 请重新连接");
        }
        return tp.getTask().readData(start, addr, channelId, filter);
    }

    public static class TaskProcess{
        Process process;
        LogTask task;
        public TaskProcess(Process process, LogTask task) {
            super();
            this.process = process;
            this.task = task;
        }
        public Process getProcess() {
            return process;
        }
        public LogTask getTask() {
            return task;
        }
    }

    /**
     * 通道
     *
     */
    private static class Channel{
        private String token;
        //上次活跃时间
        private long lastActiveTime;

        private List<String> cache = new ArrayList<String>();

        public Channel(String token) {
            super();
            this.token = token;
            this.lastActiveTime = new Date().getTime();
        }

        public String getToken() {
            return token;
        }

        public boolean isOutOfDate(){
            return new Date().getTime() - lastActiveTime > CHANNEL_MAX_IDLE_TIME;
        }

        public void addCache(String data){
            this.cache.add(data);
        }

        public List<String> readCache(){
            return cache;
        }

        public boolean hasValidCache(String filter){
            for(String line : cache){
                if(line.toLowerCase().contains(filter.toLowerCase())){
                    return true;
                }
            }
            return false;
        }

        public void clearCache(){
            this.cache.clear();
        }

        /**
         * 刷新访问时间
         */
        public void refresh(){
            this.lastActiveTime = new Date().getTime();
        }
    }
    /**
     * 日志任务类
     *
     */
    public static class LogTask{

        //保存合法的数据通道凭证, key是IP, value是通道号
        Map<String, Channel> channels = new ConcurrentHashMap<String, Channel>();

        //日志文件
        public String logFile;

        //上次访问时间
        private long lastAccess = new Date().getTime();

        public long startTime = new Date().getTime();

        private LineNumberReader reader;

        //最大行数
        private int maxLine = 0;

        //记录上次读取的位置
        private int index;

        private List<String> results;

        private boolean stop = false;

        /**
         * 停止任务
         */
        public void stop(){
            stop = true;
            run = false;
            close();
        }

        public long getLastAccess() {
            return lastAccess;
        }

        /**
         * 检查channel
         */
        public void checkChannel(){
            for(String ip : channels.keySet()){
                if(channels.get(ip).isOutOfDate()){
                    AuditLog.info("remove channel [" + channels.remove(ip) + "], remoteAddr: [" + ip + "]");
                }
            }
        }

        private synchronized void close() {
            try {
                reader.close();
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }

        public boolean registerChannel(String ip, String token){
            if(channels.containsKey(ip)){
                return false;
            }
            channels.put(ip, new Channel(token));
            //并发注册只能有一个人成功
            return channels.get(ip).getToken().equals(token);
        }

        /**
         * 从指定的行开始读取数据
         * @param from
         * @param addr
         * @param channelId
         * @param filter        过滤条件
         * @return
         * @throws Exception
         */
        public synchronized LogTask readData(int from, String addr, String channelId, String filter) throws Exception{
            if(!channels.containsKey(addr) || !channelId.equals(channels.get(addr).getToken())){
                throw new Exception("非法通道");
            }
            channels.get(addr).refresh();

            lastAccess = new Date().getTime();
            List<String> data = new ArrayList<String>();
            if(stop){
                return new LogTask(0, data);
            }
            if(from == 0){
                from = maxLine;
            }
            reader.setLineNumber(from);
            String line = "";
            try {
                int begin = 0;
                while(null != (line = reader.readLine()) && !stop){
                    from++;
                    if(StringUtils.isNotBlank(filter)){
                        //开启过滤器
                        if(line.contains("INFO]") || line.contains("DEBUG]") 
                                || line.contains("FATAL]") 
                                || line.contains("ERROR]")){
                            //新的段落
                            if(channels.get(addr).hasValidCache(filter)){
                                data.addAll(channels.get(addr).readCache());
                            }
                            channels.get(addr).clearCache();
                            begin++;
                        }
                        channels.get(addr).addCache(line.replaceAll("(?i)" + filter, "<label style='color:fuchsia;'>" + filter + "</label>"));

                    }else{
                        data.add(line);
                        begin++;
                    }
                    //单次最大读取100条,防止并发时独占reader
                    if(begin == 100){
                        break;
                    }
                }
                if(channels.get(addr).hasValidCache(filter)){
                    data.addAll(channels.get(addr).readCache());
                    channels.get(addr).clearCache();
                    begin++;
                }
                if(from > maxLine){
                    maxLine = from;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return new LogTask(from, data);
        }

        public LogTask(int index, List<String> data) {
            super();
            this.index = index;
            this.results = data;
        }

        public LogTask(String logFile) throws IOException, InterruptedException {
            super();
            this.logFile = logFile;
            reader = new LineNumberReader(new InputStreamReader(new FileInputStream(logFile),"utf-8")); 
            while(null != reader.readLine()){
                maxLine++;
            }
        }

        public List<String> getResults() {
            return results;
        }

        public int getIndex() {
            return index;
        }

        //标识任务在run
        public boolean run = true;
        public boolean isRun() {
            return run;
        }

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值