从日志记录中提取特定信息

网友投稿 612 2022-05-30

前言

论文数据需要,需要实现从服务器日志中提取出用户的特定交互行为信息。日志内容如下:  自己需要获取“请求数据包一行的信息”及“OUTSTR”下一行的信息。

思路

考虑使用正则表达式提取特定信息。

示例代码:

Pattern pattern = Pattern.compile("请求数据包信息:\"(.+?)\""); Matcher matcher = pattern.matcher("请求数据包信息:\"index.html\""); if(matcher.find()) System.out.println(matcher.group(1));

考虑到日志中数据格式特点,利用上述方式并不可行。不过还是应该考虑使用正则解决以上问题。

初步处理后的文档内容如下:

分析以上信息,需要进一步进行处理,将每个用户的信息进行单独抽取并存入到数据库中。 作为实验,先单独获取一用户的数据。但是由于服务端返回数据无任何用户标识,而且返回信息无任何交易标识,仍需添加。需要对日志做进一步的处理操作。添加信息如下:

通过将json格式的字符串转换为json对象。并获取到指定信息,如下所示:

为了提取出每个用户的交互序列,实现方法如下:将日志中的交互序列按照用户ID分别建立相应的文件夹。将同一用户的请求与输出信息输出到同一用户ID的文件内。内容如下:

文件内容如下:

通过分析分类后的文件内容,可以发现,由于存在某些耗时交易,故会出现多个请求、输出交叉显示的情况。

针对这种情况,在服务端返回信息中加入了uid,tx_code信息,如下所示:

那么就需要将服务端返回信息与请求信息进行配对操作。

考虑到交易的混合,服务端返回信息的混合,必须假设一种理想情况之下的处理。否则,处理起来过于费劲。

前提:客户端的请求与服务端的响应按照线性顺序出现,一一对应。

Ti、To到底存放什么类型的数据?Json中的key还是json对象?

只是单纯存储key的话,Ti、To基本上毫无用处,无法完成基于内容的行为预测与预警。

存储json对象的话,数据量会非常庞大,应给与调整。到底应该进行怎样的数据调整?只提取“重点信息”。例如交易金额,药品种类。

还是应该结合系统说明文档来做,将事件的输入、输出自动添加进(重点考虑输入输出内容)。

这样问题的思路就很清晰了。

考虑将交易时间写入数据表中,便于得出交易序列。同时可考虑将时间因素添加进去,做服务推荐(协同过滤,加入时间维度)。例如:在什么时间购买了什么药品,可得出在这一时间段内该用户易的某种疾病的推测。

日志信息的筛选:对于用户行为序列中只存在一个事件的情况可考虑忽略不计。对于分析用户的习惯无用。

获取到指定信息后,需要将其存入数据库中。数据表内容如下:

1.静态属性表(lab_static_attribute)

表名:lab_static_attribute

主键:uid,login_time,out_time,last_time

字段名

中文名

类型

备注

uid

用户ID

Varchar(11)

uid

login_time

登陆时间

Varchar(1)

0   24:00-1:00

1   1:00-2:00

2   2:00-3:00

.

.

23  23:00-24:00

out_time

登出时间

Varchar(1)

0   24:00-1:00

1   1:00-2:00

2   2:00-3:00

.

.

23  23:00-24:00

last_time

在线时长

Int(3)

以秒为单位

2.动态序列表(lab_dynamic_order)

表名:lab_dynamic_order

主键:uid,tid,t_next

字段名

中文名

类型

备注

uid

用户ID

Varchar(11)

uid

tid

事务ID

Varchar(4)

ti

输入参数

Varchar(50)

tout

输出结果

Varchar(50)

t_next

路由下一跳

Varchar(4)

下一个可执行路由

weight

路由权重

Int(3)

每条路由之间的权重

t_time

交易时间

Varchar(19)

接下来的工作就是建立数据库,并实现数据库的操作。

好长时间不涉及到数据库的操作了,发觉自己已经变得生疏了。还得拾起来啊。

PS:中间出了点问题,令自己很是头痛。由于数据库的操作包括肯定会涉及到增删改查,所以自己的方法得更改一下了,但是直接使用“立马送药”项目的数据库操作方法时,却出现了数据表只能读,不能写的状况。自己需要一步步的排查问题,看看使用lmapp的数据表是否可以使用。

经过阅读“立马送药”中数据库操作的有关代码,自己还是发现了一些端倪。MyDatabase.commit();这句意味深长。在操作之后添加这句后,居然就可以往数据库中写数据了。

通过实际操作,实现了数据库的连接及新增Demo操作。接下来就需要将提取到的真实数据写进数据库存储。

关于数据表lab_dynamic_order中ti与tout的存储内容问题探讨

首先注意到各交易的输入、输出参数的键是不同的,所以不可能在数据表中以字段形式展现,而是应该整体存储在数据表内。结合以下用户日志信息分析。

可得相应信息如下表所示,时间因素已在数据表中记录,故输入参数ti中不再体现。

tid

ti

tout

9015

{“stat”:“1”}

{“cnt”:0}

9101

{null}

{"data":[{"advid":"2","url":"AngularJSunny.jpg"},...,{"advid":"5","url":"VIP.jpg"}]}

9104

{“version”:“1.2”}

{"errtext":"当前已是最新版本"}

receiver:{"old_billid":"","addrid":"6","shopid":"S18853883587","msg":"","yhhdid":"YH00000019","yhhdamt":2,"yhqid":"","yhqcnt":0,"yhqamt":0,"cnt":1,"meddata":[{"medid":"TH20013063","medcnt":1,"cfid":""}],"version":"1.0","fore_time":"2016-03-18 15:53:06","uid":"18353102068","tx_code":"3002"}

刚才在手机端模拟了用户操作,明天记得将2016-05-16的日志提取出来。

通过再一次分析日志,发现自己的筛选方法存在问题。应该以“receiver:”开头的字符串作为输入参数的提取点。

以用户轨迹为线索,用户轨迹行为如下:

登录(1002)-->搜索药品(9002)-->选择地址(1004)-->提交订单(3002)

tid

ti

tout

1002

{“phone”:“18353102068”}

{“result”:登陆结果}

9002

{“classid”:分类编号}

{“pcnt”:返回数量}

9005

{“shopid”:药店编号}

{“pcnt”:返回数量}

9101

{null}

从日志记录中提取特定信息

{“data”:广告详情}

9103

{“advid”:广告编号}

{“url”:广告链接}

1004

{null}

{"addrs":[{"receiver":"孙华强","tel":"18853883586","addr":"北京市北京市朝阳区112号","addrid":1}]}

3002

{"old_billid":"","addrid":"1","shopid":"S18853883587","msg":"","yhhdid":"YH00000019","yhhdamt":2,"yhqid":"","yhqcnt":0,"yhqamt":0,"cnt":4,"meddata":[{"medid":"TH20013063","medcnt":1,"cfid":""},{"medid":"TZ44021940","medcnt":1,"cfid":""},{"medid":"TH10940251","medcnt":1,"cfid":""},{"medid":"TB20020918","medcnt":1,"cfid":""}]

{"billid":"LM201605163586476"}

注意其中的输入输出参数是经过筛选之后提取出来的。为此需要写一个工具类,用来提取特定的输入输出参数。

测试情景1:

输入:整理后的单用户日志

18353102068:1002-->9002-->9002-->9002-->9005-->1004-->3002

输出:静态统计表、动态统计表

编辑

测试情景2:

输入:整理后的多用户日志

18353102068:1002-->9002-->9002-->9002-->9005-->1004-->3002

18353102066:1002-->9002-->9005-->1004-->3002

输出:静态统计表、动态统计表

编辑

测试情景3:

输入:整理后的包含匿名用户日志

18353102068:1002-->9002-->9002-->9002-->9005-->1004-->3002

18353102066:1002-->9002-->9005-->1004-->3002

$tempuser:9002-->9005-->9101-->9103

输出:静态统计表、动态统计表

测试情景4:

输入:整理后的交叉请求案例日志

输出:静态统计表、动态统计表

测试情景5:

输入:整理后的单用户多阶段日志

注:测试需在case长度至少为2的情况下进行。

18353102068:1002-->9002-->9002

18353102068:1002

输出:静态统计表、动态统计表

测试情景6:

输入:整理后的多用户多阶段日志

注:测试需在case长度至少为2的情况下进行。

18353102068:1002(2016-05-16 11:27:45)-->9002-->9002(2016-05-16 11:27:47)

18353102066:1002(2016-05-16 12:27:45)-->1004-->3002(2016-05-16 12:37:54)

18353102068:1002(2016-05-17 11:27:45)

-->9002-->9002-->9002-->9005-->1004-->3002(2016-05-17 11:27:54)

18353102066:1002(2016-05-17 11:27:45)

-->9002->9005-->1004-->3002(2016-05-17 11:27:54)

输出:静态统计表、动态统计表

编辑

测试情景7:

输入:整理后的包含匿名用户多阶段日志

注:测试需在case长度至少为2的情况下进行。

1.18353102068:1002(2016-05-16 11:27:45)-->9002-->9002(2016-05-16 11:27:47)

2.18353102066:1002(2016-05-16 12:27:45)-->1004-->3002(2016-05-16 12:37:54)

3.18353102068:1002(2016-05-17 11:27:45)

-->9002-->9002-->9002-->9005-->1004-->3002(2016-05-17 11:27:54)

4.18353102066:1002(2016-05-17 11:27:45)

-->9002->9005-->1004-->3002(2016-05-17 11:27:54)

5.$tempuser:9002(2016-05-17 11:35:54)-->9005-->9101-->9103(2016-05-17 11:39:54)

6.18353102066:1002(2016-05-17 12:27:45)-->1004-->3002(2016-05-17 12:37:54)

7.$tempuser:9002(2016-05-17 12:35:54)-->9101-->9103(2016-05-17 12:39:54)

输出:静态统计表、动态统计表

测试情景8:

输入:实际用户日志

问题

查看日志内容:

receiver:{"version":"1.0","fore_time":"2016-05-16 20:21:04","uid":"$tempuser","tx_code":"1001"}

receiver:{"version":"1.0","fore_time":"2016-05-16 20:21:22","uid":"$tempuser","tx_code":"1002"}

实际日志中居然出现了上面的请求信息。1001为注册交易应该对应参数“phone”和“passwd”,但请求中并未包含,这是什么原因?

交易1001(注册)、1002(登录)均涉及到加密传输,在逻辑上可以解释以上现象。移动端1001(注册交易)代码如下:

var data = {}; appCallServer($http, "1001", data, function(data) { $ionicLoading.hide(); var key = data.publickey; // 在此调用测试加密 var passwd = password; // 用户密码提交至此 data = { "phone": phonenum, // 用户名提交至此 "passwd": MyRsaEncrypt(key, passwd) }; appCallServer($http, "1001", data, function(data) { if (data.result == "0000") { $ionicLoading.show({ template: "注册成功" }); $timeout(function() { $ionicLoading.hide(); $scope.gotoLogin(phonenum, password); }, 1000); } }); }, function(data) { $ionicLoading.show({ template: data.errtext }); $timeout(function() { $ionicLoading.hide(); }, 1000); });

客户端实现的业务逻辑是首先调用一次1001(此次请求参数为空),获取到服务端返回的公钥后,利用此公钥对用户所输入的密码进行加密操作。再次调用1001(此次请求参数为phone,passwd),完成用户的注册。1002逻辑同此。至此,以上问题得到了解释。

为此,通过更改服务端逻辑:在1001,1002调用之前使用0000获取公钥,这样就符合了自己的筛选规则:去除0000。

if(b.contains("result") && !"0000".equals(tx_code)){....}

整理后的日志中不会再出现1001、1002均不会存在不存在“phone”参数的现象。

注:在进行实际日志测试的时候遇到了瓶颈,交易紊乱,输入输出紊乱问题尤为突出。难道是生成日志方式有问题?

$tempuser:1001(2016-05-16 20:21:04)-->9101-->9103(2016-05-17 12:39:54)

18353102068:9104(2016-05-16 11:27:10)-->9101-->9002(2016-05-16 11:27:47)

编辑

输出:静态统计表、动态统计表

未完待续.....

参考文献

1.Java进阶(九)正则表达式_No Silver Bullet的博客-CSDN博客_java正则表达式1到9

2.在线JSON校验格式化工具(Be JSON)

JSON 数据库

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:MindSpore21天实战营(3)使用MindSpore实现Resnet50毒蘑菇识别
下一篇:唯快不破:Web 应用的 13 个优化步骤
相关文章