gpt4 book ai didi

python - 重构多线程日志文件的pyparsing解析结果

转载 作者:行者123 更新时间:2023-12-01 09:19:05 25 4
gpt4 key购买 nike

我有一个多线程进程的日志文件,如下所示:

<timestamp_in> <first_function_call_input> <thread:1>
input_parameter_1: value
input_parameter_2: value

<timestamp_in> <another_function_call_input> <thread:2>
input_parameters: values
<timestamp_out> <another_function_call_output> <thread:2>
output_parameters: values

<timestamp_out> <first_function_call_output> <thread:1>
output_parameters: values

在我的解析结果变量中,我希望将一个函数调用的输入和输出信息配对在一起,例如如下所示:

>>> print(parse_results.dump())
-[0]:
-function: first_function
-thread: 1
-timestamp_in: ...
-timestamp_out: ...
-input_parameters:
[0]:
-parameter_name: input_parameter_1
-parameter_value: value
[1]:
-parameter_name: input_parameter_2
-parameter_value: value
-output_parameters:
[0]: ...
...
-[1]:
-function: another_function
-thread: 2
...

有没有办法在解析时直接重组parse_results,这样我就不必在之后重组结果?也许有一些解析操作?或者直接解析输入部分和输出部分,然后按线程、时间戳和函数对它们进行排序,并将输入部分和输出部分拼接到一个新对象中会更容易吗?

感谢您的帮助!

编辑:
我将在分别解析输入部分和输出部分后对它们进行排序,这似乎更容易。但是,我仍然想知道是否以及如何可以重构解析结果实例。假设我有以下语法和测试字符串:

from pyparsing import *

ParserElement.inlineLiteralsUsing(Suppress)
key_val_lines = OneOrMore(Group(Word(alphas)('key') + ':' + Word(nums)('val')))('parameters')

special_key_val_lines = OneOrMore(Group(Word(printables)('key') + ':' + Word(alphas)('val')))('special_parameters')

log = OneOrMore(Group(key_val_lines | special_key_val_lines))('contents').setDebug()

test_string ='''
foo : 1
bar : 2
special_key1! : wow
another_special : abc
normalAgain : 3'''

parse_results = log.parseString(test_string).dump()
print(parse_results)

输出如下:

- contents: [[['foo', '1'], ['bar', '2']], [['special_key1!', 'wow'], ['another_special', 'abc']], [['normalAgain', '3']]]
[0]:
[['foo', '1'], ['bar', '2']]
- parameters: [['foo', '1'], ['bar', '2']]
[0]:
['foo', '1']
- key: 'foo'
- val: '1'
[1]:
['bar', '2']
- key: 'bar'
- val: '2'
[1]:
[['special_key1!', 'wow'], ['another_special', 'abc']]
- special_parameters: [['special_key1!', 'wow'], ['another_special', 'abc']]
[0]:
['special_key1!', 'wow']
- key: 'special_key1!'
- val: 'wow'
[1]:
['another_special', 'abc']
- key: 'another_special'
- val: 'abc'
[2]:
[['normalAgain', '3']]
- parameters: [['normalAgain', '3']]
[0]:
['normalAgain', '3']
- key: 'normalAgain'
- val: '3'

如何修改解析器的语法,使 parse_results.contents[2].parameters[0] 变为 parse_results.contents[0].parameters[ 3]

最佳答案

纯粹是对在哪里划清界限的判断,我已经用两种风格编写了解析器。

在这种特殊情况下,我的直觉告诉我,如果您将解析器和解析操作集中在对各个日志条目的各个部分进行分组、转换和命名,然后使用单独的方法来重新组织,那么将会生成更清晰的代码它们基于您的各种分组策略。我的推理是,日志消息结构已经有些复杂,因此您的解析器将有足够的工作要做,以将每条消息提取为统一的形式。此外,您的分组策略可能会发生一些变化(需要收集某个小时间窗口内的项目,而不仅仅是精确的时间戳匹配),并且在单独的后处理方法中执行此操作将本地化这些更改。

从测试的角度来看,这还允许您将重组代码与解析代码分开测试,也许使用字典或命名元组列表来模拟来自单独日志记录的解析结果。

tl;dr - 对于这种情况,我会使用后处理方法来对解析的日志记录进行最终排序/重组。

编辑:要就地修改解析结果,请定义一个采用单个参数的解析操作,我通常将其命名为“标记”,并使用典型的列表或字典突变器就地修改:

def rearrange(tokens):
# mutate tokens in place
tokens.contents[0].parameters.append(tokens.contents[2].parameters[0])

log.addParseAction(rearrange)

如果返回 None(如本例所示),则传入的标记结构将保留为要返回的标记结构。如果返回非 None 值,则新的返回值将替换解析器输出中的给定标记。这就是整数解析器将解析后的字符串转换为实际整数的方式,或者日期/时间解析器将解析后的字符串转换为 Python datetimes 的方式。

关于python - 重构多线程日志文件的pyparsing解析结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50958427/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com