当前位置: 首页 > 知识库问答 >
问题:

解析日志文件并查找适当的分隔符

颜森
2023-03-14
'2021-05-18T14:01:13Z UTC [ db=dev user=rdsdb pid=11593 userid=1 xid=19771457 ]' LOG: BEGIN;
'2021-05-18T14:01:13Z UTC [ db=dev user=rdsdb pid=11593 userid=1 xid=19771457 ]' LOG: SET datestyle TO ISO;
'2021-05-18T14:01:13Z UTC [ db=dev user=rdsdb pid=11593 userid=1 xid=19771457 ]' LOG: SET TRANSACTION READ ONLY;
'2021-05-18T14:01:13Z UTC [ db=dev user=rdsdb pid=11593 userid=1 xid=19771457 ]' LOG: SET STATEMENT_TIMEOUT TO 300000;
'2021-05-18T14:01:13Z UTC [ db=dev user=rdsdb pid=11593 userid=1 xid=19771457 ]' LOG: /* hash: f71f47211eca32d63469fba576bbbb19 */

SELECT TRIM(application_name) AS application_name
     , MAX(recordtime)        AS last_used
FROM stl_connection_log
WHERE dbname <> 'dev'
  AND username <> 'rdsdb'
  AND (   application_name LIKE 'RedshiftUserLastLogin-v%'
       OR application_name LIKE 'RedshiftSystemTablePersistence-v%'
       OR application_name LIKE 'AnalyzeVacuumUtility-v%'
       OR application_name LIKE 'ColumnEncodingUtility-v%' )
GROUP BY application_name
LIMIT 50
;
'2021-05-18T14:01:13Z UTC [ db=dev user=rdsdb pid=11593 userid=1 xid=19771457 ]' LOG: SELECT btrim( pg_catalog.stll_connection_log.application_name ) AS application_name, MAX(pg_catalog.stll_connection_log.recordtime) AS last_used FROM pg_catalog.stll_connection_log WHERE pg_catalog.stll_connection_log.dbname <> 'dev'::Char(3) AND pg_catalog.stll_connection_log.username <> 'rdsdb'::Char(5) AND (pg_catalog.stll_connection_log.application_name LIKE 'AnalyzeVacuumUtility-v%' OR pg_catalog.stll_connection_log.application_name LIKE 'ColumnEncodingUtility-v%' OR pg_catalog.stll_connection_log.application_name LIKE 'RedshiftSystemTablePersistence-v%' OR pg_cata

我想在每个“行”以引号+时间戳开始时阅读。每一行都以以下内容开头:'2021-05-18t14:01:13z UTC[db=dev user=rdsdb pid=11593userid=1xid=19771457]'(让我们将其称为行分隔符),然后将每一行拆分为相应的列(query、pid、user、db等)。我如何以最简单的方式做到这一点?

问题是行分隔符没有出现在每个换行符上。正如您所看到的,有一个“row”,其中查询位于多个换行符上,因此在python中读取文本文件时,我担心会有几行没有分隔符。那么,这是否意味着,当我在python中从文件中读取行时,我需要首先检查它是否以行分隔符开始,如果不是,则继续将该行追加到内存中,直到到达行分隔符为止?

理想情况下,行:

'2021-05-18T14:01:13Z UTC [ db=dev user=rdsdb pid=11593 userid=1 xid=19771457 ]' LOG: /* hash: f71f47211eca32d63469fba576bbbb19 */

SELECT TRIM(application_name) AS application_name
     , MAX(recordtime)        AS last_used
FROM stl_connection_log
WHERE dbname <> 'dev'
  AND username <> 'rdsdb'
  AND (   application_name LIKE 'RedshiftUserLastLogin-v%'
       OR application_name LIKE 'RedshiftSystemTablePersistence-v%'
       OR application_name LIKE 'AnalyzeVacuumUtility-v%'
       OR application_name LIKE 'ColumnEncodingUtility-v%' )
GROUP BY application_name
LIMIT 50
;
timestamp = 2021-05-18T14:01:13Z UTC
db = dev
user = rdsdb
pid = 11593
userid = 1
xid = 19771457
query = `SELECT TRIM(application_name) AS application_name, MAX(recordtime AS last_used FROM stl_connection_log WHERE dbname <> 'dev' AND username <> 'rdsdb' AND (application_name LIKE 'RedshiftUserLastLogin-v%' OR application_name LIKE 'RedshiftSystemTablePersistence-v% OR application_name LIKE 'AnalyzeVacuumUtility-v%' OR application_name LIKE 'ColumnEncodingUtility-v%' ) GROUP BY application_name LIMIT 50';
'2021-05-18T14:01:13Z UTC [ db=dev user=rdsdb pid=11593 userid=1 xid=19771457 ]' LOG: BEGIN;

被分解为:

timestamp = 2021-05-18T14:01:13Z UTC
db = dev
user = rdsdb
pid = 11593
userid = 1
xid = 19771457
query = `LOG: BEGIN';

共有1个答案

高峻
2023-03-14

您可以使用正则表达式来发现作为行分隔符的行,然后使用groupby()读取分隔符组或查询行组:

from itertools import groupby
import re
import csv

row_delim = re.compile(r"'(.*? UTC) \[ db=(.*?) user=(.*?) pid=(.*?) userid=(.*?) xid=(.*?) \]'")

with open('logfile.txt') as f_input, open('output.csv', 'w', newline='') as f_output:
    csv_output = csv.writer(f_output)
    csv_output.writerow(["timestamp", "db", "user", "pid", "userid", "xid", "query"])

    for re_row_delim, lines in groupby(f_input, lambda x: row_delim.match(x)):
        if re_row_delim:
            last_delim = re_row_delim.groups()
        else:
            query = [line.strip() for line in lines if line.strip()]
            row = [*last_delim, ' '.join(query)]
            csv_output.writerow(row)

这假定参数的顺序是恒定的。

对于给定的测试文件,groupby将首先返回一个有效的re_row_delim,其中包含正则表达式的结果(在lambda函数中),lines是所有分隔符行的列表。由于它们都是相同的,我们只使用键值本身(即re_row_delim)而忽略lines

timestamp,db,user,pid,userid,xid,query
2021-05-18T14:01:13Z UTC,dev,rdsdb,11593,1,19771457,"SELECT TRIM(application_name) AS application_name , MAX(recordtime)        AS last_used FROM stl_connection_log WHERE dbname <> 'dev' AND username <> 'rdsdb' AND (   application_name LIKE 'RedshiftUserLastLogin-v%' OR application_name LIKE 'RedshiftSystemTablePersistence-v%' OR application_name LIKE 'AnalyzeVacuumUtility-v%' OR application_name LIKE 'ColumnEncodingUtility-v%' ) GROUP BY application_name LIMIT 50 ;"
from itertools import groupby
import re
import csv

row_delim = re.compile(r"'(.*? UTC) \[ db=(.*?) user=(.*?) pid=(.*?) userid=(.*?) xid=(.*?) \]' LOG: (.*)")
query_start = []    # holds all text after LOG: lines

with open('logfile.txt') as f_input, open('output.csv', 'w', newline='') as f_output:
    csv_output = csv.writer(f_output)
    csv_output.writerow(["timestamp", "db", "user", "pid", "userid", "xid", "query"])

    for re_row_delim, lines in groupby(f_input, lambda x: row_delim.match(x)):
        if re_row_delim:
            last_delim = re_row_delim.groups()[:6]
            query_start.extend([row_delim.match(line).group(7) for line in lines])
        else:
            query = [line.strip() for line in [*query_start, *lines] if line.strip()]
            row = [*last_delim, ' '.join(query)]
            csv_output.writerow(row)
            query_start = []
 类似资料:
  • 问题内容: 我正在开发一个通过Commons使用Log4J的项目。 我正在尝试找到日志文件的路径,但是没有找到合适的方法来从Logger返回日志文件的路径。 有人尝试过吗? 问题答案: 您必须 从根记录器 获取所有附加程序,然后获取日志文件的名称。

  • 问题内容: 我刚刚开始学习Python,并想读取一个Apache日志文件,并将每行的一部分放入不同的列表中。 文件中的一行 172.16.0.3–[25 / Sep / 2002:14:04:19 +0200]“ GET / HTTP / 1.1” 401-“” Mozilla / 5.0(X11; U; Linux i686; en-US; rv:1.1 )Gecko / 20020827“ 根

  • 问题内容: 我正在尝试解析以这种格式记录的apache日志文件 以下是我正在测试的代码… 一些示例日志是: 关于此日志格式所需的正则表达式过滤器的任何想法? 问题答案: 我现在设法分开了…

  • 本文向大家介绍Python解析nginx日志文件,包括了Python解析nginx日志文件的使用技巧和注意事项,需要的朋友参考一下 项目的一个需求是解析nginx的日志文件。 简单的整理如下: 日志规则描述 首先要明确自己的Nginx的日志格式,这里采用默认Nginx日志格式: 其中一条真实记录样例如下: 其中,客户端型号信息用XXXXXXX代替。 项目中已经按照业务规则对Nginx日志文件进行了

  • 只要是由日志服务 rsyslogd 记录的日志文件,它们的格式就都是一样的。所以我们只要了解了日志文件的格式,就可以很轻松地看懂日志文件。 日志文件的格式包含以下 4 列: 事件产生的时间。 产生事件的服务器的主机名。 产生事件的服务名或程序名。 事件的具体信息。 我们查看一下 /var/log/secure 日志,这个日志中主要记录的是用户验证和授权方面的信息,更加容易理解。命令如下: [roo