log2seq python工具包的使用


前言

Log2seq是一个能够将原始的日志数据转化为word sequence的python开源工具包,如原始日志内容为:
Jan  1 12:34:56 host-device1 system[12345]: host 2001:0db8:1234::1 (interface:eth0) disconnected

该工具包能够将日志中的每一项都给提取出来,如提取出时间、日期、产生日志的组件以及日志的内容等,其中对于日志的内容,它还可以将里面的内容进行切分,比如切分出IP地址等等,相当于对日志数据进行预处理,以便未来更好地进行日志分析。

项目github地址: Log2seq


一、预备

一条日志实际上包含两个部分,一个是Header,一个是Statement。前者是指示日志时间、日期、级别等信息的字段,如前言中的Jan 1 12:34:56 host-device1,后者则是指日志本身的content,如前言中的后半部分。与之相对的,Header一般结构很规律,而Statement则是没有规律的,不同的组件产生的Statement基本上是完全不同的。因此,Log2seq对两部分分开处理。虽然是分开处理,但会提供一个接口让使用者可以一步到位。在接下来讲述也将按照这样的逻辑顺序。

二、Header的处理

1.基本概念

在Header的处理中,由于其结构规律的特征,一般都是 “特征1 特征2。。”这样的结构,因此将这里面的特征称为Item,Item是一个抽象的类,我们都知道Item肯定有不同的类型,比如字符串类型或者时间日期的类型又或者int类型,因此抽象类引申出了能够提取不同内容的Item子类。

2.Header的使用

在这里最重要的类就是log2seq.header.HeaderParser
在进行日志异常检测的比赛中,有如下日志数据
10001 2021-05-21 15:47:36.440 378166 DEBUG oslo_concurrency.processutils [req-32fe6dfe-d5fe-47d9-b208-12232e73c90a - - - - -] Running cmd (subprocess): /usr/bin/python2 -m oslo_concurrency.prlimit --as=1073741824 --cpu=2 – env LC_ALL=C LANG=C qemu-img info /var/lib/nova/instances/3ad77c0d-f281-408d-8c08-ebd39514a014/disk execute /usr/lib/python2.7/site-packages/oslo_concurrency/processutils.py:344
对应意义分别是:LineId,Date,Time,Pid,Level,Component,ADDR,Content
要想把各项分别提取出来,用如下代码:

from log2seq import header


lineid_item = header.Digit('LineId')
date_item = header.UserItem(name='Date',pattern=r'\d{4}-\d{2}-\d{2}')
time_item = header.UserItem(name='Time',pattern=r'\d{2}:\d{2}:\d{2}\.\d{2,3}')
pid_item = header.Digit('PId')
level_item = header.UserItem(name='Level',pattern=r'[a-zA-Z]+')
component_item = header.UserItem(name='Component',pattern=r'[a-zA-Z_]+\.[a-zA-Z_]+')
addr_item = header.UserItem(name='ADDR',pattern=r'[a-zA-Z0-9\s-]+')
statement_item = header.Statement()

head_par = header.HeaderParser(items=[lineid_item,date_item,time_item,pid_item,level_item,component_item,addr_item,statement_item],
                              full_format=r'<0> <1> <2> <3> <4> <5> \[<6>\] <7>',reformat_timestamp=False)

line = '10001 2021-05-21 15:47:36.440 378166 DEBUG oslo_concurrency.processutils [req-32fe6dfe-d5fe-47d9-b208-12232e73c90a - - - - -] Running cmd (subprocess): /usr/bin/python2 -m oslo_concurrency.prlimit --as=1073741824 --cpu=2 -- env LC_ALL=C LANG=C qemu-img info /var/lib/nova/instances/3ad77c0d-f281-408d-8c08-ebd39514a014/disk execute /usr/lib/python2.7/site-packages/oslo_concurrency/processutils.py:344 \n'
result = head_par.process_line(line)
print(result)
---------------------
result:
{'LineId': 10001, 'Date': '2021-05-21', 'Time': '15:47:36.440', 'PId': 378166, 'Level': 'DEBUG', 'Component': 'oslo_concurrency.processutils', 'ADDR': 'req-32fe6dfe-d5fe-47d9-b208-12232e73c90a - - - - -', 'message': 'Running cmd (subprocess): /usr/bin/python2 -m oslo_concurrency.prlimit --as=1073741824 --cpu=2 -- env LC_ALL=C LANG=C qemu-img info /var/lib/nova/instances/3ad77c0d-f281-408d-8c08-ebd39514a014/disk execute /usr/lib/python2.7/site-packages/oslo_concurrency/processutils.py:344 '}

有几点需要记录:
1.date_item我没有用它提供的类log2seq.header.Date,这是因为用item.pattern后发现其正则不符合该日志的日期格式,所以用它的自定义item类了。time_item也是同理

三、Statement的处理

1.基本概念

Statement的处理是按照顺序进行的,即先进行这一项操作,再进行下一项操作,比如先通过空格进行分词,再给IP地址打标禁止其分割,再通过其他分隔符进行分词。这里面操作的单元叫做一个action。
该处使用的url网络请求的数据。

2.Statement的使用

还是上个日志数据,只用content的内容:
Running cmd (subprocess): /usr/bin/python2 -m oslo_concurrency.prlimit --as=1073741824 --cpu=2 – env LC_ALL=C LANG=C qemu-img info /var/lib/nova/instances/3ad77c0d-f281-408d-8c08-ebd39514a014/disk execute /usr/lib/python2.7/site-packages/oslo_concurrency/processutils.py:344

from log2seq import statement


parser = statement.StatementParser([statement.Split(" ")])
line = 'Running cmd (subprocess): /usr/bin/python2 -m oslo_concurrency.prlimit --as=1073741824 --cpu=2 -- env LC_ALL=C LANG=C qemu-img info /var/lib/nova/instances/3ad77c0d-f281-408d-8c08-ebd39514a014/disk execute /usr/lib/python2.7/site-packages/oslo_concurrency/processutils.py:344'
result = parser.process_line(line)
print(result)
-----------------------
(['Running', 'cmd', '(subprocess):', '/usr/bin/python2', '-m', 'oslo_concurrency.prlimit', '--as=1073741824', '--cpu=2', '--', 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', '/var/lib/nova/instances/3ad77c0d-f281-408d-8c08-ebd39514a014/disk', 'execute', '/usr/lib/python2.7/site-packages/oslo_concurrency/processutils.py:344'], ['', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ''])

三、同时进行header和statement的处理

Log2seq提供了log2seq.LogParser类供使用,为了将以上两个结合在一起,代码如下:

from log2seq import header
from log2seq import statement
import log2seq


line = '10001 2021-05-21 15:47:36.440 378166 DEBUG oslo_concurrency.processutils [req-32fe6dfe-d5fe-47d9-b208-12232e73c90a - - - - -] Running cmd (subprocess): /usr/bin/python2 -m oslo_concurrency.prlimit --as=1073741824 --cpu=2 -- env LC_ALL=C LANG=C qemu-img info /var/lib/nova/instances/3ad77c0d-f281-408d-8c08-ebd39514a014/disk execute /usr/lib/python2.7/site-packages/oslo_concurrency/processutils.py:344 \n'

lineid_item = header.Digit('LineId')
date_item = header.UserItem(name='Date',pattern=r'\d{4}-\d{2}-\d{2}')
time_item = header.UserItem(name='Time',pattern=r'\d{2}:\d{2}:\d{2}\.\d{2,3}')
pid_item = header.Digit('PId')
level_item = header.UserItem(name='Level',pattern=r'[a-zA-Z]+')
component_item = header.UserItem(name='Component',pattern=r'[a-zA-Z_]+\.[a-zA-Z_]+')
addr_item = header.UserItem(name='ADDR',pattern=r'[a-zA-Z0-9\s-]+')
statement_item = header.Statement()

header_par = header.HeaderParser(items=[lineid_item,date_item,time_item,pid_item,level_item,component_item,addr_item,statement_item],
                              full_format=r'<0> <1> <2> <3> <4> <5> \[<6>\] <7>',reformat_timestamp=False)


state_parser = statement.StatementParser([statement.Split(" ")])

par = log2seq.LogParser(header_par,state_parser)
result = par.process_line(line)
print(result)
----------------------------------
result:
{'LineId': 10001, 'Date': '2021-05-21', 'Time': '15:47:36.440', 'PId': 378166, 'Level': 'DEBUG', 'Component': 'oslo_concurrency.processutils', 'ADDR': 'req-32fe6dfe-d5fe-47d9-b208-12232e73c90a - - - - -', 'message': 'Running cmd (subprocess): /usr/bin/python2 -m oslo_concurrency.prlimit --as=1073741824 --cpu=2 -- env LC_ALL=C LANG=C qemu-img info /var/lib/nova/instances/3ad77c0d-f281-408d-8c08-ebd39514a014/disk execute /usr/lib/python2.7/site-packages/oslo_concurrency/processutils.py:344 ', 'words': ['Running', 'cmd', '(subprocess):', '/usr/bin/python2', '-m', 'oslo_concurrency.prlimit', '--as=1073741824', '--cpu=2', '--', 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', '/var/lib/nova/instances/3ad77c0d-f281-408d-8c08-ebd39514a014/disk', 'execute', '/usr/lib/python2.7/site-packages/oslo_concurrency/processutils.py:344'], 'symbols': ['', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']}

总结

log2seq感觉是个很适合做日志处理的库,可以按照自己的需求制作正则表达式然后进行item以及content内容的提取和分词,但是才7颗star,未来前途无量啊。本来我是准备把学习这个库的心得写出来的,想要把整个库讲明白,但是三分钟热度,坚持不下去了。而且也觉得在写的时候不知道该怎么表达,感觉还是官方文档讲的比较清楚,但是官方文档的例子太少了尤其是header的处理。所以建议后面的使用者还是要以官网文档为主,可以看看这篇博客的例子辅助理解,如果能起到抛砖引玉的效果,我会很欣慰的。
by the way,这个库其实还是辅助做log parsing的,我们比赛的日志数据实在是太乱了,后面应该还会再更新一下日志预处理的博客来记录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值