使用偶发多行日志分析日志数据

时间:2019-01-22 22:04:23

标签: python-3.x

我需要扫描日志文件以查找运行某些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列表,并以编程方式将多行合并为一个或任何其他选项。

1 个答案:

答案 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())