Pygrok是一个开源的Python字符串解析库,github地址:https://github.com/garyelephant/pygrok。正如其项目主页所述,它可以用来解析字符串形式的log, event等,将字符串中有用信息提取出来。这个字符串解析库支持正则表达式匹配,它提供了众多预定义的字符串匹配模式,既有正则表达式的超强匹配能力,又有简单的易用性。pygrok底层也是利用正则表达式实现的。
使用pygrok只需要了解一个简单的接口grok_match(),一个简单的例子:
我们的任务是从'gary is male, 25 years old and weighs 68.5kilograms'这样的字符串中获得“姓名”,“性别”,“年龄”,“体重”信息。>>> import pygrok >>> text = 'gary is male, 25 years old and weighs 68.5 kilograms' >>> pattern = '%{WORD:name} is %{WORD:gender}, %{NUMBER:age} years old and weighs %{NUMBER:weight} kilograms' >>> print pygrok.grok_match(text, pattern) {'gender': 'male', 'age': '25', 'name': 'gary', 'weight': '68.5'}Pattern是为需要解析的字符串定义好的匹配模式,以使grok_match()知道如何进行匹配。
WORD,NUMBER,是模式的名称。WORD代表要匹配的一个单词,相当于正则表达式的“\b\w+\b”,NUMBER代表要匹配的是一个数字(整数或包含小数点),相当于正则表达式的“(?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+)))”。看起来有点晦涩复杂,但是一般使用时无需关注这些细节,只需要使用“NUMBER”来匹配数字即可,pygrok提供了多个通过模式名称即可明白其可匹配内容的模式,如“IP”,” QUOTEDSTRING”, “DATE”。看,多简单!!
%{WORD:name}的意思是要匹配一个单词,这个单词提取出来后可以通过“name”引用。其他的类似。所以最后得到结果:{'gender': 'male', 'age': '25', 'name': 'gary','weight': '68.5'}
这个例子太简单吗?来个高大上的,从nginxlog中获取domain, ip, timestamp, uripath, referrer, web browser:
>>> import pygrok >>> text = 'edge.v.iask.com.edge.sinastorage.com 14.18.243.65 6.032s - [21/Jul/2014:16:00:02 +0800]' \ ... + ' "GET /edge.v.iask.com/125880034.hlv HTTP/1.0" 200 70528990 "-"' \ ... + ' "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)' \ ... + ' Chrome/36.0.1985.125 Safari/537.36"' >>> pat = '%{HOST:host} %{IP:client_ip} %{NUMBER:delay}s - \[%{DATA:time_stamp}\]' \ ... + ' "%{WORD:verb} %{URIPATHPARAM:uri_path} HTTP/%{NUMBER:http_ver}" %{INT:http_status} %{INT:bytes} %{QS}' \ ... + ' %{QS:client}' >>> m = pygrok.grok_match(text, pat) >>> import pprint >>> pprint.pprint(m, indent = 4) { 'bytes': '70528990', 'client': '"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36"', 'client_ip': '14.18.243.65', 'delay': '6.032', 'host': 'edge.v.iask.com.edge.sinastorage.com', 'http_status': '200', 'http_ver': '1.0', 'time_stamp': '21/Jul/2014:16:00:02 +0800', 'uri_path': '/edge.v.iask.com/125880034.hlv', 'verb': 'GET' }
这里又出现了几个模式:INT,匹配整形数字;IP,匹配ip v4或ipv6;HOST,匹配域名;URIPATHPARAM,匹配http://后面的url地址及参数。正如开始所说,既有正则表达式的超强匹配能力,又有简单的易用性。
(图片来源:http://kovshenin.com/2014/fail2ban-wordpress-nginx/)
(图片来源:http://www.greenleafheatingandcooling.com/high-efficiency/)
转载本文请注明作者和出处[Gary的影响力]http://garyelephant.me,请勿用于任何商业用途!
Author: Gary Gao( garygaowork[at]gmail.com) 关注互联网、分布式、高性能、NoSQL、自动化、软件团队
支持我的工作: https://me.alipay.com/garygao