如何使用PySpark条件多正则解析Web请求日志识别GET ping请求
日志正则匹配与Spark DataFrame字段生成问题
在了解日志相关概念后,我正在处理Web请求日志,需要匹配日志字符串中请求方法为GET的条目,已参考Python风格日志解析及相关帖子内容。
假设我有一段日志行片段如下:
"GET /pas/public/ping?pas-client=007 HTTP/1.1"
完整日志示例如下:
[10/Oct/2021:05:45:20 +0000] SsAzyfdtrfdV1GKU7+Q== user_Zwfikdlo5CgOT0Loq8g== "GET /pas/public/ping?pas-client=007 HTTP/1.1" 200 "-b" 53b 5ms "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)" qFhyYRqbqtsM7tA== 50001 - -
我尝试使用正则匹配API或查询路径中?符号前(即URL参数前)的部分。现有仅含raw单列的Spark DataFrame,我需要判断事件是否为GET HTTP方法且路径包含/ping?,如果满足则新增Type列赋值为GET_ping,否则赋值为POST,预期效果如下:
| raw | Type |
|---|---|
| [10/Oct/2021:05:45:20 +0000] SsAzyfdtrfdV1GKU7+Q== user_Zwfikdlo5CgOT0Loq8g== "GET /pas/public/ping?pas-client=007 HTTP/1.1" 200 "-b" 53b 5ms "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)" qFhyYRqbqtsM7tA== 50001 - - | GET_ping |
当前我编写的代码如下:
# parsing df sdf = (df .withColumn('Type', F .when(F.isnull('raw'), '-') .when(F.regexp_extract('raw', '(?i)^/ping?$', 0) == F.col('raw'), 'ping') #To specify ping activities
该场景为多条件正则匹配场景,需要编写符合要求的条件正则,同时满足以下两个匹配规则:
- 匹配以
"开头后接空格、包含三个字母G、E、T的内容 - 匹配以
/开头、以?结尾、包含四个字母p、i、n、g的内容
解决方案
直接使用组合正则结合PySpark的rlike方法做布尔判断即可,修正后代码如下:
from pyspark.sql import functions as F sdf = df.withColumn('Type', F.when(F.isnull('raw'), '-') .when(F.col('raw').rlike(r'(?i)"GET\s+.*/ping\?'), 'GET_ping') .otherwise('POST') )
正则规则说明
(?i):开启大小写不敏感匹配,兼容GET、get等不同写法的请求方法"GET\s+:匹配双引号开头、后跟GET方法和至少1个空格,满足第一个匹配规则.*:匹配路径中间的任意层级字符/ping\?:匹配以/开头的ping路径、后跟参数前缀?,满足第二个匹配规则
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

