一种基于kafka+storm实现的日志记录方法
背景:
在我们系统中,每逢大促经常会遇到活动页面莫名被篡改的情况,有些操作是人为故意修改,比如大促时把某些坑位的商品全部换为某个商家的商品,这里就存在恶意修改页面的问题。每次遇到这种问题,内控合规部 需要找我们提取操作日志,追溯所有篡改记录,查找元凶。
由于活动页面装修可以通过授权给多人装修,我们mysql表里的操作日志只有最后一次修改的状态记录,没有操作流水日志。无法从技术上排除每个被授权人的嫌疑。
当然你可以会觉得解决这个问题很简单,可以首先通过传统的打印日志的方法。但这个种方式有如下缺陷:
1、日志散落在各台应用服务器,要收集齐所有相关日志非常麻烦。
2、由于服务器硬盘资源有限,日志超过一定量或多少天就会被删除,如超过7天就会被删除。
3、我们公司不允许在日志中打印用户的账户等敏感信息。这点是最致命的。
也许你还会想到直接把日志写入的nosql数据库的方式,比如 Mongodb、ES、hbase等nosql数据库。但直接把日志写入到数据库的方式存在很大的性能问题,每打印一条日志都需要消耗几十到几百毫秒不等。严重影响正常业务的性能。
采用kafka+storm异步记录日志方式
借鉴点击流日志上报流程,只是上报客户端从用户的浏览器变成了我们的系统服务器,上报的内容从浏览数据变成了用户操作日志。使用到的技术:java+kafka+storm+hbase。具体流程如下:
1、前期准备工作:预先为每个需要接入该“日志上报工具”的业务系统分配一个系统id,如”sys_A”。在我们的实现中,有一个“业务接入”注册功能:
2、把用java语言实现的向kafka集群指定的“日志topic”发送消息的功能,封装成一个通用的jar包,在每个需要接入该“日志上报工具”的业务系统中引入该jar包。
3、在需要打印用户操作日志的地方,收集系统id、用户信息(账号,ip等)、查询key、用户操作、日志描述、操作时间等信息 组装成一个map。调用通用jar包中的日志打印方法SelfLog.log(map)。
4、在通用jar包SelfLog.log(Map map)方法中,会检查日志参数是否正确(比如,是否包含关键的 “系统id”和“查询key”,因为查询日志时需要根据这两个参数做定位)。检查通过后,把map转换成json字符串发送到指定kafka集群的指定topic中。
向kafka发送消息是个很快的过程,性能消耗几乎可以忽略不计,对正常业务几乎没有影响。同时利用kafka的高吞吐量,每天支持亿级的日志量没有问题。
5、通过storm实时消费kafka的指定“日志topic”,对日志进行解析,并根据“系统id”进行分组,每隔指定时间(比如1分钟)把收集到的日志信息,批量写入hbase的指定表中。这里每隔指定时间向hbase批量写入,主要是为了减少与hbase的交互次数,提升性能。这里指定的间隔时间,就是日志查询的延迟时间,可以做到近乎实时的日志查询。
日志被写入hbase日志表以后,就可以通过编写一个查询hbase的web页面进行日志查询。通过录入相关查询key,一次就可以提取出所有相关的日志信息:
最终效果
1、实现高效的流水日志记录(几乎没有性能消耗)。方便问题追溯。
2、可以打印敏感信息,这些信息最终是存在到hbase表,而不是写到日志文件。
3、相比传统的日志打印方式,日志存储周期更长,可以做到永久存在。日志不再散落在各个应用服务器,查询日志更方便直观。
为了提高日志的查询效率,我们把“查询key”做为hbase日志表rowkey的一部分,所有每次需要打印日志时,需要认真定义这个“查询key”,比如操作某个活动,可以把活动id作为“查询key”。
最后,通过创建更多的“topic”,在storm消费的地方再进行更细分处理,再加上一些权限验证,完全可以把这个工具平台化,提供一个类似“统一日志管理”的日志平台。
上一篇: Java多线程之Semaphore
推荐阅读
-
springMVC自定义注解,用AOP来实现日志记录的方法
-
实现Nginx中使用PHP-FPM时记录PHP错误日志的配置方法
-
基于log4net的日志组件扩展分装,实现自动记录交互日志 XYH.Log4Net.Extend
-
一种基于kafka+storm实现的日志记录方法
-
实现Nginx中使用PHP-FPM时记录PHP错误日志的配置方法
-
基于log4net的日志组件扩展封装,实现自动记录交互日志 XYH.Log4Net.Extend(微服务监控)...
-
基于.net core微服务的另一种实现方法
-
spring boot使用自定义注解+AOP实现对Controller层方法的日志记录
-
Yii框架实现记录日志到自定义文件的方法
-
一种基于记录集查找特定行的方法_MySQL