我需要扫描日志文件以查找运行某些SQL语句(DROP,CREATE等)的用户,并返回与用户有关的数组以及他们尝试使用的SQL ddl(删除,创建等)。
我有一些日志文件,通常每一行看起来像这样:
'2019-01-14T-19:23:50Z UTC' [ db=dev user=joeschmoe pid=123 userid=1 xid=1234]' Log: Select *
但是,有时select语句会跨越多行,如下所示:
'2019-01-14T19:23:50Z UTC [ db=dev user=rb pid=16 userid=1 xid=8 ]' LOG: SELECT SUM (num_queries) num_all_queries
,SUM (CASE WHEN lalala is not null THEN num_queries ELSE 0 END) num_b
,SUM (CASE WHEN lalala is null THEN num_queries ELSE 0 END) num_non_b
,SUM (total_queue_time_min) total_queue_time_min
,SUM (CASE WHEN lalala is not null THEN total_queue_time_min ELSE 0 END) b_total_queue_time_min
,SUM (CASE WHEN lalala is null THEN total_queue_time_min ELSE 0 END) non_b_total_queue_time_min
,SUM (CASE WHEN lalala is not null THEN duration_s ELSE 0 END)/60.0 total_burst_usage_min
,SUM (CASE WHEN lalala is not null THEN 1 ELSE 0 END) num_lalalas
,MIN(firsttime) mintime
,MAX(lasttime) maxtime
,DATEDIFF (seconds, mintime, maxtime) workload_duration_s
,wration_s/60.0 workload_duration_min
LEFT JOIN (SELECT b FROM STfdaf LIMIT 1) sq ON sq.but_reon < 100
;
我正在为SQL语句中的某些关键字组合这些日志。我可以编写正则表达式来处理该问题,但我需要帮助以一种可以使用的格式获取此日志。我最初使用的是for循环和正则表达式
for line in input:
user_match = re.search("DROP", line, re.IGNORECASE)
这是不准确的,因为当sql语句跨越多行时,如果DROP在初始行之后出现多行,我将无法将“ DROP”绑定回“ USER”。
我不确定该怎么做。是否将文本文件转换为python列表,并以编程方式将多行合并为一个或任何其他选项。
答案 0 :(得分:1)
我通过将用户值存储在一个变量中解决了这个问题,该变量仅在使用RegEx找到匹配项时才会更新。因此,如果找到了关键字,则最后存储在变量中的用户值将与关键字一起返回。
for line in input:
error = []
user_match = re.search("USER=b[0-9]{6}", line, re.IGNORECASE)
serviceuser = re.search("USER=[a-z0-9]*", line, re.IGNORECASE)
if serviceuser:
user = (serviceuser.group().split("=")[1])
elif user_match:
user = (user_match.group().split("=")[1])
ddl = re.search(
"LINK|.DELETE.|INSERT|TRIGGER|TRUNCATE|UPDATE|WRITE", line, re.IGNORECASE)
if ddl:
error.append(user)
error.append(ddl.group())