我正在参与掘金创作者训练营第6期,点击了解活动详情
最近因为一些原因,需要尝试分析服务器的访问日志,然而,这个日志格式真有些让人难受。空格、括号、引号、连接符都用上了。
$fake_remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$sent_http_content_type" "$http_referer" "$http_user_agent" - $scheme
要是日志都是按照大家平常用的序列化方式多好,管他json也好,protobuffer也罢,完全互逆的过程,如果需要,也省得今日这般麻烦。
现在这日志真就看着心里就烦躁,虽然猜它可能是出于结构紧凑之类的原因才设计成这样的,但还是不爽。输出的时候像模板引擎一样,解析时心里只剩呵呵。
解析日志可以单独写一些函数来解析,但是大概率不值得,比如IP地址、HTTP状态码、时间戳、一个个根据形式匹配,完了还有可能不存在这个字段,如果要这样做的化,这里的工程量还是有一些的。
由于现在计算机性能足够强,这种日志可以靠正则表达式来解析,可能的性能损失一般都可以是可以接受的,而且并不一定有损失,因为jit之类的还有持续的优化。
用了正则表达式很多东西就变得简单了,比如经典的IP地址的匹配。0~255这是一部分,他和.点连续出现三次,再是一个0~255,也就是下面这样
((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))
主要连个很长的部分是一样的,都是标识匹配0~255之间的数字的,看懂了应该不能算难。但是它太长了,一旦要匹配更多其他的东西,组合的长度起来可能让人前一秒还明白,下一秒就是天书了。
按照正常的思路这里应该要做的就是把这些不同用途的正则表达式分开封装,以便于上层使用看起来不会太多繁琐。这就是大名鼎鼎的grok做的事情了。
先前我们说打印就像是模板引擎渲染一样,grok这个好东西可以做到反过来实现效果。像模板一样写出格式,然后就可以匹配出其中的字段,它的底层实现就是正则表达式。
比如说这个东西
23.1.244.1 POST /index.html 15824 - 0.043
grok可以用下面这种表达式匹配
%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} - %{NUMBER:duration}
第一次看到这个的时候,心里的感觉就好像回到家了一样,这表达式看着就爽啊。 大括号里左边是表示定义好的模式,右边是提取的字段。常见的一些模式都已经有测试好可以投入使用的名字。具体可以参考这个www.alibabacloud.com/help/zh/log…。而且如果实在没有需要的pattern,也可以自己定义。