什么是解析用户定义的方法或 class 写在日志中的构造的更好方法

What is better way to parse user defined methods or class construct written in logs

我有日志,我需要解析和提取传递给方法或 class 构造的值。

例如。日志行如

10-08-2021 08:10:00.345 | 10-08-2021 08:10:00.345 | Debug | test.importA.yada | sometext - [ somefunction(arg1=3,arg2="odd"),somefunction2(arg1=8,arg2="even")].

我需要从上面的行中提取字符串列表(上面的粗体斜体)。并检索参数和函数名称。该列表可以具有相同或不同的功能。

我能够使用正则表达式检索字符串列表,但在从字符串更改为列表后将其作为列表进行迭代,python 抱怨:对象未定义或值错误。为了解决这个问题,我使用了 exec。但是想知道是否有更多 pythonic 方法来做到这一点。

征求专家意见。很正常,我们记录函数入口 - 带参数退出,但我们如何检索它。如果您无权访问这些函数签名或模块,实际上导入所有可能在日志中弹出的函数是不可能的。

给定问题中的 message 值,此 python 将通过 eval(str):

创建有效对象

创建字典列表,函数名和参数为 k,v

import re

msg = u' { "message" : "sometext - [func1(arg1=2,arg2=\'even\'), func1(arg1=3,arg2=\'odd\')]"}'
# get the string representing the list
lstStr = msg.split(' - ')[1][:-2]
#replace 'func1(' with 'dict(...'
arr = re.sub('func1[(]','dict(name="func1",',lstStr)

print(eval(arr)[0])
print(eval(arr)[1])

结果:

{'name': 'func1', 'arg1': 2, 'arg2': 'even'}
{'name': 'func1', 'arg1': 3, 'arg2': 'odd'}

此正则表达式模式 func1[(] 将替换为 dict(name="func1",后者将创建字典并将函数名称添加为项目。

搜索函数名称的正则表达式甚至可以是通用的

msg = u' { "message" : "sometext - [func1(arg1=2,arg2=\'even\'), xyz_vcx(arg1=3,arg2=\'odd\')]"}'

lstStr = msg.split(' - ')[1][:-2]
arr = re.sub(r'([a-z][a-zA-Z0-9_]+)[(]',r'dict(name="",',lstStr)

lstOfDict = eval(arr)

print(arr)
print(lstOfDict[0])
print(lstOfDict[1])
print(u'function {} , args: {} {}'.format(lstOfDict[1]['name'], lstOfDict[1]['arg1'], lstOfDict[1]['arg2'] ))

结果:

[dict(name="func1",arg1=2,arg2='even'), dict(name="xyz_vcx",arg1=3,arg2='odd')]
{'name': 'func1', 'arg1': 2, 'arg2': 'even'}
{'name': 'xyz_vcx', 'arg1': 3, 'arg2': 'odd'}
function xyz_vcx , args: 3 odd

由于函数可以有 args 和 kwargs 并且它们的数量是未知的,我想避免在任何地方切片并使用一些。

msg = u' { "message" : "sometext - [func1(arg1=2,arg2=\'even\'), xyz_vcx(arg1=3,arg2=\'odd\')]"}'

lstStr = msg.split(' - ')[1][:-2]

创建了另一个函数 Name evalstring,它将在 try 异常块中递归地计算 lstSTR,Exception 调用了其他函数 createfunction,它根据预定义的模板创建函数。 createfunction 的输入是从异常中的回溯消息派生的名称。

createfunction中我只是将函数名替换为F字符串,并用exec()调用整个字符串。

预定义模板字符串如下:

"""
def {functionname}(*args, **kwargs):
     argdict = {{}}
     argdict["args"]=args
     argdict["kwargs"]=kwargs
     return argdict
"""

如果对完整代码感兴趣,请告诉我。

@LMS 感谢您的帮助。