【详解】日志监控
简介:日志监控提供了针对日志内容的实时监控能力。通过云监控服务和云日志服务的结合,用户可以针对日志内容进行监控统计、设置告警规则等,降低用户监控日志的运维成本,简化用户使用监控日志的流程。前情提要:本文主要针对日志文件的监控、解析、入库,至于后续统计、警告等等操作,并没有明确说明,如果要完成整套的日志框架,建议使用ELK框架,而不是手动去写一个日志系统。ELK简介参见:【ELK学习笔记】ELK的简
简介:
日志监控提供了针对日志内容的实时监控能力。通过云监控服务和云日志服务的结合,用户可以针对日志内容进行监控统计、设置告警规则等,降低用户监控日志的运维成本,简化用户使用监控日志的流程。
前情提要:
本文主要针对日志文件的监控、解析、入库,至于监控统计、告警等的操作,并没有说明,如果要完成整套日志收集、分析和展示的功能,建议使用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容器管理,项目运行,监控就开始了
效果如下:
更多推荐
所有评论(0)