简介:

日志监控提供了针对日志内容的实时监控能力。通过云监控服务和云日志服务的结合,用户可以针对日志内容进行监控统计、设置告警规则等,降低用户监控日志的运维成本,简化用户使用监控日志的流程。

前情提要:

本文主要针对日志文件的监控、解析、入库,至于监控统计、告警等的操作,并没有说明,如果要完成整套日志收集、分析和展示的功能,建议使用ELK (企业级解决方案)。

ELK简介参见:【ELK学习笔记】ELK的简介_大龄码农生活的博客-CSDN博客_elk学习

核心思路:

利用Commons IO 监听器 监听项目的日志文件目录,解析出日志内容,存储到MongoDB中。

优点:相对于日志文件中的内容,存储到MongoDB显然更便于我们的查看和有条件的筛选。

效果如下: 

实现:

添加Commons IO 依赖

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.2</version>
</dependency>

编写监听器类: 

用到的方法:一个是监听文件创建的onFileCreate方法,一个是监听文件修改的onFileChange方法

@Component
public class FileListener extends FileAlterationListenerAdaptor {

    @Override
    public void onStart(FileAlterationObserver observer) {
        System.out.println("==============Start Listening==============");
    }

    @Override
    public void onDirectoryCreate(File directory) {
        System.out.println("==============Directory Creating==============");
    }

    @Override
    public void onDirectoryChange(File directory) {
        System.out.println("==============Directory Changing==============");
    }

    @Override
    public void onDirectoryDelete(File directory) {
        System.out.println("==============Directory Deleting==============");
    }

    /**
     * 监听文件的创建方法
     * @param file
     */
    @Override
    public void onFileCreate(File file) {
       
        String fileName = file.getName();
        System.out.println("onFileCreate,file=" + fileName);

         //解析文件  ...
   
    }

     /**
     * 监听文件的修改方法
     * @param file
     */
    @Override
    public void onFileChange(File file) {
       
        String fileName = file.getName();
        System.out.println("onFileChange,file=" + fileName);

        //解析文件 ...
    }

    @Override
    public void onFileDelete(File file) {
        System.out.println("onFileDelete,file=" + file.getName());
    }

    @Override
    public void onStop(FileAlterationObserver observer) {
        System.out.println("onStop");
    }
}

因为我们是做的日志监控操作,所以对我们来说日志文件的内容的变化,一定要全部记录下,不然就是功能不完整。

所以,我们要分析一些情况:

正常的流程,一个文件初次创建时是空的,然后我们只需要在change方法中去读取它,然后因为每次change方法监控到的是目录下有文件内容变化的这个文件,所以读取时就需要我们记录读取到的行号,不然每次都有重复读取的部分,实现的话方式很多种,目的就是保证完整性的同时不能浪费资源。 可以做如下记录,相当于走了一点小业务。

文件读取记录表:

非正常流程:我们可能从别的地方直接copy一个有内容的文件,这个时候话要考虑,我们要不要不处理它,让change方法处理,似乎可以,但是如果这个文件放进去就不再改变了呢? 所以对于这种情况我们要在create方法中就读取、解析、入库并且记录行号,然后加入后续有改动,和我们的change方法中的逻辑也不冲突,这是需要注意的一个点。

具体的文件解析

这里其实没有什么难点,主要就是IO读取文件,整行读取,然后切割,存对象,读取完毕存MongoDB,只需要注意一个地方就是,关于日志文件格式比较繁杂我们无法解析的问题,这个说来有点搞笑,当时也有这样傻呵呵的想过,但是其实这个真没必要,因为我们用的是logback框架,添加的logback配置文件,这样的话,日志文件内容的格式是我们自己给定的,我们为什么要难为自己呢? hh

监听器及核心内容完成以后就是监听器工厂和Runner的封装,代码如下,效果就是项目启动时就让监听器跑起来,监听器工厂主要用来指定监听目录

代码附上:

  =================监听器工厂 =================

@Slf4j
@Component
public class FileListenerFactory {

    @Autowired
    FileListener fileListener;

    /**
     * 获取一个 监听目录的线程
     *
     * @return 执行线程
     */
    public FileAlterationMonitor getMonitor() {

        // 创建一个文件观察器
        FileAlterationObserver observer = new FileAlterationObserver("监听目录");

        //  向监听者添加监听器
        observer.addListener(fileListener);

        //创建文件监控中心  构造一个默认间隔为10秒的监视器。
        FileAlterationMonitor monitor = new FileAlterationMonitor(10000);

        //监控器中封装观察器对象
        monitor.addObserver(observer);

        // 返回监听者
        return monitor;
    }
}

  =================Runner=================

@Component
@Slf4j
public class ApplicationBizRunner implements ApplicationRunner {

    @Autowired
    FileListenerFactory fileListenerFactory;

    @Autowired
    Executor customExecutor;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        FileAlterationMonitor monitor = fileListenerFactory.getMonitor();
        monitor.start();
        System.out.println("***************监控开始***************");
    }
}

注意这三个对象都要交给IOC容器管理,项目运行,监控就开始了

效果如下:

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐